[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



恕我直言,Java中普遍的, 隱含的本地化是其最大的單一設計缺陷。 它可能是面向用戶界面的,但坦率地說,現在誰真的在用戶界面上使用Java,除了一些IDE基本上可以忽略本地化,因為程序員並不完全是它的目標受眾。 你可以通過以下方式修復它(尤其是在Linux服務器上):

  • 導出LC_ALL = C TZ = UTC
  • 將系統時鐘設置為UTC
  • 除非絕對必要,否則不要使用本地化實現(即僅用於顯示)

對於我推薦的Java社區過程成員:

  • 使本地化的方法不是默認的,但要求用戶明確要求本地化。
  • 使用UTF-8 / UTC作為FIXED默認值,因為這僅僅是今天的默認值。 沒有理由去做其他事情,除非你想產生這樣的線程。

我的意思是,來吧,不是全局靜態變量反OO模式? 沒有其他的東西是由一些基本的環境變量給出的那些普遍的默認值.......




我很抱歉地說,但時間的不連續性已經有所改變了

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

吸取教訓:不惜一切代價避免非UTC時間,除了可能用於顯示。




增加時間時,應該將其轉換回UTC,然後進行加或減。 僅使用本地時間進行顯示。

通過這種方式,您將能夠遍歷數小時或分鐘發生兩次的任何時段。

如果您轉換為UTC,請每秒添加一次,然後轉換為本地時間以供顯示。 您將經過11:54:08 pm LMT - 11:59:59 pm LMT ,然後11:54:08 pm CST - 11:59:59 pm CST。




Related