Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: How do you convert a UTC timestamp to local time?

I have a timestamp that's in UTC and I want to convert it to local time without using an API call like TimeZone.getTimeZone("PST"). How exactly are you supposed to do this? I've been using the following code without much success:

private static final SimpleDateFormat mSegmentStartTimeFormatter = new        SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");  Calendar calendar = Calendar.getInstance();      try {         calendar.setTime(mSegmentStartTimeFormatter.parse(startTime));     }     catch (ParseException e) {         e.printStackTrace();     }      return calendar.getTimeInMillis(); 

Sample input value: [2012-08-15T22:56:02.038Z]

should return the equivalent of [2012-08-15T15:56:02.038Z]

like image 991
Android Noob Avatar asked Sep 19 '12 00:09

Android Noob


People also ask

How do I convert UTC timestamp to local timestamp?

(GMT-5:00) Eastern Time (US & Canada)Add the local time offset to the UTC time. For example, if your local time offset is -5:00, and if the UTC time is shown as 11:00, add -5 to 11. The time setting when adjusted for offset is 06:00 (6:00 A.M.).

How do you convert UTC to specific time zones?

The best way to do this is simply to use TimeZoneInfo. ConvertTimeFromUtc . // you said you had these already DateTime utc = new DateTime(2014, 6, 4, 12, 34, 0); TimeZoneInfo tzi = TimeZoneInfo. FindSystemTimeZoneById("Pacific Standard Time"); // it's a simple one-liner DateTime pacific = TimeZoneInfo.

How do I convert DateTime to local time?

The ToLocalTime method converts a DateTime value from UTC to local time. To convert the time in any designated time zone to local time, use the TimeZoneInfo. ConvertTime method. The value returned by the conversion is a DateTime whose Kind property always returns Local.


2 Answers

Date has no timezone and internally stores in UTC. Only when a date is formatted is the timezone correction applies. When using a DateFormat, it defaults to the timezone of the JVM it's running in. Use setTimeZone to change it as necessary.

DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));  Date date = utcFormat.parse("2012-08-15T22:56:02.038Z");  DateFormat pstFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); pstFormat.setTimeZone(TimeZone.getTimeZone("PST"));  System.out.println(pstFormat.format(date)); 

This prints 2012-08-15T15:56:02.038

Note that I left out the 'Z' in the PST format as it indicates UTC. If you just went with Z then the output would be 2012-08-15T15:56:02.038-0700

like image 66
Steve Kuo Avatar answered Sep 28 '22 04:09

Steve Kuo


Use the modern Java date & time API, and this is straightforward:

    String inputValue = "2012-08-15T22:56:02.038Z";     Instant timestamp = Instant.parse(inputValue);     ZonedDateTime losAngelesTime = timestamp.atZone(ZoneId.of("America/Los_Angeles"));     System.out.println(losAngelesTime); 

This prints

2012-08-15T15:56:02.038-07:00[America/Los_Angeles] 

Points to note:

  • There’s a little bug in your expectations. The Z in your timestamp means UTC, also known as Zulu time. So in your local time value, the Z should not be there. Rather you would want a return value like for example 2012-08-15T15:56:02.038-07:00, since the offset is now -7 hours rather than Z.
  • Avoid the three letter time zone abbreviations. They are not standardized and therefore most often ambiguous. PST, for example, may mean Philppine Standard Time, Pacific Standard Time or Pitcairn Standard Time (though S in an abbreviation is often for summer time (meaning DST)). If you intended Pacific Standard Time, that isn’t even a time zone, since in summer (where your sample timestamp falls) Pacific Daylight Time is used instead. Instead of the abbreviations use time zone IDs in the format region/city as in my code.
  • Timestamps are generally best handled as Instant objects. Convert to ZonedDateTime only when you have a need, like for presentation.

Question: Can I use the modern API with my Java version?

If using at least Java 6, you can.

  • In Java 8 and later the new API comes built-in.
  • In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (that’s ThreeTen for JSR-310, where the modern API was first defined).
  • On Android, use the Android edition of ThreeTen Backport. It’s called ThreeTenABP, and I think that there’s a wonderful explanation in this question: How to use ThreeTenABP in Android Project.
like image 30
Ole V.V. Avatar answered Sep 28 '22 04:09

Ole V.V.