Cannot Parse Date and get Milliseconds - java

I am trying to parse a String into Date.
I am using
new SimpleDateFormat("yyyyMMdd-HH:mm:ss.SSS").parse("20140923-14:32:34.456")
My output is: (Date object)
Tue Sep 23 14:32:34 EDT 2014
I dont understand why I do not get the milliseconds. I need the date along with milliseconds and not just the milliseconds.
Expected Output: (Date object)
Tue Sep 23 14:32:34.456 EDT 2014
thanks
PS: I dont want a string object in the end but a Date.

You're just printing out the result of calling Date.toString() which happens not to include the milliseconds. If you print out the result of calling getTime() on the date, you'll see that it ends in "456", showing that it has parsed the milliseconds.
Also, don't be fooled by the "EDT" part of the output of Date.toString(). It doesn't mean that this is a Date object "in" EDT... a Date doesn't have a time zone at all; it's just a number of milliseconds since the unix epoch.
I'd advise you to explicitly set the time zone of your SimpleDateFormat, however - even if you deliberately set it to the system default time zone. By doing it explicitly, you make it clear to the reader that you meant to use that time zone, rather than just that you failed to think about it. You should take the same approach to the locale, too - in this case I'd probably specify Locale.US, which is usually a good bet for formats which are designed more for machine-parsing than humans.

You need to use the format when printing the date you just read too:
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HH:mm:ss.SSS")
Date date = sdf.parse("20140923-14:32:34.456");
System.out.println(date); // Tue Sep 23 14:32:34 EDT 2014
System.out.println(sdf.format(date)); // 20140923-14:32:34.456

Your Date object does already contain the correct milliseconds. It's just that, when you are writing the Date object back out again, the default String representation of a Date does not include milliseconds.
You presumably have:
DateFormat myFormat = new SimpleDateFormat("yyyyMMdd-HH:mm:ss.SSS");
Date myDate = myFormat.parse("20140923-14:32:34.456");
To output the date with milliseconds, you should use:
System.out.println(myFormat.format(myDate));
Instead of reusing myFormat, you could use a different DateFormat that also includes milliseconds in its specification.

The answer by Jon Skeet is correct.
Joda-Time
I will add some example code using the Joda-Time library.
The java.util.Date, java.util.Calendar, and java.text.SimpleDateFormat classes bundled with Java are notoriously troublesome, flawed in both design and implementation. Avoid them. Use either Joda-Time or the java.time package in Java 8 (inspired by Joda-Time, defined by JSR 310).
In both Joda-Time and java.time, a date-time object knows its own assigned time zone, unlike in java.util.Date. Another difference is that both those good libraries use immutable objects where we instantiate fresh objects based on original object rather than alter ("mutate") the original.
DateTimeZone timeZone = DateTimeZone.UTC; // Or DateTimeZone.forID( "America/Montreal" )
DateTimeFormatter formatter = DateTimeFormat.forPattern( "yyyyMMdd-HH:mm:ss.SSS" ).withZone( timeZone );
DateTime dateTime = formatter.parseDateTime("20140923-14:32:34.456"); // Parsed *and* assigned the specified time zone.
String output = dateTime.toString();
You can convert to another time zone.
DateTime dateTimeKolkata = dateTime.withZone( DateTimeZone.forID( "Asia/Kolkata" ) );
If you really need a java.util.Date, perhaps required by other classes, convert from Joda-Time.
java.util.Date date = dateTime.toDate();

Related

Google cloud function Time zone converstion [duplicate]

