Java SimpleDateFormat time wierdness - java

I am trying to parse a date string into a java.util.Date using java.text.SimpleDateFormat; however, the resulting formatted date is wrong.
Here is a test case showing the issue:
#Test
public void testSimpleDateFormat() throws Exception {
String dateString = "2016-03-03 11:50:39.5960000";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSS");
Date date = format.parse(dateString);
assertEquals(dateString, format.format(date));
}
This results in the following failure:
org.junit.ComparisonFailure:
Expected :2016-03-03 11:50:39.5960000
Actual :2016-03-03 13:29:59.0000000
The date is correct, but the hours, minutes, seconds, and milliseconds are all wrong. Why is java.text.SimpleDateFormat messing up the time on my date?

Your pattern says that 5960000 is a number of milliseconds. That represents 5960 seconds, so approximately 1 hour and 39 minutes, which explains the difference between the date you obtain and the initial one.

java.time
You are using old classes that have proven to be confusing, troublesome, and poorly designed. Avoid them. They have been supplanted by the java.time framework built into Java 8 and later.
The java.time classes use resolution of nanoseconds, for up to nine digits of a decimal fraction of second. More than enough for your six digits (microseconds).
Your input string is close to the standard ISO 8601 format. That format is used by default in java.time for parsing/generating string representations of date-time values. So, need to specify parsing pattern.
Morph your input string into standard format. Replace the SPACE in the middle with a T.
String input = "2016-03-03 11:50:39.5960000";
String inputStandardized = input.replace( " " , "T" );
Parse that string into a date-time object.
LocalDateTime ldt = LocalDateTime.parse( inputStandardized );
To get an actual moment on the timeline, assign an offset or time zone intended for this input.
If in UTC, create a OffsetDateTime.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );
If a specific time was intended, create a ZonedDateTime.
ZonedDateTime zdt = ldt.atZone( ZoneId.of( "America/Montreal" ) ) ;
Before Java 8
If you do not yet have Java 8 technology available, consider adding either the backport of java.time or Joda-Time (the inspiration for java.time). For Android, there is a specific wrapper of the backport, ThreeTenABP.

Related

java date format "2023-01-25 16:30:22.998" vs "2023-01-16T23:59:59.938Z" [duplicate]

This question already has answers here:
What is this date format? 2011-08-12T20:17:46.384Z
(11 answers)
Closed 24 days ago.
Any help or hint would be greatly appreciated. From the below code I get this date:2023-01-25 16:30:22.998. How can I get this date: "FrmDt": "2023-01-16T23:59:59.938Z". It has a "T" which I not sure what this mean?
java.util.Date tsFrom = new java.util.Date();
Calendar calFrom = Calendar.getInstance();
calFrom.setTime(tsFrom);
calFrom.add(Calendar.YEAR, -1);
tsFrom.setTime(calFrom.getTime().getTime()); // or
sqlTSFromDate = new Timestamp(calFrom.getTime().getTime());
System.out.println("From date:" + sqlTSFromDate);
tl;dr
OffsetDateTime
.now( ZoneOffset.UTC )
.minus( Period.ofYears( 1 ) )
.toString()
2022-01-27T02:02:36.985475Z
ISO 8601
Study the ISO 8601 standard formats for textually representing date-time values.
Avoid legacy classes
Never use the legacy classes Date, Calendar, Timestamp. They are terribly flawed, designed by people who did not understand date-time handling.
java.time
Instead, use the java.time classes defined in JSR 310.
Apparently you want one year prior to the the current moment as seen in UTC.
Capture the current moment in UTC.
OffsetDateTime oneYearAgoInUtc = OffsetDateTime.now( ZoneOffset.UTC );
now.toString(): 2023-01-27T02:02:36.985475Z
Go back a year, using calendar dates as seen in the offset of zero, in UTC. First define the amount of time to go back, using Period for a scale of years-months-days.
Period p = Period.ofYears( 1 );
Then subtract.
OffsetDateTime then = now.minus( p );
then.toString(): 2022-01-27T02:02:36.985475Z
See that code run at Ideone.com.
To generate text in standard ISO 8601, merely call toString. The java.time classes use ISO 8601 formats by default when generating/parsing text.
String output = then.toString() ; // By default, standard ISO 8601 format.
2022-01-27T02:02:36.985475Z
The T separates the year-month-day portion from the hour-minute-second portion.
The Z indicates an offset from UTC of zero hours-minutes-seconds.
As several comments said, this is an ISO 8601 date.
In java, you can parse or write using SimpleDateFormat.
With the Z at the end, makle sure to use UTC/Zulu time.
Amending your code:
public static String ISO_8601 = "yyyyMMdd'T'HHmmss'Z'";
...
SimpleDateFormat dateFormat = new SimpleDateFormat(ISO_8601);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
sqlTSFromDate = dateFormat.format(tsFrom)

