Converting PST to CST and EST not giving proper output - java

I am trying to create a proper conversion method for my app which will get the input as PST and can convert it to CST or EST and also support the daylight saving.
Here is the problem. Check this below code and the output. I am simply converting my PST date to CST and EST and printing it. But in output CST and EST is same. there needs to be 1 hour of difference but it is not reflecting.
System.out.println("CURRENT in PST : " + new Date());
SimpleDateFormat utcDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
utcDateFormat.setTimeZone(TimeZone.getTimeZone("PST"));
System.out.println("convert in PST : " + utcDateFormat.format( new Date()));
utcDateFormat.setTimeZone(TimeZone.getTimeZone("CST"));
System.out.println("convert in CST : " + utcDateFormat.format(new Date()));
utcDateFormat.setTimeZone(TimeZone.getTimeZone("EST"));
System.out.println("convert in EST : " + utcDateFormat.format(new Date()));
OutPut :
CURRENT in PST : Wed Jun 13 15:14:15 PDT 2018
convert in PST : 2018-06-13T15:14:15Z
convert in CST : 2018-06-13T17:14:15Z
convert in EST : 2018-06-13T17:14:15Z
So can any one please let me know why? And how I can do this conversion perfectly for all timezones of USA.
I used EST5EDT and it worked but don't know it will support when daylight saving start or ends.
I can use JAVA 8.

tl;dr
how I can do this conversion perfectly for all timezones of USA.
Instant now = Instant.now() ; // Capture current moment in UTC.
ZonedDateTime zdtLosAngeles = now.atZone( ZoneId.of( "America/Los_Angeles" ) ) ;
ZonedDateTime zdtChicago = now.atZone( ZoneId.of( "America/Chicago" ) ) ;
ZonedDateTime zdtNewYork = now.atZone( ZoneId.of( "America/New_York" ) ) ;
ZonedDateTime zdtGuam = now.atZone( ZoneId.of( "America/Guam" ) ) ;
ZonedDateTime zdtHonolulu = now.atZone( ZoneId.of( "America/Los_Angeles" ) ) ;
ZonedDateTime zdtAnchorage = now.atZone( ZoneId.of( "America/Anchorage" ) ) ;
ZonedDateTime zdtIndianapolis = now.atZone( ZoneId.of( "America/Indiana/Indianapolis" ) ) ;
ZonedDateTime zdtPortOfSpain = now.atZone( ZoneId.of( "America/Port_of_Spain" ) ) ;
ZonedDateTime zdtPhoenix = now.atZone( ZoneId.of( "America/Phoenix" ) ) ;
… and so on through the list of the many time zones in the United States.
Date is UTC
"CURRENT in PST : " + new Date()
This is incorrect; this code is not behaving as you apparently are expecting. You may get a String such as Wed Jun 13 15:58:37 PDT 2018, or you may not.
A java.util.Date is always in UTC, by definition. Defined as a count of milliseconds since the epoch reference of first moment of 1970 in UTC. You generated output string may be in west coast time, but that is only by accident.
The confusing part is that the Date::toString method is unfortunately designed to inject the JVM’s current default time zone dynamically while generating a String to represent this Date object’s value. If your JVM happens to have a current default time zone of a zone such as America/Los_Angeles, you will get a string with a west coast US time-of-day. But then your results will vary at runtime should the default time zone be set otherwise, and your "CURRENT in PST:" label will be incorrect. And remember that the JVM’s current default time zone can be changed at any moment during runtime by any code in any thread of any app within the JVM.
The legacy date-time classes are riddled with such poor design choices. Avoid using these classes.
java.time
The modern approach uses the java.time classes rather than those troublesome old legacy date-time classes.
Instant replaces java.util.Date. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Apply a time zone (ZoneId) to get a ZonedDateTime object. Same moment, same point on the timeline, but viewed through the wall-clock time used by the people of a certain region.
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 pseudo-zones such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
As a shortcut, you can skip the Instant object by calling ZonedDateTime.now and passing a ZoneId.
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
And how I can do this conversion perfectly for all timezones of USA.
Firstly, never use the pseudo-zones “PST”, “CST”, “EST” is discussed above. Use real time zones.
There are many more than three zones in the United States, such as America/Chicago, America/New_York, America/Fort_Wayne, Pacific/Honolulu, America/Puerto_Rico, and so on. Why so many? Because current and past practices have varied. For example, some places in the US opt out of the silliness of Daylight Saving Time (DST). Various places have various histories where the offset-from-UTC in that zone were changed by people at different points in their history.
Secondly, keep your time zone definitions up-to-date. Most software systems use a copy of tzdata (formerly known as Olson Database) published by IANA. Your host OS, your JVM implementation, and your database server, likely all have a copy of tzdata that must be kept up-to-date if the rules for any zone you care about change.
Never ignore zone/offset
"yyyy-MM-dd'T'HH:mm:ss'Z'"
Your formatting pattern made a dreadful choice in putting single-quote marks around the Z. That Z means UTC, and is pronounced Zulu. Your single-quotes tell the formatter to ignore that particular string as if it were meaningless. But it is not meaningless, it is vital information about your input data which you are choosing to ignore and discard.
Another thing… That particular format is defined by the ISO 8601 standard. The java.time classes use these standard formats by default when parsing/generating strings.
Instant.parse( "2018-01-23T12:34:56Z" ) // Parse standard ISO 8601 string into a `Instant` object.
instant.toString() // Yields "2018-01-23T12:34:56Z".
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, and later
Built-in.
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
Much 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.

