joda时间到日期时区不一致



我有一堆日期,我想用BST:存储在服务器上运行的数据库中

  1. 2015-09-23
  2. 2024-05-07
  3. 2024-03-13

然而,它们在数据库中存储为:

  1. 2015-09-23 01:00:00
  2. 2024-05-07 01:00:00
  3. 2024-03-13 00:00:00<--我需要这个是01:00:00

这些值在被存储在DB中之前被转换为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

首先,请记住java.util.Date没有时区(有关它的更多详细信息可以在此处阅读(。

结果是Date.toString()方法使用系统的默认时区来打印其值(在JVM中检查TimeZone.getDefault()的值,它可能是Europe/London(。

Europe/London时区,偏移量在冬季等于UTC(打印为GMT(,在夏季等于+01:00(打印为BST,即英国夏令时间(。这些不同的3个字母的名称表示偏移量的变化,但这并不意味着日期"改变"了时区。

还要考虑时区不仅是偏移量或名称,而且是历史期间某个区域中发生的所有偏移量更改的集合(更改发生时以及每次更改前后的偏移量(。

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

  1. 在同一时区中,可以有一个以上的偏移。偏移量的一些变化导致了3个字母名称的变化——尽管这些3个字母的名称被广泛使用,但它们是模糊的,不是标准的
  2. java.util.Date没有时区,因此无法更改

如果您想将这些对象保存在数据库中,那么您应该关心的是时间戳(从1970-01-01T00:00:00Z开始的毫秒数(,它在转换为Date时会被保留。

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

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,这意味着它们代表相同的时间瞬间(因此日期没有改变(。

实际上,您可以看到所有DateTime对象都在UTC:中

System.out.println(d1);
System.out.println(d2);
System.out.println(d3);

此打印:

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

结论:

  • 您可以毫无问题地保存Date对象,因为它们的值是正确的
  • 如果要向用户显示日期,可以使用DateTime对象(如果需要不同的格式,则使用DateTimeFormatter(,因为它们在toString()方法中不使用默认的TimeZone

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

最新更新