在不同时区之间格式化时间的正确方法是什么?

时间:2018-05-30 09:40:54

标签: java formatting timezone jodatime

我想将19:19:00的时间格式化为不同的时区。如果我使用SimpleDateFormat,它总是考虑到纪元的开始:1970.01.01。

某些时区在时代的开始和现在有不同的偏移。例如,欧洲/基辅的默认偏移现在是UTC + 0200,但在1970年它是UTC + 0300。这意味着如果我在欧洲/基辅下运行我的服务器,在欧洲/柏林(UTC + 0100)下登录的客户将看到三个小时而不是两个小时。

我可以通过为java.sql.Time编写自定义格式化程序来解决此问题。但我想问一下可能有一些常用的方法或Java工具/库可以解决它。

另一个解决方案是使用joda-time:

TimeZone.setDefault(TimeZone.getTimeZone("Europe/Kiev"));
DateTimeZone.setDefault(DateTimeZone.forID("Europe/Kiev"));

DateTimeFormat.forPattern("HH:mm:ss.SSS")
   .withZone(DateTimeZone.forID("Europe/Berlin"))
   .print(Time.valueOf("19:00:00").getTime());

3 个答案:

答案 0 :(得分:1)

您无法将 格式化为不同时区的时间。你需要约会。

如果您想假设当天的日期是今天,您可以尝试以下代码:

ZoneId originalZone = ZoneId.of("Europe/Kiev");
ZoneId targetZone = ZoneId.of("Europe/Berlin");
LocalTime originalTime = LocalTime.parse("19:19:00");
LocalTime convertedTime = LocalDate.now(originalZone)
                            .atTime(originalTime)
                            .atZone(originalZone)
                            .withZoneSameInstant(targetZone)
                            .toLocalTime();
System.out.println(convertedTime);

答案 1 :(得分:0)

java.time.instant是你的另类选择吗?它在内部处理所有时间戳作为UTC时间。

从字符串中解析它的一种方法是Instant.parse("2018-05-30T19:00:00")

如果您想拥有特定时区的时间,可以使用myInstant.atZone("Zone")

获取

答案 2 :(得分:0)

    ZoneId originalZone = ZoneId.of("Europe/Kiev");
    ZoneId targetZone = ZoneId.of("Europe/Berlin");
    LocalDate assumedDate = LocalDate.now(originalZone);
    String formattedTime = assumedDate.atTime(LocalTime.parse("19:19:00"))
            .atZone(originalZone)
            .withZoneSameInstant(targetZone)
            .format(DateTimeFormatter.ofPattern("HH:mm:ss"));
    System.out.println(formattedTime);

今天打印出来了:

  

十八点十九分00秒

当你知道日期时,你当然应该使用它而不仅仅是今天。在基辅和柏林的情况下,我认为它们遵循夏季时间(DST)的相同规则,因此确切的日期可能并不重要。如果在不使用相同过渡的区域之间或在使用夏令时的区域和不使用夏令时的区域之间进行转换,则突然变得至关重要。谁知道这两个国家中哪些政治家明年会改变规则?更安全。

链接: Oracle tutorial: Date Time解释如何使用java.time