DateFormat格式方法不会向特定TimeZone显示已解析的日期

时间:2015-12-10 11:09:23

标签: java date datetime time

我通过SimpleDateFormat将日期字符串转换为日期(" yyyy-MM-dd' T' HH:mm:ssZ")。解析(DateinString)。
这里不是转换为UTC而是转换为我的本地TimeZone。我通过DateFormat的格式化方法显示这个解析日期来检查它。

所以我必须重新格式化回UTC.Now当我试图通过相同的格式方法将此解析日期显示给UTC TimeZone时,它仍然显示在本地TimeZone中。以下是我将解析日期格式化为UTC的代码 -

Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
cal.setTime(alreadyParsedDateTime); // 
System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(cal.getTime()));       

我的样本日期字符串为" 2015-12-23T15:00:00-0800"
解析后--readyParsedDateTime.toString():: Thu Dec 24 04:30:00 IST 2015
解析后 - System.out.println(新的SimpleDateFormat(" yyyy-MM-dd' T' HH:mm:ss")。format(alreadyParsedDateTime)):: 2015-12-24T04:30: 00

在上面提到的将解析日期重新格式化为UTC之后 - System.out.println(新的SimpleDateFormat(" yyyy-MM-dd' T' HH:mm:ss")。format(cal.getTime())):: 2015-12- 24T04:30:00

预计日期格式为:: 2015-12-23T23:00:00

我不知道为什么格式方法不能以预期的方式工作,或者有任何技巧可以做同样的事情。请帮助..

2 个答案:

答案 0 :(得分:2)

这里有两个不同的主题;解析和格式化。

1。解析

SimpleDateFormat.parse()将尝试从提供的日期字符串中解析时区。如果您要解析的日期字符串不包含显式时区,那么"默认"将使用SimpleDateFormat对象上的时区。您可以使用setTimeZone()方法设置默认时区。请参阅SimpleDateFormat.parse()DateFormat.setTimeZone()的API文档以供参考。

这是一个示例,显示解析如何受setTimeZone()设置的时区影响:

    String dateString = "2015.12.10 13:58:18";

    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
    sdf1.setTimeZone(TimeZone.getTimeZone("GMT"));
    Date date1 = sdf1.parse(dateString);

    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
    sdf2.setTimeZone(TimeZone.getTimeZone("EST"));
    Date date2 = sdf2.parse(dateString);

    // Shows that the parsing honours time zone -- will print:
    // Thu Dec 10 14:58:18 CET 2015 (original date was parsed as GMT)
    // Thu Dec 10 19:58:18 CET 2015 (original date was parsed as EST)
    System.out.println(date1);
    System.out.println(date2);

2。格式化

假设日期已正确解析,那么问题在于格式化。您需要为正在用于格式化的实际SimpleDateFormat对象设置时区。我修改了你的代码来执行此操作,现在它将打印出你所使用的内容:

    Calendar cal = Calendar.getInstance();
    cal.setTime(alreadyParsedDateTime);
    SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    sdf3.setTimeZone(TimeZone.getTimeZone("UTC"));

    // Prints: 2015-12-23T23:00:00 for your example date string
    System.out.println(sdf3.format(cal.getTime()));

答案 1 :(得分:0)

TL;博士

UTC当前时刻。

Instant.now()        // Capture current moment in UTC.
    .toString()      // Generate string in standard ISO 8601 format.
  

2018-02-11T22:13:28.650328Z

调整到另一个时区。

instant.atZone(      // Apply a `ZoneId` to `Instant` object to get a `ZonedDateTime` object.
    ZoneId.of( "Pacific/Auckland" )
).toString()
  

2018-02-12T11:13:28.650328 + 13:00 [太平洋/奥克兰]

或者将当前时刻直接捕捉到该区域。

ZonedDateTime.now(   // Capture current moment as seen on the wall-clock time of the people in a particular region.
    ZoneId.of( "Pacific/Auckland" )
).toString()         // Generate string in standard ISO 8601 format, wisely extended by appending the name of the time zone in square brackets.
  

2018-02-12T11:13:28.650328 + 13:00 [太平洋/奥克兰]

详细

Answer by Grodriguez是正确但过时的。

java.time

现代方法使用 java.time 类来取代麻烦的旧遗留日期时间类。

您的输入字符串符合ISO 8601格式标准。解析/生成字符串时, java.time 类默认使用这些格式。因此无需指定格式化模式。

Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

捕获UTC中的当前时刻。

Instant instant = Instant.now() ;  // Current moment in UTC.

要通过镜头观看另一个地区(时区)的人使用的挂钟时间同一时刻,请应用ZoneId获取ZonedDateTime对象。

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

请注意,我们在这里使用智能对象,而不是愚蠢的字符串。不要将日期时间对象与仅以文本方式表示其值的字符串混淆。

如果您想以标准ISO 8601格式生成字符串,请调用toString方法。

String outputA = instant.toString() ;
String outputB = zdt.toString() ;

要生成其他格式的字符串,请使用DateTimeFormatterDateTimeFormatterBuilder类。两者都在Stack Overflow上广泛涉及,因此请搜索更多信息。

关于 java.time

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

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

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

如果JDBC driver符合JDBC 4.2或更高版本,您可以直接与数据库交换 java.time 对象。不需要字符串或java.sql。* classes。

从哪里获取java.time类?

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