Related

OffsetDateTime String Comparision with OffsetDateTime.now() in java

I am very new to OffsetDateTime usage and I am trying to compare OffsetDateTime strings with OffsetDateTime.now() in java this way,
import java.time.OffsetDateTime;
public class OffsetDateTimeDemo {
public static void main(String[] args) {
OffsetDateTime one = OffsetDateTime.parse("2017-02-03T12:30:30+01:00");
System.out.println("First ::" + OffsetDateTime.now().compareTo(one));
OffsetDateTime date1 = OffsetDateTime.parse("2019-02-14T00:00:00");
System.out.println("Second ::" + OffsetDateTime.now().compareTo(date1));
OffsetDateTime date3 = OffsetDateTime.parse("Mon Jun 18 00:00:00 IST 2012");
System.out.println(" Third :: " +OffsetDateTime.now().compareTo(date3));
}
}
But I am getting java.time.format.DateTimeParseException in all the 3 cases.
However if i compare 2 OffsetDateTime Strings with CompareTo method its working fine.
Can someone shed some light to me in this regard and kindly guide me through my mistake.
Thanks in Advance.
Your compareTo coding is a distraction. Your exception is about parsing the string inputs into objects.
Another problem: You are using wrong classes on the 2nd and 3rd inputs.
Another problem: You are relying implicitly on your JVM’s current default time zone when calling now(). Poor practice as any programmer reading will not know if you intended the default or if you were unaware of the issue as are so many programmers. Furthermore, the current default can be changed at any moment during runtime by any code in any thread of any app within the JVM. So better to always specify explicitly your desired/expected zone or offset.
OffsetDateTime.now(
ZoneOffset.UTC
)
Or better yet, use a ZonedDateTime to capture more information than a OffsetDateTime.
ZonedDateTime.now(
ZoneId.of( "Pacific/Auckland" )
)
First: OffsetDateTime works
Your first string input is proper, and parses successfully.
OffsetDateTime.parse( "2017-02-03T12:30:30+01:00" )
Full line of code:
OffsetDateTime odt = OffsetDateTime.parse( "2017-02-03T12:30:30+01:00" ) ;
See this code run live at IdeOne.com.
odt.toString(): 2017-02-03T12:30:30+01:00
To compare, extract an Instant. Doing so effectively adjusts your moment from some offset to an offset of zero, or UTC itself. An Instant is always in UTC, by definition.
Instant instant = Instant.now() ; // Capture the current moment as seen in UTC.
boolean odtIsPast = odt.toInstant().isBefore( instant ) ;
Second: LocalDateTime
Your second string input lacks any indicator of offset-from-UTC or time zone. So an OffsetDateTime is the wrong class to use. Instead use LocalDateTime which lacks any concept of offset or zone.
This means a LocalDateTime cannot represent a moment. For example, noon on the 23rd of January this year could mean noon on Asia/Tokyo which would be hours earlier than noon in Europe/Paris, or it could mean noon in America/Montreal which would be a moment even more hours later. Without the context of a zone or offset, a LocalDateTime has no real meaning. So comparing a LocalDateTime to the current moment is senseless.
LocalDateTime.parse( "2019-02-14T00:00:00" )
See this code run live at IdeOne.com.
ldt.toString(): 2019-02-14T00:00
To compare, you can’t — illogical as discussed above. You must assign a time zone (or offset) to determine a moment on the timeline. If you know for certain this date and time were meant for a specific time zone, assign ZoneId to get a ZonedDateTime. Then extract a Instant to compare.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ; // India time.
ZonedDateTime zdt = ldt.atZone( z ) ;
Instant instant = Instant.now() ; // Capture the current moment as seen in UTC.
boolean zdtIsPast = zdt.toInstant().isBefore( instant ) ; // Compare.
By the way, I noticed the time-of-day is zero. If your goal was to represent the date only, without any time-of-day and without any zone, use LocalDate class.
Third: Don’t bother, ambiguous input
Your third string input carries a time zone indicator. So it should be parsed as a ZonedDateTime.
Unfortunately, you’ve chosen a terrible string format to parse. Never use the 2-4 character pseudo-zones like IST. They are not standardized. And they are not unique! Your IST could mean Ireland Standard Time or India Standard Time or others.
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
See this code run live at IdeOne.com.
zdt.toString(): 2019-02-20T22:34:26.833+01:00[Africa/Tunis]
You could try to parse this. ZonedDateTime will make a guess as to which zone was meant by IST. But it would be just a guess, and so is unreliable given the inherently ambiguous input. Personally, I would refuse to code that, rejecting this input data back to its source.
If you insist on making this unreliable parse attempt, see the correct Answer to a similar Question you asked recently.
Educate your source about always using standard ISO 8601 formats to exchange date-time values as human-readable text.
The java.time classes use these ISO 8601 formats by default when parsing/generating strings. The ZonedDateTime class wisely extends the standard to append the standard name of the time zone in square brackets.
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.
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.