Confusions about Java's Date class and getTime() function

I am new to Java's Date class. When I try to use its getTime() function for calculating time difference, issues come out. For example, below is the code.
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
task = opt.get();
task.setEndDate(dateFormat.format(date));
Date startDate = null;
try {
startDate = dateFormat.parse(task.getStartDate());
} catch (ParseException e) {
System.out.println("date parsing error...");
startDate = date;
}
System.out.printf("Start date is: %s", task.getStartDate());
System.out.printf("Start date is: %d", startDate.getTime());
System.out.printf("End date is: %s", task.getEndDate());
System.out.printf("End date is: %d", date.getTime());
long diff = date.getTime() - startDate.getTime() - 43200000;
System.out.printf("Time difference is: %d", diff);
int secNum = (int)(diff / 1000);
String timeCost = String.valueOf(secNum);
System.out.println("Time cost(sec) is:");
System.out.println(timeCost);
task.setTimeCost(timeCost);
The outputs are:
Start date is: 2020-04-15 01:46:17
Start date is: 1586929577000
End date is: 2020-04-15 01:46:35
End date is: 1586972795461
Time difference is: 18461
Time cost(sec) is:18
As you might notice, there is 12 hours(43200000 ms) offset between the calculated difference and the real difference through "date.getTime() - startDate.getTime()".
I don't know what's going on.
Does anyone have an idea and correct me ?
It seems you are storing the date/time as a string in your task object, and converting between Date and String using the format "yyyy-MM-dd hh:mm:ss". I believe lower-case h means you are using a 12-hour clock, but you do not include an AM/PM indicator in your format string.
I'm guessing you ran the code at 1:46 PM to produce the sample output.
You have "2020-04-15 01:46:17" stored as your start date. When you convert that back to a date, the formatter doesn't know whether it is an AM time or PM time. I guess that it defaults to AM.
The Date object, however, knows that it was initialized with a PM time. Therefore, when you subtract the two, you get over 12 hours difference, because it is subtracting 1:46:17 AM from 1:46:35 PM.
A simple recommendation would be to add an AM/PM indicator to your date format, or use a 24-hour clock (upper-case H in the format string).
An even better recommendation would be to store dates as dates, not as strings! Convert them to strings when you want to display them.
You are using hh which is a 12-hour hour format, hence 20:00 becomes 08:00. You should use HH which is a 24-hour format. The below illustrates the difference.
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
Date date = new Date(1586973600000L);
System.out.println(date);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String fd1 = df.format(date);
System.out.println(fd1);
System.out.println(df.parse(fd1));
df.applyPattern("yyyy-MM-dd HH:mm:ss");
String fd2 = df.format(date);
System.out.println(fd2);
System.out.println(df.parse(fd2));
Also, java.util.Date is old, buggy and generally avoided for some time now. You might want to switch to java.time instead.
java.time
I am new to Java's Date class.
Stop! Backup, rewind.
Both java.util.Date and java.sql.Date classes are terrible, deeply flawed, and quite frustrating. Never use these classes.
These classes were shipped in the earliest versions of Java. Supplanted years ago by the modern java.time classes defined in JSR 310.
Date date = new Date();
To capture the current moment in UTC, use Instant.now. Uses a resolution finer than the milliseconds used in the java.util.Date class it replaced.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
task.setEndDate(dateFormat.format(date));
Your Task class should hold a java.time object rather than a mere string.
class Task {
Instant start , stop ;
…
}
Use smart objects rather than dumb strings throughout your Java codebase. Doing so ensures valid values, provides type-safety, and makes your code more self-documenting.
If your Task is like booking appointments in the future, where you want a certain time-of-day regardless of changes to the offset used by your time zone, then use LocalDateTime. This type represents only a date and time-of-day but lacks any concept of time zone or offset.
LocalDate ld = LocalDate.of( 2020 , Month.APRIL , 15 ) ;
Localtime lt = LocalTime.of( 15 , 30 ) ;
LocalDateTime ldt = LocalDateTime.of( ld , lt ) ;
When generating a calendar where you need a specific point on the timeline, then apply the relevant time zone.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
The issue at stake here is the fact that politicians around the world have shown a predilection for changing the offset used by the time zone(s) of their jurisdiction. The politicians do so with surprising frequency. And they have done so with little or no forewarning.
When exchanging date-time values with other systems textually, then use ISO 8601 formats. These formats are used by default in java.time when parsing/generating text. And for presentation to users, produce automatically localized strings using DateTimeFormatter.
new SimpleDateFormat("yyyy-MM-dd hh:mm:ss")
This format is incorrect if you are trying to record moments, specific points on the timeline. You must include an indication of time zone and/or offset-from-UTC to track a moment.
For moments, use the ISO 8601 formats mentioned above. Used by default, so no need to specify a formatting pattern.
String input = "2020-01-23T01:23:45.123456789Z" ;
Instant instant = Instant.parse( input ) ;
Adjust from UTC into the wall-clock time used by the people of a particular region (a time zone).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Generate localized text.
Locale locale = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( locale ) ;
String output = zdt.format( f ) ;
See this code run live at IdeOne.com.
zdt.toString(): 2020-01-22T20:23:45.123456789-05:00[America/Montreal]
output: mercredi 22 janvier 2020 à 20 h 23 min 45 s heure normale de l’Est
long diff = date.getTime() - startDate.getTime() - 43200000;
No need to do the math yourself. We have a class for that: Duration.
Duration d = Duration.between( start , stop ) ;
If you want a count of whole seconds across the entire span of time, call Duration::toSeconds.
long seconds = d.toSeconds() ; // Entire duration in terms of whole seconds.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

