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

时间:2016-10-17 13:40:56

标签: java calendar timezone date-format simpledateformat

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

一直在尝试用Java解析相同的Date对象。预期的结果是

  

FastTime = 1451908800000。2016年1月4日(星期一)格林威治标准时间下午12:00:00

尝试过这样的事情

mainPanel(width = 9,
   tabsetPanel("tab",
   tabPanel(strong("Count of Objects"), tableOutput("mon")),
   tabPanel(strong("% of Objects"), tableOutput("mon_per")))

但解析后的输出是

  

FastTime = 1451822400000。 2016年1月3日星期日格林威治标准时间12:00:00 PM

如何使DateFormat采用与其相同的时区。

非常感谢任何帮助。

提前致谢。

2 个答案:

答案 0 :(得分:1)

java.time

您正在使用现在由java.time类取代的麻烦的旧日期时间类。

LocalDate类代表一个仅限日期的值,没有时间和没有时区。

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

现在分配一个时间和一个offset-from-UTC来传递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。切勿使用诸如ESTIST之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

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

zdt.toString():2016-01-05T00:00 + 12:00 [亚洲/堪察加]

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date.Calendar和& java.text.SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 1 :(得分:0)

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

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

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