I am trying to instantiate GregorianCalendar with TimeZone GMT, but whenever I call the getTime() method, it gives me time in local TimeZone. Here is my code:
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
System.out.println(cal.getTime());
The output I am getting is this:
Sat Nov 28 19:55:49 PKT 2009
Please help!
I'm not sure if this answers your question, but this is one way to get "now" in GMT.
import java.text.*
import java.util.*
Calendar cal = new GregorianCalendar();
Date date = cal.getTime();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(formatter.format(date));
See the Javadoc on SimpleDateFormat for different patterns. Also, you may want to consider Joda Time as it is far superior for dates and times.
The problem is not with GregorianCalendar but with Date, which is being used to format the date/time for toString for println.
If you want control of date formatting, you'll need to instantiate your own DateFormat - I always use SimpleDateFormat because I'm rather picky about how I want my dates to look.
If you're not interested in the details of how the date is formatted, you can also use one of the getInstance... factory methods of DateFormat.
You can explicitly setTimeZone on a DateFormat (including SimpleDateFormat, of course).
tl;dr
Instant.now().toString()
2020-03-08T00:21:48.647951Z
java.util.Date::toString tells a lie
Your call to GregorianCalendar::getTime returns a java.util.Date. As you can see with this method and class naming, these classes are badly designed.
Then you implicitly called Date::toString to generate text that represents the value within that object. That value is actually in UTC, being merely a count of milliseconds since the epoch reference of first moment of 1970 in UTC. Unfortunately, that method dynamically applies the JVM’s current default time zone while generating the text. This creates the illusion of that zone being contained within the object.
Confusing? Yes. One of many reasons to never use these legacy date-time classes. Use java.time classes instead.
java.time
The other Answers are correct, but now obsolete. The terrible Date, Calendar, GregorianCalendar, and SimpleDateFormat classes were years ago supplanted by the modern java.time classes defined in JSR 310.
To get the current moment in UTC, use Instant. This basic building block class in java.time is always in UTC, by definition.
Instant instant = Instant.now() ;
Generate a string in standard in ISO 8601 format by calling toString.
String output = instant.toString() ;
See this code run live at IdeOne.com.
2020-03-08T00:21:48.647951Z
For more flexible formatting when generating strings, use the OffsetDateTime class. Search Stack Overflow to learn about DateTimeFormatter.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;

DateTime showing different date when converted to date

I am currrently working with Java JODATIME DateTime. I have a dateTime as 2015-09-08T11:00:00.000Z , When I convert to date using toDate().
I am getting the date object as Tue Sep 08 06:00:00 CDT 2015.
DateTime dateTime = 2015-09-08T11:00:00.000Z; // Not a string I am getting this date from another API.
Date date = dateTime.toDate(); //Tue Sep 08 06:00:00 CDT 2015.
May I know what is the thing happening here?
A Date object simply holds the number of milliseconds since 1 Jan 1970 UTC. It does not contain presentation logic, so your comment that it equates to 6am CDT shows that something (your IDE, or some date formatter) has applied a timezone in order to render the date to a human readable form. The code is actually working correctly.
Apparently you are calling the toString method on the java.util.Date object. That class’ implementation of toString has the confusing feature of silently applying your JVM’s current default time zone to the date-time value as it generates a String representation.
The java.util.Date object itself has no time zone, and is always in UTC.
This is one of many reasonable avoid these old java.util.Date/.Calendar classes. Use java.time, now built into Java 8 and later. For older versions of Java, use Joda-Time.
Also this topic has been addressed many many times before on StackOverflow. Please search before posting.
A quick bit of example code in java.time. An Instant is a moment on the timeline in UTC. Your input string happens to be in standard ISO 8601 format which java.time uses by default when parsing/generating strings. So you can parse directly without bothering to specify a parsing pattern.
String input = "2015-09-08T11:00:00.000Z";
Instant instant = Instant.parse( input );
Adjust that Instant into a specific time zone to get a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Search StackOverflow.com for many more examples of java.time.
Actually there is a time zone buried in the source code of java.util.Date but is ignored for practical purposes.

Java Date Conversion - UTC to Local - works differently depending on the timezone

