【问题标题】:Java getting UTC+2 when it would be UTC+1Java 在 UTC+1 时获得 UTC+2
【发布时间】:2016-11-02 14:23:15
【问题描述】:

上周日我们更改了中欧的时间 (-1h)。我正在做一些测试,但有些东西不能让我用 java 时间解析器睡觉。这是代码

public static void main(String[] args) {
    String dateFormatPattern = "yyyy-MM-dd HH:mm:ss";
    String dateUtc = "2016-10-09 12:50:00";

    SimpleDateFormat dateFormatUtc = new SimpleDateFormat(dateFormatPattern);
    dateFormatUtc.setTimeZone(TimeZone.getTimeZone("UTC"));

    SimpleDateFormat dateFormatLisboa = new SimpleDateFormat(dateFormatPattern);
    dateFormatLisboa.setTimeZone(TimeZone.getTimeZone("Europe/Lisboa"));

    SimpleDateFormat dateFormatMadrid = new SimpleDateFormat(dateFormatPattern);
    dateFormatMadrid.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));

    SimpleDateFormat dateFormatParis = new SimpleDateFormat(dateFormatPattern);
    dateFormatParis.setTimeZone(TimeZone.getTimeZone("Europe/Paris"));

    System.out.println("UTC: "+dateUtc);
    try {
        Date d = dateFormatUtc.parse(dateUtc);
        System.out.println("Lisboa: "+dateFormatLisboa.format(d));
        System.out.println("Madrid: "+dateFormatMadrid.format(d));
        System.out.println("Paris: "+dateFormatParis.format(d));
    } catch (ParseException e) {
        e.printStackTrace();
    }
}

这是输出

UTC: 2016-10-09 12:50:00
Lisboa: 2016-10-09 12:50:00
Madrid: 2016-10-09 14:50:00
Paris: 2016-10-09 14:50:00

为什么 UTC 和马德里时间相差 2 小时?现在在马德里是 UTC+1。

谢谢。

【问题讨论】:

  • 时钟是哪一天改的?如果你这样做String dateUtc = "2016-11-02 12:50:00";会发生什么?
  • 谢谢,你是对的。我对时间变化视而不见,我没有意识到字符串日期更早:(
  • 别担心,它的经典,需要另一双眼睛,东西。叫别人看东西我就解决了这么多。
  • 仅供参考,那些日期时间类现在是遗留的,被 java.time 类所取代。迁移到 java.time 将使您的生活更轻松。

标签: java date timezone


【解决方案1】:

时间是正确的,因为时钟在 10 月 30 日凌晨 2 点改变

如果您将代码更改为此

String dateUtc = "2016-11-09 12:50:00";

你得到这个输出,给出正确的 1 小时差。

UTC: 2016-11-09 12:50:00
Lisboa: 2016-11-09 12:50:00
Madrid: 2016-11-09 13:50:00
Paris: 2016-11-09 13:50:00

时区是由于日期对象实际引用的时间。所以当时是正确的

【讨论】:

    【解决方案2】:

    法语接受的答案是正确的。这些值与夏令时 (DST) 中的切换重叠。

    我只是指出您的代码正在使用旧的日期时间类,现在是遗留的,被 java.time 类取代。

    将输入值解析为 LocalDateTime,因为它缺少任何时区指示符或与 UTC 的偏移量。

    将中间的空格替换为T,以符合 java.time 类中用于解析/生成字符串的默认 ISO 8601 格式。

    LocalDateTime ldt = LocalDateTime.parse( "2016-10-09 12:50:00".replace( " " , "T" ) );
    

    我们从业务上下文中知道 UTC 用于此输入字符串。所以分配一个UTC的偏移量。

    OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );
    

    通过应用ZoneId 来调整到时区以获得ZonedDateTime

    ZoneId z = ZoneId.of( "Europe/Lisboa" );
    ZonedDateTime zdt = odt.atZoneSameInstant( z );
    


    关于java.time

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

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

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

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

    从哪里获得 java.time 类?

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

    • 感谢您的回答,但应用程序必须在 java 7 中运行。正如您所解释的,java 8 有新的库来处理日期,公平且必要,aleluya!
    • @JonAnder java.time 的大部分功能在 ThreeTen-Backport 项目中被反向移植到 Java 6 和 7。
    猜你喜欢
    • 2020-11-26
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    • 2021-10-02
    • 2014-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多