How to get the difference between two dates in Java including the last day?

I'm writing automated bdds for a rest API. And the API returns a date. I want to get the difference between the returned date from the API and the current date today.
So for example, the API returns "March 13, 2018 12:00 pm"
And today's date is "March 11, 2018 12:00pm"
The times are always the same, it's only the days that change. And the API will also return a date that's in the future.
I have this piece of code:
Date currentDate = Date.from(Instant.now());
// endDate comes from the API
long diff = endDate.getTime() - currentDate.getTime();
long differenceInDays = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
This returns 1, but I want it to include the last day. I can just add +1 at the end of endDate.getTime() - currentDate.getTime(); but I'm not sure if that's the right approach.
I also read that this is not a good solution in general, because it doesn't account for daylight savings time. I'm not sure how or if it would affect my automated bdds when daylight savings comes. What's the best way to capture the difference in days?
Think of it as how many days do I have left until expiration
Your real problem is that your backend REST service is poorly designed.
ISO 8601
First of all, date-time values exchanged should be in standard ISO 8601 format, not some localized presentation string.
The standard formats are used by default in the java.time classes when parsing/generating text.
java.time
Never use the terrible Date class. That class, along with Calendar, SimpleDateFormat, and such, was supplanted years ago by the java.time classes defined in JSR 310.
Date.from(Instant.now())
Never mix the terrible legacy date-time classes (Date) with their replacements (Instant), the modern java.time classes. Mixing these is unnecessary and confusing.
The java.time classes entirely replace their predecessors.
The times are always the same, it's only the days that change. And the API will also return a date that's in the future.
If you only want to exchange date values, without a time-of-day and without a time zone or offset, use LocalDate class, and exchange the ISO 8601 format YYYY-MM-DD such as 2018-03-11. Call LocalDate.parse and LocalDate::toString.
long differenceInDays = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
Representing a count of days as a count of milliseconds without the context of a time zone or offset-from-UTC is reckless. Days are not always 24 hours long. They can be 23, 23.5, 25, or some other number of hours.
If you mean to use UTC so as to always have 24-hour days, say so. Represent your date-time with an indication of time zone or offset. For example, the standard format: 2018-03-11T00:00Z where the Z on the end means UTC and is pronounced “Zulu”.
So your entire problem could be reduced to this one-liner.
ChronoUnit.DAYS.between(
LocalDate.now( ZoneId.of( "America/Montreal" ) ) , // Get the current date as seen in the wall-clock time used by the people of a particular region (a time zone).
LocalDate.parse( "2019-01-23" ) // Parse a string in standard ISO 8601 format for a date-only value.
) // Returns a `long` integer number of days elapsed.
Unzoned
If you are not in a position to clean up all those messy design problems, then let's forge ahead, trying to use this messy data.
First fix the am/pm which should be in uppercase.
String input = "March 13, 2018 12:00 pm".replace( " am" , " AM" ).replace( " pm" , " PM" );
Define a formatting pattern to match your input string.
Specify a Locale to determine the human language and cultural norms to use in translating the text.
Locale locale = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MMMM d, uuuu HH:mm a" );
Parse as a LocalDateTime because your input lacks an indicator of time zone or offset-from-UTC.
LocalDateTime ldt = LocalDateTime.parse( input , f );
ldt.toString(): 2018-03-13T12:00
A LocalDateTime purposely has no concept of time zone or offset-from-UTC. So this class cannot represent a moment, is not a point on the timeline.
If you want generic 24-hour days without regard to the reality of anomalies in wall-clock time used by various people in various places, such as Daylight Saving Time (DST), we can continue to use this class.
Get the current date as seen in the wall-clock time used the people to whom your app is aimed (a time zone).
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-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( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Get noon on that date, in no particular time zone.
LocalDateTime ldtTodayNoon = LocalDateTime.of( today , LocalTime.NOON ) ;
Count days elapsed.
long daysElapsed =
ChronoUnit.DAYS.between(
ldtTodayNoon ,
ldt
)
;
Of course we could just as well have done this using only LocalDate rather than LocalDateTime, but I followed your problem statement as written.
Notice that in your given example, the string represents a date in the past. So our number of days will be negative.
Zoned
If you did want to account for anomalies seen on some dates in some zones, then you should have represented a moment properly, as discussed above, with an indicator of time zone or offset-from-UTC.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
ZonedDateTime zdtNow = ZonedDateTime.now( z ) ;
Or perhaps you want noon today in the desired time zone. If noon is not a valid time-of-day on this date in this zone, the ZonedDateTime class will adjust. Be sure to read the ZonedDateTime.of JavaDoc to understand the algorithm of that adjustment.
LocalDate today = LocalDate.now( z ) ;
ZonedDateTime zdtTodayNoon = ZonedDateTime.of( today , LocalTime.NOON , z ) ;
Calculate elapsed time either based in fractional seconds, or in whole calendar days.
Duration d = Duration.between( zdtTodayNoon , zdt ) ; // For a calculation based in whole seconds plus a fractional second in nanoseconds without regard for a calendar, just using generic 24-hour days.
Period p = Period.between( zdtTodayNoon , zdt ) ; // For a calculation based in whole days, for a number of years-months-days based on calendar dates.
If you insist on tracking by a count of milliseconds, call Duration::toMillis.
long millisecondsElapsed = d.toMillis() ; // Entire duration as a total number of milliseconds, ignoring any microseconds or nanos.
All of this has been covered many times already on Stack Overflow. You can learn more and see more examples by searching for these java.time class names.
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.

Convert Joda-Time `DateTime` with timezone to DateTime without timezone?

Given a DateTime for example 2015-07-09T05:10:00+02:00 using Joda-Time?
How can I convert it to local time, meaning adding the timezone to the time itself.
Desired output: 2015-07-09T07:10:00
I tried dateTime.toDateTime(DateTimeZone.UTC) but that did not give the desired result.
Adding a bit more info and examples to the correct answers (accepted answer and other one).
UPDATE Added section at end on java.time classes. These supplant Joda-Time.
Purpose of LocalDateTime
You may be confused about the purpose of LocalDateTime.
If trying to represent a date-time value using "wall clock time" as seen by someone in a locality looking at their own clock and calendar, then adjust the time zone of the DateTime object to suit the desired locality.
LocalDateTime is not meant for a particular locality but for the general idea of date+time. For example, "This year's Christmas starts at midnight on December 25, 2014". Conceptually, that is a LocalDateTime, intended to mean different moments in Paris than Montréal and Auckland.
Adjusting Time Zone
Use the DateTimeZone class in Joda-Time to adjust to a desired time zone. Joda-Time uses immutable objects. So rather than change the time zone ("mutate"), we instantiate a new DateTime object based on the old but with the desired difference (some other time zone).
Use proper time zone names. Generally a continent/cityOrRegion.
DateTimeZone zoneParis = DateTimeZone.forID( "Europe/Paris" );
DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTimeZone zoneAuckland = DateTimeZone.forID( "Pacific/Auckland" );
Parse string, assign a time zone, adjust to other time zones.
DateTime dateTimeParis = new DateTime( "2015-07-09T05:10:00+02:00" , zoneParis );
DateTime dateTimeMontréal = dateTimeParis.withZone( zoneMontréal );
DateTime dateTimeAuckland = dateTimeParis.withZone( zoneAuckland );
Dump to console.
System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );
System.out.println( "dateTimeAuckland: " + dateTimeAuckland );
When run.
dateTimeParis: 2015-07-09T05:10:00.000+02:00
dateTimeMontréal: 2015-07-08T23:10:00.000-04:00
dateTimeAuckland: 2015-07-09T15:10:00.000+12:00
Localize Using Formatted Strings
Joda-Time can translate to a particular locale’s language and customary style when creating a string representation of your date-time object.
DateTimeFormatter formatterMontréal = DateTimeFormat.forStyle( "FF" ).withZone( zoneMontréal ).withLocale( Locale.CANADA_FRENCH );
String outputMontréal = formatterMontréal.print( dateTimeParis );
System.out.println( "outputMontréal: " + outputMontréal );
When run:
outputMontréal: mercredi 8 juillet 2015 23 h 10 EDT
java.time
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes. The Joda-Time framework inspired java.time, so concepts are quite similar.
ZoneId and ZoneOffset are the two classes to represent a time zone and offset-from-UTC respectively. An offset is merely a number of hours and minutes and seconds. A time zone is an offset plus a set of rules for handling anomalies such as Daylight Saving Time (DST).
ZoneId zoneParis = ZoneId.of( "Europe/Paris" );
ZoneId zoneMontreal = ZoneId.of( "America/Montreal" );
ZoneId zoneAuckland = ZoneId.of( "Pacific/Auckland" );
The primary date-time classes in java.time are:
Instant – A moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
OffsetDateTime – An Instant plus a ZoneOffset.
ZonedDateTime – An Instant plus a ZoneId.
The java.time classes use ISO 8601 standard formats by default when parsing/generating strings representing date-time values. So no need to specify a formatting pattern with such inputs.
This input here indicates an offset-from-UTC but not a full time zone. So we parse as an OffsetDateTime rather than a ZonedDateTime.
OffsetDateTime odt = OffsetDateTime.parse( "2015-07-09T05:10:00+02:00" );
As the basic building-block of java.time, always in UTC by definition, you may want to extract an Instant.
Instant instant = odt.toInstant(); // `Instant` is always in UTC by definition.
You can adjust into a time zone.
ZonedDateTime zdtParis = odt.atZoneSameInstant( zoneParis );
ZonedDateTime zdtMontreal = odt.atZoneSameInstant( zoneMontreal );
ZonedDateTime zdtAuckland = zdtMontreal.withZoneSameInstant( zoneAuckland );
Localize via the DateTimeFormatter class.
DateTimeFormatter f = DateTimeformatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH );
String output = zdtMontreal.format( f );
See live code in IdeOne.com.
odt: 2015-07-09T05:10+02:00
instant: 2015-07-09T03:10:00Z
zdtParis: 2015-07-09T05:10+02:00[Europe/Paris]
zdtMontreal: 2015-07-08T23:10-04:00[America/Montreal]
zdtAuckland: 2015-07-09T15:10+12:00[Pacific/Auckland]
output: mercredi 8 juillet 2015 23 h 10 EDT
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.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
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.
What #Nazgul said is right, but in case all you want to achieve is a "wall-time" in UTC zone you can do something like that:
DateTime dateTimePlus2 = DateTime.parse("2015-07-09T05:10:00+02:00");
System.out.println(dateTimePlus2);
DateTime dateTimeUTC = dateTimePlus2.withZone(DateTimeZone.UTC);
System.out.println(dateTimeUTC);
LocalDateTime localDateTimeUTC = dateTimeUTC.toLocalDateTime();
System.out.println(localDateTimeUTC);
Result:
2015-07-09T05:10:00.000+02:00
2015-07-09T03:10:00.000Z ("Z" == Zulu tz == UTC)
2015-07-09T03:10:00.000
As you can see, the time is not "07:10" as you expected, because UTC+2 zone is two hours ahead of UTC. Converting to UTC subtracts 2 hours.
DateTime without timezone dosnt make sense. DateTime are always relative to the timezone in which they are used. Without the timezone information a date time combination makes no sense for the geography as such. raw timestamp millies can however be accessed as the number of millies gone since 1st Jan 1970 but any concrete date time combinations must have a timezone with it.

