0

In Java 7 what is the best way to both hold a DateTime with an explicit time zone and to convert it to a different timezone.

And when I say convert, the time (and possibly date) is converted for the difference between the timezone on and the one converting to. So converting from PST to EST, it's not just the timezone in the object changes to EST, but 3 hours are added to the time component, possibly causing the date to roll over by 1 day.

What I must handle is toLocalTime() and toUtcTime(). I'd prefer being able to handle converting to any timezone.

Andremoniy
  • 34,031
  • 20
  • 135
  • 241
David Thielen
  • 28,723
  • 34
  • 119
  • 193
  • Store a `Date` in UTC. Let is system always deal with dates in UTC if you can. When you recieve date information into the system, covert the UTC and when you print out of the system covert to the specified time zone. This is fairly easy to do with [`SimpleDateFormat`](https://docs.oracle.com/javase/7/docs/api/java/text/DateFormat.html#setTimeZone(java.util.TimeZone)). – Boris the Spider Mar 30 '18 at 15:27
  • 1
    http://joda-time.sourceforge.net/apidocs/org/joda/time/DateTime.html#withZone(org.joda.time.DateTimeZone), http://www.threeten.org/threetenbp/apidocs/org/threeten/bp/ZonedDateTime.html#withZoneSameInstant(org.threeten.bp.ZoneId) – JB Nizet Mar 30 '18 at 15:27
  • FYI: switching to Java 8 would make you life much easier - the new Date Time API is much more sane. – Boris the Spider Mar 30 '18 at 15:27
  • I concur with JB Nizet, use the Java 8 Time API (JSR-310) [Backport](http://www.threeten.org/threetenbp/). That way your code is prepared for the future, i.e. when you finally leaving the obsolete Java 7 behind. – Andreas Mar 30 '18 at 15:38
  • Unfortunately we're stuck on Java 7 for some time. – David Thielen Mar 30 '18 at 15:42
  • @BoristheSpider isn't a date timezone ignorant? I've also heard it stated that it's always in UTC but I think it's more that there is no timezone tied to it. ??? - thanks - dave – David Thielen Mar 30 '18 at 15:43
  • 2
    @DavidThielen that's why we're advising to use the Java 8 Time API (JSR-310) **Backport**, which is a backport of the standard Java 8 classes, intended to be used on previous versions of Java. – JB Nizet Mar 30 '18 at 15:44
  • I'm sorry, I didn't understand the backport part at first. – David Thielen Mar 30 '18 at 17:23

1 Answers1

3

tl;dr

ZonedDateTime.now(                      // Capture the current moment as seen with a wall-clock time used by the people of a certain region (a time zone). 
    ZoneId.of( "America/Los_Angeles" )  // Use proper time zone names in `continent/region` format. Never use pseudo-zones such as `PST` & `EST`.
).withZoneSameInstant(                  // Adjust from one zone to another. Using immutable objects, so we produce a second distinct `ZonedDateTime` object.
    ZoneId.of( "America/New_York" )     // Same moment, different wall-clock time.
)

java.time & ThreeTen-Backport

To gain much of the java.time functionality in Java 7, add the ThreeTen-Backport library to your project.

Generally best to work with UTC values.

Instant instant = Instant.now() ;  // Capture the current moment in UTC.

Apply a time zone only when required by business logic or display to user.

Your PST and EST values are not actual time zones. Use proper time zone names.

ZoneId z = ZoneId.of( "America/Los_Angeles" ) ; 

Apply to the Instant to get a ZonedDateTime object. Same moment, same point on the timeline, different wall-clock time.

ZonedDateTime zdt = instant.atZone( z ) ;  

Adjust to yet another time zone. The java.time framework uses immutable objects. So rather than alter (“mutate”) the original, we product a separate distinct object based on the original’s values.

Both ZonedDateTime objects and the Instant all represent the very same moment, the same point on the timeline. This is a crucial concept to understand in date-time handling. Imagine two people, one on the west coast and one on the east coast of North America, talking to each other on the phone. If they both simultaneously look up at the clock hanging on their respective walls, what time do they see? Same moment, different wall-clock time.

ZoneId zNewYork = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdtNewYork = zdt.withZoneSameInstant( zNewYork ) ;  // Same moment, different wall-clock time.

All of this has been covered many times already on Stack Overflow. So search for more examples and discussion.


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?

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154