Converting date from UTC to PST in Java
I need to convert date from Google App Engine local server time zone to pacific time in Java.
I tried using
Calendar calstar开发者_开发知识库t =
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?
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.
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.
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
.
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 brought 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 (26+) bundle implementations of the java.time classes.
- For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android.
- If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
精彩评论