Date Time Conversion based on the TimeZone Java/Groovy

I am in MST and I want my Date in PST. I set the timeZone that I want.
Now if i do c.getTime() I always get my server time.
Instead I want Pacific Date time. Please help
How to get the date time Object in the specified timezone.
Calendar c= Calendar.getInstance();
TimeZone timezone= TimeZone.getTimeZone("PST");
c.setTimeZone(timezone)
Or, use JodaTime
#Grab( 'joda-time:joda-time:2.3' )
import org.joda.time.*
def now = new DateTime()
println now.withZone( DateTimeZone.forTimeZone( TimeZone.getTimeZone( "PST" ) ) )
​TimeZone.setDefault(TimeZone.getTimeZone('PST'))
println new Date() //PST time
You can set the default timezone to PST/MST according to your need and then get the date. I would do this in a test method, if possible.
UPDATE: The Joda-Time project has been succeeded by the java.time classes. See this other Answer.
(a) Use Joda-Time (or new JSR 310 built into Java 8). Don't even think about using the notoriously bad java.util.Date/Calendar.
(b) Your question is not clear. Your comments on answers talk about comparing, but you say nothing about comparing in your question.
(c) Avoid the use of 3-letter time zone abbreviations. Read note of deprecation in Joda-Time doc for TimeZone class.
(d) Avoid default time zone. Say what you mean. The time zone of your computer can change intentionally or not.
(e) Search StackOverflow for 'joda' for lots of code snippets and examples.
(f) Here's some Joda-Time example code to get you started.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// Specify your time zone rather than rely on default.
org.joda.time.DateTimeZone californiaTimeZone = org.joda.time.DateTimeZone.forID( "America/Los_Angeles" );
org.joda.time.DateTimeZone denverTimeZone = org.joda.time.DateTimeZone.forID( "America/Denver" );
org.joda.time.DateTime nowDenver = new org.joda.time.DateTime( denverTimeZone );
org.joda.time.DateTime nowCalifornia = nowDenver.toDateTime( californiaTimeZone );
// Same moment in the Universe’s timeline, but presented in the local context.
System.out.println( "nowDenver: " + nowDenver );
System.out.println( "nowCalifornia: " + nowCalifornia );
When run…
nowDenver: 2013-11-21T18:12:49.372-07:00
nowCalifornia: 2013-11-21T17:12:49.372-08:00
About Joda-Time…
// Joda-Time - The popular alternative to Sun/Oracle's notoriously bad date, time, and calendar classes bundled with Java 7 and earlier.
// http://www.joda.org/joda-time/
// Joda-Time will become outmoded by the JSR 310 Date and Time API introduced in Java 8.
// JSR 310 was inspired by Joda-Time but is not directly based on it.
// http://jcp.org/en/jsr/detail?id=310
// By default, Joda-Time produces strings in the standard ISO 8601 format.
// https://en.wikipedia.org/wiki/ISO_8601
// About Daylight Saving Time (DST): https://en.wikipedia.org/wiki/Daylight_saving_time
// Time Zone list: http://joda-time.sourceforge.net/timezones.html
tl;dr
ZonedDateTime
.now(
ZoneId.of( "America/Los_Angeles" )
)
See this code run live at IdeOne.com. (Be aware the system clock on that site seems to be about a half-hour slow today.)
zdt.toString(): 2019-07-27T12:29:42.029531-07:00[America/Los_Angeles]
java.time
The modern approach uses the java.time classes built into Java 8 and later, defined in JSR 310.
I am in MST and I want my Date in PST. I set the timeZone that I want.
Never depend on the current default time zone of the JVM at runtime. As a programmer, you have no control over that default. So the results of your code may vary unexpectedly.
Always specify the optional time zone arguments to date-time methods.
Now if i do c.getTime() I always get my server time.
Learn to think not of client-time or server-time, but rather UTC. Most of your business logic, data storage, data exchange, and logging should be done in UTC. Think of UTC as the One True Time™, and all other offsets/zones are but mere variations.
For UTC, use Instant.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Generate text representing that moment in standard ISO 8601 format.
String output = instant.toString() ;
Instead I want Pacific Date time. Please help How to get the date time Object in the specified timezone.
None of your terms (Pacific, MST, or PST) are true time zones.
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-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( "America/Montreal" ) ;
To adjust from UTC to a time zone, apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "America/Edmonton" ) ; // https://time.is/Edmonton
ZonedDateTime zdt = instant.atZone( z ) ;
And try one of the time zones on the west coast of North America.
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ; // https://time.is/Los_Angeles
ZonedDateTime zdt = instant.atZone( z ) ;
To generate strings in formats other than ISO 8601, use the DateTimeFormatter class. Search Stack Overflow as this has been covered many many times already.
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.
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.
The Java Date object do not have a timezone -- it just represents a point in time.
If you would like to format a date into a timezone, you can set it in the DateFormat class. For example:
Date date = new Date ();
DateFormat df = DateFormat.getDateTimeInstance();
df.setTimeZone(TimeZone.getTimeZone("PST"));
System.out.println(df.format(date));
df.setTimeZone(TimeZone.getTimeZone("EST"));
System.out.println(df.format(date));
will display a time in PST, then a time in EST.
I had to a similar issue myself recently, and setting the timezone to a locale worked better for me (i.e. not EST/EDT, but America/New_York). I tried EST then tried to do the daylight savings time offset stuff for EDT and this turned out to be a heck of lot easier. Set your timezone to whatever you want it to be then make use of the Date object to create a new date and it will for that timezone. Then you can use the format method to take a timestamp however you please.
TimeZone.setDefault(TimeZone.getTimeZone("America/New_York"));
Date date = new Date();
timeStamp = date.format('yyyy-MM-dd HH:mm:ss.SSSZ');
System.out.println(timeStamp);
Returns
"2019-07-25 17:09:23:626-0400"

