Java:如何将UTC时间戳转换为本地时间?

我有一个UTC时间戳,我想将它转换为本地时间而不使用像TimeZone.getTimeZone("PST")这样的API调用。 你到底应该怎么做? 我一直在使用以下代码但没有取得多大成功:

 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(); 

输入值示例: [2012-08-15T22:56:02.038Z]

应该返回相当于[2012-08-15T15:56:02.038Z]

Date没有时区,内部存储在UTC中。 仅在格式化日期时才适用时区校正。 使用DateFormat ,它默认为运行它的JVM的时区。使用setTimeZone根据需要进行更改。

 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)); 

这打印2012-08-15T15:56:02.038

请注意,我在PST格式中省略了'Z' ,因为它表示UTC。 如果您刚刚使用Z那么输出将是2012-08-15T15:56:02.038-0700

使用现代Java日期和时间API,这很简单:

  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); 

这打印

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

注意事项:

  • 你的期望有一点小错误。 时间戳中的Z表示UTC,也称为祖鲁时间。 因此,在您当地的时间价值中, Z不应该在那里。 相反,你会想要一个返回值,例如2012-08-15T15:56:02.038-07:00 ,因为偏移现在是-7小时而不是Z.
  • 避免使用三个字母的时区缩写。 它们不是标准化的,因此通常是模棱两可的。 例如,PST可能意味着Philppine标准时间,太平洋标准时间或皮特凯恩标准时间(虽然缩写中的S通常用于夏季时间(意味着DST))。 如果您打算太平时标准时间,那甚至不是时区,因为在夏天(您的样本时间戳下降)使用太平洋夏令时代替。 而不是缩写在我的代码中使用格式region / city中的时区ID。
  • 时间戳通常最好作为Instant对象处理。 仅在您需要时转换为ZonedDateTime ,例如演示文稿。

问题:我可以在Java版本中使用现代API吗?

如果至少使用Java 6 ,则可以。

  • 在Java 8及更高版本中,新的API内置。
  • 在Java 6和7中获取ThreeTen Backport ,这是新类的后端(这是JSR-310的ThreeTen,其中首先定义了现代API)。
  • 在Android上,使用Android版的ThreeTen Backport。 它被称为ThreeTenABP,我认为这个问题有一个很好的解释:如何在Android项目中使用ThreeTenABP 。

这是一个简单修改的​​解决方案

  public String convertToCurrentTimeZone(String Date) { String converted_date = ""; try { DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); utcFormat.setTimeZone(TimeZone.getTimeZone("UTC")); Date date = utcFormat.parse(Date); DateFormat currentTFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); currentTFormat.setTimeZone(TimeZone.getTimeZone(getCurrentTimeZone())); converted_date = currentTFormat.format(date); }catch (Exception e){ e.printStackTrace();} return converted_date; } //get the current time zone public String getCurrentTimeZone(){ TimeZone tz = Calendar.getInstance().getTimeZone(); System.out.println(tz.getDisplayName()); return tz.getID(); }