[java] 为什么要减去这两次(在1927年)给出一个奇怪的结果?


Answers

您遇到了当地时间不连续问题

当地方标准时间即将到达星期日时,1928年1月1日00:00:00时钟被转换为0:05:52小时至星期六,1927年12月31日,23:54:08当地标准时间

这并不奇怪,并且由于政治或行政行为而导致时区被切换或更改,因此在任何时候都会发生。

Question

如果我运行下面的程序,该程序分析引用时间间隔1秒的两个日期字符串并对它们进行比较:

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);
}

输出是:

353

为什么ld4-ld3不是1 (正如我期望的那样,时间差一秒钟),但是353

如果我将日期更改为1秒后的时间:

String str3 = "1927-12-31 23:54:08";  
String str4 = "1927-12-31 23:54:09";  

那么ld4-ld3将是1

Java版本:

java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Dynamic Code Evolution Client VM (build 0.2-b02-internal, 19.0-b04-internal, mixed mode)

Timezone(`TimeZone.getDefault()`):

sun.util.calendar.ZoneInfo[id="Asia/Shanghai",
offset=28800000,dstSavings=0,
useDaylight=false,
transitions=19,
lastRule=null]

Locale(Locale.getDefault()): zh_CN



增加时间时,应该将其转换回UTC,然后进行加或减。 仅使用本地时间进行显示。

通过这种方式,您将能够在几小时或几分钟发生两次的任何时间内步行。

如果您转换为UTC,请每秒添加一次,然后转换为本地时间以供显示。 您将经过11:54:08 pm LMT - 11:59:59 pm LMT ,然后11:54:08 pm CST - 11:59:59 pm CST。




恕我直言,Java中普遍的, 隐含的本地化是其最大的单一设计缺陷。 它可能是面向用户界面的,但坦率地说,现在谁真的在用户界面上使用Java,除了一些IDE,基本上可以忽略本地化,因为程序员并不完全是它的目标受众。 你可以通过以下方式修复它(尤其是在Linux服务器上):

  • 导出LC_ALL = C TZ = UTC
  • 将系统时钟设置为UTC
  • 除非绝对必要,否则不要使用本地化实现(即仅用于显示)

对于我推荐的Java社区过程成员:

  • 使本地化的方法不是默认的,但要求用户明确要求本地化。
  • 使用UTF-8 / UTC作为FIXED默认值,因为这仅仅是今天的默认值。 没有理由去做其他事情,除非你想产生这样的线程。

我的意思是,来吧,不是全局静态变量反OO模式? 没有其他的东西是由一些基本的环境变量给出的那些普遍的默认值.......




我很抱歉地说,但时间的不连续性已经有所改变了

两年前的JDK 6 ,以及最近的更新25中的JDK 7

吸取教训:不惜一切代价避免非UTC时间,除了可能用于显示。






Related