joda时间到达日期不一致的时区

时间:2015-09-23 18:35:20

标签: java timezone jodatime

我有一大堆日期,我希望将它存储在使用BST在服务器上运行的数据库中:

  1. 2015-09-23
  2. 2024-05-07
  3. 2024-03-13
  4. 但是它们存储在DB中:

    1. 2015-09-23 01:00:00
    2. 2024-05-07 01:00:00
    3. 2024-03-13 00:00:00< - 我需要这是01:00:00
    4. 在存储到数据库之前,这些值将转换为Date。调试时我注意到以下内容:

      TimeZone timeZone = Calendar.getInstance().getTimeZone();
      System.out.println(timeZone.getDisplayName(false, TimeZone.SHORT));
      
      System.out.println(new SimpleDateFormat("zzz").format(new Date()));
      
      DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd").withZone(DateTimeZone.UTC);
      System.out.println(formatter.parseDateTime("2015-09-23").toDate());
      System.out.println(formatter.parseDateTime("2024-05-07").toDate());
      System.out.println(formatter.parseDateTime("2024-03-13").toDate());
      

      前两个日期使用BST,最后一个日期为GMT。是否可以使它们都使用相同的时区?

      GMT
      BST
      Wed Sep 23 01:00:00 BST 2015
      Tue May 07 01:00:00 BST 2024
      Wed Mar 13 00:00:00 GMT 2024
      

2 个答案:

答案 0 :(得分:1)

首先,请注意java.util.Date没有时区(有关详细信息,请参阅here)。

Date.toString()方法使用系统的默认时区来打印其值(检查JVM中TimeZone.getDefault()的值,它可能是{{1} }})。

Europe/London时区,偏移量等于冬季的 UTC (打印为Europe/London),夏季为GMT(打印为+01:00,又名British Summer Time)。这些不同的3个字母的名称表示偏移量变化,但它并不代表日期"更改"他们的时区。

还要考虑时区不仅是偏移量或名称,还有the set of all offset changes that occur in a region during history(发生更改时,以及每次更改前后的偏移量)。

因此,日期没有不同的时区,因为:

  1. 在同一时区,可以有超过1个偏移量。并且偏移中的一些更改会导致3个字母的名称发生变化 - 尽管这些3个字母的名称的使用被广泛使用,但他们还是ambiguous and not standard
  2. java.util.Date doesn't have a timezone,因此无法更改。
  3. 如果要将这些对象保存在数据库中,您应该关注的是时间戳(BST的毫秒数),转换为1970-01-01T00:00:00Z时会保留该时间戳。

    如果检查创建的对象中的时间戳毫秒,您会发现它没有被更改:

    Date

    以上所有3个案例都打印DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd").withZone(DateTimeZone.UTC); DateTime d1 = formatter.parseDateTime("2015-09-23"); DateTime d2 = formatter.parseDateTime("2024-05-07"); DateTime d3 = formatter.parseDateTime("2024-03-13"); // comparing timestamp millis between DateTime and java.util.Date System.out.println(d1.getMillis() == d1.toDate().getTime()); System.out.println(d2.getMillis() == d2.toDate().getTime()); System.out.println(d3.getMillis() == d3.toDate().getTime()); ,这意味着它们代表了同一时刻(因此日期没有改变)。

    实际上,您可以看到所有true个对象都是UTC:

    DateTime

    打印:

      

    2015-09-23T00:00:00.000Z
      2024-05-07T00:00:00.000Z
      2024-03-13T00:00:00.000Z

    结论:

    • 您可以毫无问题地保存System.out.println(d1); System.out.println(d2); System.out.println(d3); 个对象,因为它们的值是正确的
    • 如果您想向用户显示日期,可以使用Date个对象(如果您想要不同的格式,可以使用DateTime),因为他们不会使用DateTimeFormatter方法中的默认TimeZone

答案 1 :(得分:0)

试试这个:     SimpleTimeZone UTCTimeZone = new SimpleTimeZone(0, "UTC"); TimeZone.setDefault(UTCTimeZone); 所有日期对象都将使用UTC作为后端代码的默认时区