如何使日期格式将字符串日期解析为指定的时区

How to make DateFormat to parse String date to the assigned timezone

我有一个 "yyyyMMdd" 的字符串日期“20160104”,它是 GMT-12 时区。

一直在尝试将相同的内容解析为 Java 中的 Date 对象。预期结果是

FastTime = 1451908800000. Monday, January 4, 2016 12:00:00 PM GMT

试过这样的东西

DateFormat gmtMinus12 = new SimpleDateFormat("yyyyMMdd");
gmtMinus12.setTimeZone(TimeZone.getTimeZone("Etc/GMT-12"));
// gmtMinus12.getCalendar().setTimeZone(TimeZone.getTimeZone("Etc/GMT-12"));
gmtMinus12
    .setCalendar(Calendar.getInstance(TimeZone.getTimeZone("Etc/GMT-12")));

try {
  Date date = gmtMinus12.parse("20160104");

} catch (ParseException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}

但是解析后的输出是

FastTime = 1451822400000 . Sunday, January 3, 2016 12:00:00 PM GMT

如何使 DateFormat 与指定的时区相同。

非常感谢任何帮助。

提前致谢。

java.time

您使用的是麻烦的旧日期时间 classes 现在已被 java.time classes 取代。

LocalDate class 表示仅日期值,没有时间和时区。

DateTimeFormatter f = DateTimeFormatter.ofPattern ( "uuuuMMdd" );
LocalDate ld = LocalDate.parse ( "20160104" , f );

现在分配一个时间和一个 offset-from-UTC to deliver a OffsetDateTime 对象。

ZoneOffset offset = ZoneOffset.ofHours ( -12 );
LocalTime lt = LocalTime.MIN;  // 00:00
OffsetTime ot = OffsetTime.of ( lt , offset );
OffsetDateTime odt = ot.atDate ( ld );

odt.toString(): 2016-01-04T00:00-12:00

要在 UTC 中查看同一时刻,请提取一个 Instant

Instant instant = odt.toInstant();

instant.toString(): 2016-01-04T12:00:00Z

如您所料,UTC 时间是 4 号中午。

时区

您应该知道 GMT-12 而不是 时区。这是一个 offset-from-UTC.

一个time zone是一个偏移加上一套处理异常的规则,比如夏令时(DST)。

如果您知道预期的时区,则应该应用它,而不仅仅是偏移量。以 continent/region 的格式指定 proper time zone name。切勿使用 3-4 个字母的缩写,例如 ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "Asia/Kamchatka" );
ZonedDateTime zdt = odt.atZoneSameInstant( z );

zdt.toString(): 2016-01-05T00:00+12:00[Asia/Kamchatka]

关于java.time

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, & java.text.SimpleDateFormat.

Joda-Time project, now in maintenance mode,建议迁移到java.time。

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

从哪里获得java.time classes?

  • Java SE 8 and SE 9 及更高版本
    • 内置。
    • 标准 Java API 的一部分,带有捆绑实施。
    • Java 9 添加了一些小功能和修复。
  • Java SE 6 and SE 7
  • Android
    • ThreeTenABP项目专门为Android改编了ThreeTen-Backport(上面提到的)。
    • 参见

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.

您真正的问题不只是使用了旧的和笨拙的 API,而是 使用了错误的偏移量 。请使用

Etc/GMT+12 (=UTC-12:00) 而不是 Etc/GMT-12 (=UTC+12:00).

过时的 Etc/...-notation 非常混乱,因为它使用标准时区偏移量的相反符号,另请参阅嵌入的 translation table in TZ-database.