ISO 8601 datetime now

I need exactly that format in java which in C# is
DateTime.Now.ToString("o"). Sample returned date for DateTime.Now.ToString("o") is
2016-03-10T11:24:59.7862749+04:00
and then in sql it's inserted as
2016-03-10 11:24:59.786
I'm trying to insert same date format from java. I use that:
TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());
and it returns this
2016-03-10T07:29+0000
Because of that format then it goes in error. How can I change format to be exactly which I want?
For Java 7 you can use:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
System.out.println(df.format(new Date()));
This uses the pattern symbol XXX which will print the colon inside the offset, too. However, for Java-6 this feature is not offered. And the precision is always constrained to milliseconds.
For Java-8, you can also use:
DateTimeFormatter dtf = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
System.out.println(OffsetDateTime.now().format(dtf)); // 2016-03-10T08:46:44.849+01:00
This enables nanosecond precision if such a clock is available (starting with Java-9).
For Java-6 either apply a hack based on SimpleDateFormat or use external libraries:
// Java-6 (SimpleDateFormat)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String text = sdf.format(new Date());
text = text.substring(0, text.length() - 2) + ":" + text.substring(text.length() - 2);
System.out.println(text);
// Joda-Time
DateTime now = DateTime.now();
System.out.println(DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZZ").print(now));
// Time4J
Moment now = SystemClock.currentMoment();
System.out.println(Iso8601Format.EXTENDED_DATE_TIME_OFFSET.withStdTimezone().format(now));
The Answer by Meno Hochschild is correct. I'll just add some more comments and some SQL-specific code.
Avoid Old Date-Time Classes
The old date-time classes, java.util.Date/.Calendar & java.text.SimpleDateFormat, are poorly designed, confusing, and troublesome. Avoid them.
The old clases have been supplanted by the java.time framework built into Java 8 and later.
For use before Java 8, check out the ThreeTen-Backport project.
Nanoseconds
The java.time classes have nanosecond resolution. So you will not have the problem of data loss where 2016-03-10T11:24:59.7862749+04:00 gets truncated to 2016-03-10 11:24:59.786 because of millisecond resolution used by the old classes.
Getting the current moment in Java 8 is limited to milliseconds, three digits of decimal fraction of second, due to legacy issue. Java 9 will get the current moment in nanoseconds, up to nine digits of decimal fraction (provided your computer’s hardware clock can provide such fine resolution).
ISO 8601
The ISO 8601 standard defines sensible text formats for date-time values. For example, 2016-03-09T23:24:33Z or 2016-03-09T22:24:33-01:00. The java.time classes use these by default, so no need to define parsing patterns.
Instant
An Instant is a moment on the timeline in UTC.
Instant instant = Instant.now();
Call Instant::toString to generate a string in standard format.
String output = instant.toString();
2016-03-09T23:24:33.123Z
OffsetDateTime
Apply a ZoneOffset to get an OffsetDateTime.
ZoneOffset zoneOffset = ZoneOffset.ofHoursMinutes( -5 , 30 );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
If you know the full time zone rather than just the offset-from-UTC, apply a ZoneId to get a ZonedDateTime.
Use proper time zone names.
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" ); // "Europe/Paris", "America/Montreal", etc.
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
java.sql.Timestamp
Hopefully the JDBC drivers will be updated to directly use the java.time types. Until then we convert to java.sql types for transferring data in/out of database.
As noted above, java.time can handle nanoseconds. So does java.sql.Timestamp. But your database may not. Some databases are limited to whole seconds, milliseconds, or microseconds. When data is passed via JDBC to the database, the database may truncate.
java.sql.Timestamp ts = java.sql.Timestamp.from( instant );
…and going the other direction…
Instant instant = ts.toInstant();
Note that an Instant is always in UTC by definition. So no need to perform the kind of code attempted at the end of the Question.
Work Flow
You should minimize your use of strings when working with date-time. Maximize your use of helpful date-time classes/objects, namely java.time classes. Stop thinking of strings as date-time values -- they are a textual representation of a date-time value.
Do not insert/retrieve date-time values to/from your database as strings. Use the java.sql objects such as java.sql.Timestamp and java.sql.Date. Use PreparedStatement and the "set/get" methods such as setTimestamp/getTimestamp. And virtually always define your columns in database as TIMESTAMP WITH TIME ZONE rather than “without time zone”.
When getting data from database, use the java.sql types. But as soon as is possible, convert to java.time types. The java.sql types are a mess, a dirty hack, and should be used only for data transfer not business logic.
Generally best to use UTC in your business logic, data storage, data exchange, API calls, and so on. Adjust into a time zone only when expected by a user or required by a data sink.
use this format "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
Example:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
System.out.println(df.format(new Date()));

Conversion of string with AM/PM date-time, from Oracle database

I have the timestamp in form of 03-AUG-12 08.15.00.000000000 PM -05:00
I am unable to get a String representation in form on yyyy-MM-dd HH:mm:ss.
Here is my code :
public static void convert() {
String oldstring = "03-AUG-12 08.15.00.000000000 PM -05:00";
Date date = null;
try {
date = new SimpleDateFormat("dd-MMM-yy HH.mm.ss.S aa").parse(oldstring);
}
catch (ParseException e) {
e.printStackTrace();
}
String newstring = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
System.out.println(newstring);
}
Basically it is a timestamp with timezone format from the Oracle database.
You can't use SimpleDateFormat to parse such a string, at least not without some limitations:
A time zone designator like -05:00 (according to ISO 8601) is not supported until Java 7. With Java 7 you can use the XXX pattern to parse it.
To parse the month name correctly, you should specify that you require an English locale.
The pattern for milliseconds (S) parses an unlimited number of digits. If your string contains "08.15.00.100000000", SimpleDateFormat would parse this as 8:15:00 and 100000000ms, adding almost 28 hours to the expected value. If you are sure that the value is always 0, you can ignore this problem.
If you can accept the last issue and use Java 7, you should be using something like this:
new SimpleDateFormat("dd-MMM-yy hh.mm.ss.S aa XXX", Locale.ENGLISH)
Change this line like this:
date = new SimpleDateFormat("dd-MMM-yy hh.mm.ss.S aa").parse(oldstring);
You need to use the lowercase h which parses the AM/PM hours 1-12.
tl;dr
DateTimeFormatter f = new DateTimeFormatterBuilder ().parseCaseInsensitive ().appendPattern ( "dd-MMM-yy hh.mm.ss.SSSSSSSSS a ZZZZZ" ).toFormatter ().withLocale ( Locale.US );
OffsetDateTime odt = OffsetDateTime.parse ( "03-AUG-12 08.15.00.000000000 PM -05:00" , f );
Objects, not strings
You mentioned Oracle. When retrieving data from a database, use objects rather than strings. Ask your ResultSet for a java.sql.Timestamp object.
java.sql.Timestamp ts = myResultSet.getTimestamp( … );
Convert from the troublesome old date-time class to the modern java.time type. Look to new methods added on the old classes to facilitate conversion to/from java.time.
Instant instant = ts.toInstant();
Or preferably, if using JDBC 4.2 or later, and using Java 8 or later, you may be able to retrieve an java.time.Instant via the ResultSet::getObject method.
But if you must parse a string, read on.
Avoid old date-time classes
The old date-time classes bundled with the earliest versions of Java are troublesome and confusing. Now supplanted by the java.time classes.
Nanoseconds
That bunch of zeros must represent a fraction of a second with nanosecond resolution, up to nine digits of a decimal fraction. The old date-time classes can handle only milliseconds, but fortunately the modern java.time classes can indeed handle a resolution up to nanoseconds.
Using java.time
Define a formatting pattern to parse the given input. By the way, your data’s format is less than optimal; in the future, use ISO 8601 standard formats for strings that represent date-time values.
We use a “builder” in order to specify case-insensitive parsing. Proper abbreviation for a name of month in English is initial-cap, Aug, but your input uses all-caps.
String pattern = "dd-MMM-yy hh.mm.ss.SSSSSSSSS a ZZZZZ";
DateTimeFormatterBuilder fb = new DateTimeFormatterBuilder ().parseCaseInsensitive ().appendPattern ( pattern );
Tell the builder to instantiate our formatter. The Locale to determines (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, and such.
Locale l = Locale.US;
DateTimeFormatter f = fb.toFormatter ().withLocale ( l );
Finally, parse the string as an OffsetDateTime object.
String input = "03-AUG-12 08.15.00.000000000 PM -05:00";
OffsetDateTime odt = OffsetDateTime.parse ( input , f );
Dump to console. Note how our 8 PM is transformed into the 24-hour clock value of 20 hours.
System.out.println ( "input: " + input + " | odt.toString(): " + odt );
input: 03-AUG-12 08.15.00.000000000 PM -05:00 | odt.toString(): 2012-08-03T20:15-05:00
A time zone is an offset-from-UTC plus a set of rules for handling anomalies such as Daylight Saving Time (DST). If desired, apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( “America/Montreal” );
ZonedDateTime zdt = odt.atZoneSameInstant( z );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use…).
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

want current date and time in "dd/MM/yyyy HH:mm:ss.SS" format

I am using following code to get date in "dd/MM/yyyy HH:mm:ss.SS" format.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateAndTime{
public static void main(String[] args)throws Exception{
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS");
String strDate = sdf.format(cal.getTime());
System.out.println("Current date in String Format: "+strDate);
SimpleDateFormat sdf1 = new SimpleDateFormat();
sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS");
Date date = sdf1.parse(strDate);
System.out.println("Current date in Date Format: "+date);
}
}
and am getting following output
Current date in String Format: 05/01/2012 21:10:17.287
Current date in Date Format: Thu Jan 05 21:10:17 IST 2012
Kindly suggest what i should do to display the date in same string format(dd/MM/yyyy HH:mm:ss.SS) i.e i want following output:
Current date in String Format: 05/01/2012 21:10:17.287
Current date in Date Format: 05/01/2012 21:10:17.287
Kindly suggest
SimpleDateFormat
sdf=new SimpleDateFormat("dd/MM/YYYY hh:mm:ss");
String dateString=sdf.format(date);
It will give the output 28/09/2013 09:57:19 as you expected.
For complete program click here
You can't - because you're calling Date.toString() which will always include the system time zone if that's in the default date format for the default locale. The Date value itself has no concept of a format. If you want to format it in a particular way, use SimpleDateFormat.format()... using Date.toString() is almost always a bad idea.
The following code gives expected output. Is that what you want?
import java.util.Calendar;
import java.util.Date;
public class DateAndTime {
public static void main(String[] args) throws Exception {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS");
String strDate = sdf.format(cal.getTime());
System.out.println("Current date in String Format: " + strDate);
SimpleDateFormat sdf1 = new SimpleDateFormat();
sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS");
Date date = sdf1.parse(strDate);
String string = sdf1.format(date);
System.out.println("Current date in Date Format: " + string);
}
}
Use:
System.out.println("Current date in Date Format: " + sdf.format(date));
tl;dr
Use modern java.time classes.
Never use Date/Calendar/SimpleDateFormat classes.
Example:
ZonedDateTime // Represent a moment as seen in the wall-clock time used by the people of a particular region (a time zone).
.now( // Capture the current moment.
ZoneId.of( "Africa/Tunis" ) // Always specify time zone using proper `Continent/Region` format. Never use 3-4 letter pseudo-zones such as EST, PDT, IST, etc.
)
.truncatedTo( // Lop off finer part of this value.
ChronoUnit.MILLIS // Specify level of truncation via `ChronoUnit` enum object.
) // Returns another separate `ZonedDateTime` object, per immutable objects pattern, rather than alter (“mutate”) the original.
.format( // Generate a `String` object with text representing the value of our `ZonedDateTime` object.
DateTimeFormatter.ISO_LOCAL_DATE_TIME // This standard ISO 8601 format is close to your desired output.
) // Returns a `String`.
.replace( "T" , " " ) // Replace `T` in middle with a SPACE.
java.time
The modern approach uses java.time classes that years ago supplanted the terrible old date-time classes such as Calendar & SimpleDateFormat.
want current date and time
Capture the current moment in UTC using Instant.
Instant instant = Instant.now() ;
To view that same moment through the lens of the wall-clock time used by the people of a particular region (a time zone), apply a ZoneId to get a ZonedDateTime.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Or, as a shortcut, pass a ZoneId to the ZonedDateTime.now method.
ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "Pacific/Auckland" ) ) ;
The java.time classes use a resolution of nanoseconds. That means up to nine digits of a decimal fraction of a second. If you want only three, milliseconds, truncate. Pass your desired limit as a ChronoUnit enum object.
ZonedDateTime
.now(
ZoneId.of( "Pacific/Auckland" )
)
.truncatedTo(
ChronoUnit.MILLIS
)
in “dd/MM/yyyy HH:mm:ss.SS” format
I recommend always including the offset-from-UTC or time zone when generating a string, to avoid ambiguity and misunderstanding.
But if you insist, you can specify a specific format when generating a string to represent your date-time value. A built-in pre-defined formatter nearly meets your desired format, but for a T where you want a SPACE.
String output =
zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " )
;
sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS");
Date date = sdf1.parse(strDate);
Never exchange date-time values using text intended for presentation to humans.
Instead, use the standard formats defined for this very purpose, found in ISO 8601.
The java.time use these ISO 8601 formats by default when parsing/generating strings.
Always include an indicator of the offset-from-UTC or time zone when exchanging a specific moment. So your desired format discussed above is to be avoided for data-exchange. Furthermore, generally best to exchange a moment as UTC. This means an Instant in java.time. You can exchange a Instant from a ZonedDateTime, effectively adjusting from a time zone to UTC for the same moment, same point on the timeline, but a different wall-clock time.
Instant instant = zdt.toInstant() ;
String exchangeThisString = instant.toString() ;
2018-01-23T01:23:45.123456789Z
This ISO 8601 format uses a Z on the end to represent UTC, pronounced “Zulu”.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Here's a simple snippet working in Java 8 and using the "new" date and time API LocalDateTime:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss.SS");
LocalDateTime now = LocalDateTime.now();
System.out.println(dtf.format(now));
The output in your first printline is using your formatter. The output in your second (the date created from your parsed string) is output using Date#toString which formats according to its own rules. That is, you're not using a formatter.
The rules are as per what you're seeing and described here:
http://docs.oracle.com/javase/6/docs/api/java/util/Date.html#toString()
Disclaimer: this answer does not endorse the use of the Date class (in fact it’s long outdated and poorly designed, so I’d rather discourage it completely). I try to answer a regularly recurring question about date and time objects with a format. For this purpose I am using the Date class as example. Other classes are treated at the end.
You don’t want to
You don’t want a Date with a specific format. Good practice in all but the simplest throw-away programs is to keep your user interface apart from your model and your business logic. The value of the Date object belongs in your model, so keep your Date there and never let the user see it directly. When you adhere to this, it will never matter which format the Date has got. Whenever the user should see the date, format it into a String and show the string to the user. Similarly if you need a specific format for persistence or exchange with another system, format the Date into a string for that purpose. If the user needs to enter a date and/or time, either accept a string or use a date picker or time picker.
Special case: storing into an SQL database. It may appear that your database requires a specific format. Not so. Use yourPreparedStatement.setObject(yourParamIndex, yourDateOrTimeObject) where yourDateOrTimeObject is a LocalDate, Instant, LocalDateTime or an instance of an appropriate date-time class from java.time. And again don’t worry about the format of that object. Search for more details.
You cannot
A Date hasn’t got, as in cannot have a format. It’s a point in time, nothing more, nothing less. A container of a value. In your code sdf1.parse converts your string into a Date object, that is, into a point in time. It doesn’t keep the string nor the format that was in the string.
To finish the story, let’s look at the next line from your code too:
System.out.println("Current date in Date Format: "+date);
In order to perform the string concatenation required by the + sign Java needs to convert your Date into a String first. It does this by calling the toString method of your Date object. Date.toString always produces a string like Thu Jan 05 21:10:17 IST 2012. There is no way you could change that (except in a subclass of Date, but you don’t want that). Then the generated string is concatenated with the string literal to produce the string printed by System.out.println.
In short “format” applies only to the string representations of dates, not to the dates themselves.
Isn’t it strange that a Date hasn’t got a format?
I think what I’ve written is quite as we should expect. It’s similar to other types. Think of an int. The same int may be formatted into strings like 53,551, 53.551 (with a dot as thousands separator), 00053551, +53 551 or even 0x0000_D12F. All of this formatting produces strings, while the int just stays the same and doesn’t change its format. With a Date object it’s exactly the same: you can format it into many different strings, but the Date itself always stays the same.
Can I then have a LocalDate, a ZonedDateTime, a Calendar, a GregorianCalendar, an XMLGregorianCalendar, a java.sql.Date, Time or Timestamp in the format of my choice?
No, you cannot, and for the same reasons as above. None of the mentioned classes, in fact no date or time class I have ever met, can have a format. You can have your desired format only in a String outside your date-time object.
Links
Model–view–controller on Wikipedia
All about java.util.Date on Jon Skeet’s coding blog
Answers by Basil Bourque and Pitto explaining what to do instead (also using classes that are more modern and far more programmer friendly than Date)
If you are using JAVA8 API then this code will help.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String dateTimeString = LocalDateTime.now().format(formatter);
System.out.println(dateTimeString);
It will print the date in the given format.
But if you again create a object of LocalDateTime it will print the 'T' in between the date and time.
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println(dateTime.toString());
So as mentioned in earlier posts as well, the representation and usage is different.
Its better to use "yyyy-MM-dd'T'HH:mm:ss" pattern and convert the string/date object accordingly.
use
Date date = new Date();
String strDate = sdf.format(date);
intead Of
Calendar cal = Calendar.getInstance();
String strDate = sdf.format(cal.getTime());
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateAndTime{
public static void main(String[] args)throws Exception{
Date date = new Date(System.currentTimeMillis());
DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS",
Locale.ENGLISH);
String strDate = format.format(date);
System.out.println("Current date in String Format: "+strDate);
}
}
use this code u will get current date in expected string format

Categories