【问题标题】:How to get the difference without timezones between two times?如何获得两次之间没有时区的差异?
【发布时间】:2011-07-27 09:07:48
【问题描述】:

A very strange date before 1970的问题中,我知道为什么两次看起来只有1s的差异,但有时我们可以得到另一个值。

例如从那个问题:

public static void main(String[] args) throws ParseException {
    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
    String str3 = "1927-12-31 23:54:07";  
    String str4 = "1927-12-31 23:54:08";  
    Date sDt3 = sf.parse(str3);  
    Date sDt4 = sf.parse(str4);  
    long ld3 = sDt3.getTime() /1000;  
    long ld4 = sDt4.getTime() /1000; 
    System.out.println(ld4-ld3);
}

Shanghai 的时区中输出将是353,但在其他时区将是1

我的问题是,如何计算没有时区的差异?如何始终获得正确的差异?

【问题讨论】:

  • 没有“正确”的区别。差异取决于时区!
  • 如果您想一直使用同一个时区,您是否尝试过创建日历对象并指定您要使用的时区?
  • 日历标准日历 = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
  • @Ritchie:GMT 可能仍有不连续性。
  • 这里正确的差异是 1 的整个想法是错误的。正确的差是 353。时间很奇怪。处理它。

标签: java datetime


【解决方案1】:

您可以使用Joda Time 轻松处理时区。

  • 您可以创建具有所需时区的DateTimeFormatter 并使用它来解析字符串。 DateTime 实例也可以是converted to other time zones

  • 您可以使用LocalDateTime 类完全忽略时区。

  • 此外,Period 类具有 toStandardSeconds()toStandardDuration()normalizedStandard() 等方法,“假设所有周为 7 天,所有天为 24 小时,所有小时为 60分钟和所有分钟都是 60 秒。如果考虑夏令时,这不是真的,对于一些不寻常的年表也可能不是真的。但是,它被包括在内,因为它对许多应用程序和业务规则来说是一个有用的操作。"

以下是如何直接或通过从有时区的 DateTime 实例转换来构造无时区的 LocalDateTime。

LocalDateTime a1 = new LocalDateTime(1927, 12, 31, 0, 0, 0, 0);
LocalDateTime a2 = new LocalDateTime(1928, 1, 2, 0, 0, 0, 0);
System.out.println(a1);
System.out.println(a2);
System.out.println(Seconds.secondsBetween(a1, a2).getSeconds()); // 172800 == 60 * 60 * 24 * 2 == 2 days without leap seconds

DateTime b1 = new DateTime(1927, 12, 31, 0, 0, 0, 0, DateTimeZone.forID("Asia/Shanghai"));
DateTime b2 = new DateTime(1928, 1, 2, 0, 0, 0, 0, DateTimeZone.forID("Asia/Shanghai"));
System.out.println(b1);
System.out.println(b2);
System.out.println(Seconds.secondsBetween(b1, b2).getSeconds());

LocalDateTime c1 = b1.toLocalDateTime();
LocalDateTime c2 = b2.toLocalDateTime();
System.out.println(c1);
System.out.println(c2);
System.out.println(Seconds.secondsBetween(c1, c2).getSeconds());

这将打印如下。注意its timezone adjustment in 1927之前上海时间的搞笑时区。

1927-12-31T00:00:00.000
1928-01-02T00:00:00.000
172800
1927-12-31T00:00:00.000+08:05:52
1928-01-02T00:00:00.000+08:00
173152
1927-12-31T00:00:00.000
1928-01-02T00:00:00.000
172800

【讨论】:

  • -1 表示有可能,但没有说明如何。
  • 是的,但这能解决什么问题?这个特定的日期将在 GMT 中解析得“更好”,但在其他日期,GMT 也会有闰秒之类的东西。
  • 对于“正确”的最常见定义,两次之间的正确差异需要考虑闰秒等。
  • @Esko:所以 353 与 1 一样“正确”。答案取决于时区。你不能“计算没有时区的差异”。
  • 感谢您的澄清。 Downvote 名义上是为了提供详细信息而删除的,但名义上是为了提出一些建议而添加的 downvote (a) 不能解决“问题”,因为 GMT 可能仍然存在不连续性,并且 (b) 可以在 JDK 中的类中同样出色地完成。
【解决方案2】:

在上海,此时时区从 LMT 更改为 CST。

1928 年 1 月 1 日星期日,00:00:00 时钟被调回 0:05:52 时 改为 1927 年 12 月 31 日星期六 23:54:08 当地标准时间

http://www.timeanddate.com/worldclock/clockchange.html?n=237&year=1927

【讨论】:

  • GMT 是否也发生了类似的情况?
  • AFAIK,格林威治标准时间自 1675 年以来没有改变。UTC 是最近的变化。 en.wikipedia.org/wiki/Time_zone
  • 但是没有闰秒吗?不过,这不是五分钟。 en.wikipedia.org/wiki/Leap_second
  • 我相信这是 UTC 和 GMT 之间的差异之一。 Java 使用没有闰秒的 GMT。每天正好是 24*60*60*1000 毫秒长。
【解决方案3】:

不要将每个date 转换成长的代码:

long i = (sDt4.getTime() - sDt3.getTime()) / (1000);
System.out.println(i);

输出是:

1

【讨论】:

  • 恐怕不是它在不同语言环境中具有不同值的原因。
猜你喜欢
  • 1970-01-01
  • 2014-05-14
  • 1970-01-01
  • 2021-12-28
  • 2017-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多