I'm experiencing a problem when converting strings to a UTC data, and then to various timezones. It appears that my program behaves differently depending on whether I convert to EST or PST. Here is my code:
SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
utcFormat.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
Date date = utcFormat.parse("2014-08-18 17:00:17");
SimpleDateFormat localFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
localFormat.setTimeZone(java.util.TimeZone.getTimeZone("PST"));
System.out.println(localFormat.format(date));
If I run the code above, here is my output:
2014-08-18 10:00:17
This reflects a 7 hour offset from the UTC time provided: 2014-08-18 17:00:17. This is what I would have expected. Now if I change that date to 2014-11-18 17:00:17 (changed the month from August to November), here is the output produced:
2014-11-18 09:00:17
This is fine too as far as I can tell. The output reflects an 8 hour offset from UTC, and I believe this is due to the fact that November is not in Daylight Savings time, while August is.
The problem I'm having is that the same code above works differently if I change the time zone from "PST" to "EST". When I change to EST I get the same time output no matter whether my date is in August or November.
Here is the output using EST and 2014-08-18 17:00:17
2014-08-18 12:00:17
Here is the output using EST and 2014-11-18 17:00:17
2014-11-18 12:00:17
In both cases, the output represents a 5 hour offset from UTC which makes sense only during November, not during August.
Can anyone explain to me what I am doing wrong?
Instead of using EST, you should use America/New_York or US/Eastern (these are aliases). The three letter timezone abbreviations are ambiguous and you can't be sure what you're getting.
From the Documentation for TimeZone
For compatibility with JDK 1.1.x, some other three-letter time zone IDs (such as "PST", "CTT", "AST") are also supported. However, their use is deprecated because the same abbreviation is often used for multiple time zones (for example, "CST" could be U.S. "Central Standard Time" and "China Standard Time"), and the Java platform can then only recognize one of them.
Instead of "EST", "US/Eastern" will be much clearer as to your intent.
These are the supported US aliases.
US/Alaska
US/Aleutian
US/Arizona
US/Central
US/East-Indiana
US/Eastern
US/Hawaii
US/Indiana-Starke
US/Michigan
US/Mountain
US/Pacific
US/Pacific-New
US/Samoa
#Compass is right.
Here is the code you would use:
public static void main(String[] args) {
SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
utcFormat.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
Date date = null;
try {
date = utcFormat.parse("2014-08-18 17:00:17");
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SimpleDateFormat localFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
localFormat.setTimeZone(java.util.TimeZone.getTimeZone("US/Eastern"));
System.out.println(localFormat.format(date));
}
The answer by Dave Morrissey is correct.
Can anyone explain to me what I am doing wrong?
Yes. You are using a terrible and confusing date-time library.
Avoid java.util.Date
The java.util.Date and .Calendar classes are notoriously troublesome, flawed in both design and implementation. Use a decent library. In Java that means either Joda-Time or the new java.time package in Java 8 (inspired by Joda-Time, defined by JSR 310).
Time Zone
While a j.u.Date has no time zone, in both Joda-Time and java.time a date-time object does indeed know its own assigned time zone. Makes this work much easier and more sensible.
Time Zone Names
Use proper time zone names. Avoid the 2, 3, or 4 letter codes as they are neither standardized nor unique. Most of those proper names are Continent/CityOrRegion.
Daylight Saving Time
You should not worry about Daylight Saving Time. Let the date-time library do the heavy lifting there. All you need to do is be sure your library is using a fresh version of the time zone database. Politicians enjoy redefining DST.
ISO 8601
Both Joda-Time and java.time support ISO 8601 formats as their defaults in parsing and generating string representations of date-time values.
Joda-Time Example
Here is some example code in Joda-Time 2.4. All of the DateTime objects in this example represent the same simultaneous moment in the history of the Universe but adjusted to show the wall-clock time as seen by a person in each locality.
String inputRaw = "2014-08-18 17:00:17"; // Nearly in [ISO 8601][7] format.
String input = inputRaw.replace( " ", "T" );
DateTime dateTimeUtc = DateTime.parse( input, DateTimeZone.UTC );
DateTime dateTimeLosAngeles = dateTimeUtc.withZone( DateTimeZone.forID( "America/Los_Angeles" ) );
DateTime dateTimeNewYork = dateTimeUtc.withZone( DateTimeZone.forID( "America/New_York" ) );
DateTime dateTimeMontréal = dateTimeUtc.withZone( DateTimeZone.forID( "America/Montreal" ) );
DateTime dateTimeKolkata = dateTimeUtc.withZone( DateTimeZone.forID( "Asia/Kolkata" ) );
That's because EST is ET outside of saving and its shift is constant and it complementary zone for daylight saving period is EDT.
Ergo you should use ET to get the expected behavior.
More on Wikipedia

is there a simple way to convert Date(sql) to following format Month(3 character) day(int) , year(2014)

is there a simple way to convert Date(sql) to following format Month(3 character) day(int) , year(int)?
For example:
Jan 3, 2014
Feb 2, 2014
I have this: "2014-02-14"
(i use postgresql, java and javascript on client)
Assuming , if you want to achieve this in the Database side itself. Then use the below sql query.
Lets say "stack" is the column containing your DATE value ie "2014-02-14"
select to_char(stack,'Mon dd, YYYY') from testing;
to_char
--
Feb 14, 2014
Take a look at Java's SimpleDateFormat API
You can do something like this --
SimpleDateFormat format = new SimpleDateFormat("MMM dd, YYYY");
String dateString = format.format(date); // Pass your SQL date object here
This will work:
SimpleDateFormat format = new SimpleDateFormat("MMM dd, yyyy");
SimpleDateFormat sqlformat = new SimpleDateFormat("yyyy-mm-dd");
java.util.Date date;
try {
date = sqlformat.parse("2014-02-14");
String result = format.format(date);
System.out.println(result);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // Pass your SQL date object here
Short Answer
In Joda-Time 2.3 (substitute your desired time zone and Locale)…
String output = DateTimeFormat.forStyle( "M-" ).withLocale( new java.util.Locale( "fr", "CA" ).withTimeZone( "America/Montreal").print( new DateTime( myJavaDotSqlDotJavaObject ) );
A Date-Time Object Has No Format
You are making the common mistake of conflating a date-time value with its string representation. A java.sql.Date object has no String format. You can generate a String representation from a date-time object, but the two are separate independent objects.
ISO 8601
The format you mentioned is defined by the ISO 8601 standard. The Joda-Time date-time library uses ISO 8601 for its defaults for both inputs and outputs.
Time Zone
Both the question and other answers ignore the crucial issue of time zone.
Determining what day it is (yesterday, today, tomorrow) depends on your time zone. While a new day dawns in Paris for Feb 2, in Montréal the date is still Feb 1.
A java.sql.Date instance has no time zone. It's date-time value internally is effectively in UTC (no offset).
Decent Date-Time Library
The bundled java.util.Date and .Calendar classes in Java are notoriously troublesome. Avoid them. Use either:
Joda-Time
The new java.time package in Java 8.
Joda-Time
Some example code in Joda-Time 2.3.
Get the current date-time.
DateTimeZone timeZoneParis = DateTimeZone.forID( "Europe/Paris" );
DateTime nowInParis = DateTime.now( timeZone );
To convert your java.sql.Date instance to a Joda-Time object, simply pass it to the constructor. Be sure to include a time zone to be assigned to the Joda-Time DateTime object. If you omit the time zone, the JVM’s default zone is assigned.
DateTime dateTimeInParis = new DateTime( myJavaDotSqlDotDateObject, timeZoneParis );
Adjust for time zone.
DateTimeZone timeZoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTime nowInMontréal = nowInParis.withTimeZone( timeZone );
You may adjust to UTC. This might be helpful for debugging, to verify the UTC value stored in your database. Postgres always stores TIMESTAMP types in UTC. I repeat: both TIMESTAMP WITH TIME ZONE and TIMESTAMP WITHOUT TIME ZONE types are stored in UTC. The 'with' or 'without' names are misleading, as they refer not to storage but to whether or not a time zone is respected during insertion into or retrieval from the database. Expert advice says: Always use TIMESTAMP WITH TIME ZONE.
DateTime dateTimeInUtc = nowInMontréal.withTimeZone( DateTimeZone.UTC );
Generate a string representation of the date-time value using one of the built-in ISO 8601 formatters. For the date-only YYYY-MM-DD format you mentioned, call the factory method ISODateTimeFormat.date().
For the MMM DD, YYYY format you want, I suggest you instead use a localized format. See the line of code at the top of this answer for an example. Pass "M-" to generate a medium-length string representation of the date portion while omitting the time portion. Pass "F", "L", "M", or "S" for Full, Long, Medium, and Short.
If you insist on exactly your specified format, you may create a formatter using the DateTimeFormat.forPattern method. Search StackOverflow for many examples.
Note that the formatter can do the time zone adjusting as part of its process, as an alternative to the time zone adjustment we saw above. The formatter can also localize.
DateTimeFormat formatter = ISODateTimeFormat.date().withTimeZone( timeZoneMontréal ).withLocale( new java.util.Locale( "fr", "CA" ); // Factory producing formatters.
String outputDateOnlyInMontréal = formatter.print( nowInParis );

TimeZone problem in Java

I am trying to instantiate GregorianCalendar with TimeZone GMT, but whenever I call the getTime() method, it gives me time in local TimeZone. Here is my code:
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
System.out.println(cal.getTime());
The output I am getting is this:
Sat Nov 28 19:55:49 PKT 2009
Please help!
I'm not sure if this answers your question, but this is one way to get "now" in GMT.
import java.text.*
import java.util.*
Calendar cal = new GregorianCalendar();
Date date = cal.getTime();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(formatter.format(date));
See the Javadoc on SimpleDateFormat for different patterns. Also, you may want to consider Joda Time as it is far superior for dates and times.
The problem is not with GregorianCalendar but with Date, which is being used to format the date/time for toString for println.
If you want control of date formatting, you'll need to instantiate your own DateFormat - I always use SimpleDateFormat because I'm rather picky about how I want my dates to look.
If you're not interested in the details of how the date is formatted, you can also use one of the getInstance... factory methods of DateFormat.
You can explicitly setTimeZone on a DateFormat (including SimpleDateFormat, of course).
tl;dr
Instant.now().toString()
2020-03-08T00:21:48.647951Z
java.util.Date::toString tells a lie
Your call to GregorianCalendar::getTime returns a java.util.Date. As you can see with this method and class naming, these classes are badly designed.
Then you implicitly called Date::toString to generate text that represents the value within that object. That value is actually in UTC, being merely a count of milliseconds since the epoch reference of first moment of 1970 in UTC. Unfortunately, that method dynamically applies the JVM’s current default time zone while generating the text. This creates the illusion of that zone being contained within the object.
Confusing? Yes. One of many reasons to never use these legacy date-time classes. Use java.time classes instead.
java.time
The other Answers are correct, but now obsolete. The terrible Date, Calendar, GregorianCalendar, and SimpleDateFormat classes were years ago supplanted by the modern java.time classes defined in JSR 310.
To get the current moment in UTC, use Instant. This basic building block class in java.time is always in UTC, by definition.
Instant instant = Instant.now() ;
Generate a string in standard in ISO 8601 format by calling toString.
String output = instant.toString() ;
See this code run live at IdeOne.com.
2020-03-08T00:21:48.647951Z
For more flexible formatting when generating strings, use the OffsetDateTime class. Search Stack Overflow to learn about DateTimeFormatter.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;

Categories

Resources