how to pass hour, minute and second in calendar object in android java

i have made an application in which i need to perform date conversion.
Here is my code.
GregorianCalendar c = new GregorianCalendar(Locale.GERMANY);
c.set(2011, 04, 29,0,0,0);
String cdate = (String) DateFormat.format("yyyy-MM-dd HH:mm:ss", c.getTime());
Log.i(tag,cdate);
now when i check my LOG here is the output:
04-22 12:44:15.956: INFO/GridCellAdapter(30248): 2011-04-29 HH:00:00
why is the hour field not getting set. i have explicitly passed 0 when i was making the calendar object, still it is display HH in the LOG.
what could be the problem?
thank you in advance.
use lower-case hh:
String cdate = (String) DateFormat.format("yyyy-MM-dd hh:mm:ss", c.getTime());
set c.set(Calendar.HOUR_OF_DAY,0) and it should work.
Have you tried like this?
c.set(Calendar.YEAR, 2009);
c.set(Calendar.MONTH,11);
c.set(Calendar.DAY_OF_MONTH,4);
c.set(Calendar.HOUR_OF_DAY,0);
c.set(Calendar.MINUTE,0);
c.set(Calendar.SECOND,0)
tl;dr
LocalDate.of( 2011 , 4 , 29 ) // Represent April 29, 2011.
.atStartOfDay( ZoneId.of( "America/Montreal" ) ) // Determine the first moment of the day. Often 00:00:00 but not always.
.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) // Generate a String representing the value of this date, using standard ISO 8601 format.
.replace( "T" , " " ) // Replace the `T` in the middle of standard ISO 8601 format with a space for readability.
Using java.time
The modern way is with the java.time classes.
If you are trying to get the first moment of the day, do not assume the time 00:00:00. Anomalies in some time zones mean the day may start at another time-of-day such as 01:00:00.
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
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( "America/Montreal" );
LocalDate today = LocalDate.now( z );
You want a specific date in your Question.
LocalDate localDate = LocalDate.of( 2011 , 4 , 29 ) ;
Apply the time zone again in determining the first moment of the day.
ZonedDateTime zdt = localDate.atStartOfDay( z ); // Determine the first moment of the day on this date for this zone.
I recommend always including an indicator of the time zone or offset-from-UTC with your date-time strings. But if you insist, you can use a DateTimeFormatter predefined in java.time that does not include zone/offset: DateTimeFormatter.ISO_LOCAL_DATE_TIME. Merely remove the T from the middle.
String output = zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " ) ;
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
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
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….

Categories