Converting date from UTC to PST in Java

2019-04-29 13:36发布

问题:

I need to convert date from Google App Engine local server time zone to pacific time in Java.

I tried using

Calendar calstart =
Calendar.getInstance();

calstart.setTimeZone(TimeZone.getTimeZone("PST"));
//calstart.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));

Date startTime = calstart.getTime();

but this gives me incorrect time (some 4pm when actual PST is 10pm). Also tried commented line America/Los_Angeles but gives incorrect time on GAE server.

Any thoughts/advice?

回答1:

Using Joda Time, all you need is the DateTime.withZone method. Example below:

public static Date convertJodaTimezone(LocalDateTime date, String srcTz, String destTz) {
    DateTime srcDateTime = date.toDateTime(DateTimeZone.forID(srcTz));
    DateTime dstDateTime = srcDateTime.withZone(DateTimeZone.forID(destTz));
    return dstDateTime.toLocalDateTime().toDateTime().toDate();
}

As an advice, never use the default API for time-related calculations. It is just awful. Joda seems to be the best replacement API around.



回答2:

Unless you need that to do some calculations, thus you want to format this date to display it to end user, you may simply use DateFormat:

Date startTime = new Date(); // current date time
TimeZone pstTimeZone = TimeZone.getTimeZone("America/Los_Angeles");
DateFormat formatter = DateFormat.getDateInstance(); // just date, you might want something else
formatter.setTimeZone(pstTimeZone);
String formattedDate = formatter.format(startTime);

However, if you really need to convert dates (which is really rare), you might want to use following code snippet:

TimeZone pacificTimeZone = TimeZone.getTimeZone("America/Los_Angeles");
long currentTime = new Date().getTime();
long convertedTime = currentTime +
    pacificTimeZone.getOffset(currentTime);

This will give you number of milliseconds that passed since January 1st, 1970 in PST TimeZone. You can easily create Date object with this information.
If you need to perform date calculations quite often, you may want to use Apache Commons Lang's DateUtils. Or switch to JodaTime as mdrg suggested.



回答3:

Never depend on server’s time zone

Never depend or rely on the server’s or host JVM’s current default time zone.

Always specify your desired/expected time zone explicitly, passed as optional argument.

java.time

The java.util.Calendar class is now legacy, supplanted by the java.time classes.

Get the current moment in UTC. 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();

instant.toString(): 2017-01-19T22:01:21.321Z

When you want to view that moment through the lens of a particular region’s wall-clock time, 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 PST 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 );

zdt.toString(): 2017-01-19T14:01:21.321-08:00[America/Los_Angeles]


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 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.