繁体   English   中英

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

[英]joda time to Date inconsistent time zones

我有很多日期要存储在使用 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. 在同一时区中可以有 1 个以上的偏移量。 并且偏移量的一些变化导致了 3 个字母名称的变化——虽然这些 3 个字母名称的使用被广泛使用,但它们是模棱两可的,不标准的
  2. java.util.Date没有 timezone ,所以它不能改变它。

如果您想将这些对象保存在数据库中,您应该关心的是时间戳(从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());

上面的所有 3 种情况都打印true ,这意味着它们代表同一时刻(因此日期没有改变)。

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

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

这打印:

2015-09-23T00:00: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); SimpleTimeZone UTCTimeZone = new SimpleTimeZone(0, "UTC"); TimeZone.setDefault(UTCTimeZone); 所有日期对象都将使用 UTC 作为后端代码的默认时区

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM