2014-12-05 98 views
5

我錯過了什麼? Date()是自1970年1月1日午夜以來經過的毫秒數。如果午夜不是從凌晨0點開始?Java時間:從1970年1月1日凌晨1點開始?

參考文獻:

我的測試程序:

package be.test.package.time; 

import java.text.DateFormat; 
import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
import java.util.Locale; 

public class TimeWork { 

    public static void main(String[] args) {  

     List<Long> longs = new ArrayList<>(); 
     List<String> strings = new ArrayList<>(); 

     DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss.SSS"); 

     //Now 
     Date now = new Date(); 
     strings.add(formatter.format(now)); 

     //Test dates 
     strings.add("01-01-1970 00:00:00.000"); 
     strings.add("01-01-1970 01:00:00.000"); 
     strings.add("31-11-1969 00:00:00.000"); 
     strings.add("01-01-2014 00:00:00.000"); 

     //Test data 
     longs.add(-1L); 
     longs.add(0L); 
     longs.add(1L); 
     longs.add(7260000L); 
     longs.add(1417706084037L); 
     longs.add(-7260000L); 

     //Show the long value of the date 
     for (String string: strings) { 
      try { 
       Date date = formatter.parse(string); 
       System.out.println("Formated date : " + string + " = Long = " + date.getTime()); 
      } catch (ParseException e) { 
       e.printStackTrace(); 
      } 
     } 

     //Show the date behind the long 
     for (Long lo : longs) { 
      Date date = new Date(lo); 
      String string = formatter.format(date); 
      System.out.println("Formated date : " + string + " = Long = " + lo);   
     } 
    } 
} 

這是結果:

Formated date : 05-12-2014 08:54:59.318 = Long = 1417766099318 
Formated date : 01-01-1970 00:00:00.000 = Long = -3600000 
Formated date : 01-01-1970 01:00:00.000 = Long = 0 
Formated date : 31-11-1969 00:00:00.000 = Long = -2682000000 
Formated date : 01-01-2014 00:00:00.000 = Long = 1388530800000 
Formated date : 01-01-1970 12:59:59.999 = Long = -1 
Formated date : 01-01-1970 01:00:00.000 = Long = 0 
Formated date : 01-01-1970 01:00:00.001 = Long = 1 
Formated date : 01-01-1970 03:01:00.000 = Long = 7260000 
Formated date : 04-12-2014 04:14:44.037 = Long = 1417706084037 
Formated date : 31-12-1969 10:59:00.000 = Long = -7260000 

爲什麼:

Formated date : 01-01-1970 01:00:00.000 = Long = 0 

這是凌晨1點。我期待着凌晨0點。

+8

你是什麼時區的java.time? – 2014-12-05 08:00:22

+1

我的時區是CET - 布魯塞爾/比利時時間。 – 2014-12-05 08:01:47

+2

你領先於你自己的時代:-) – 2014-12-05 08:03:37

回答

8

1970年1月1日午夜UTC。您需要TimeZone

public static void main(String[] args) { 
    TimeZone tz = TimeZone.getTimeZone("UTC"); 
    Calendar cal = Calendar.getInstance(tz); 
    cal.setTimeInMillis(0); 
    DateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss.SSS"); 
    sdf.setTimeZone(tz); 
    System.out.println(sdf.format(cal.getTime())); 
} 

輸出是

01-01-1970 12:00:00.000 
+0

當我沒有在'Calendar'實例中設置TimeZone時,我得到了相同的結果。但這是否意味着'DateFormat'取決於時區? – GameDroids 2014-12-05 08:08:52

+0

@GameDroids請記住,自從1970年1月1日@ 12:00.000以來,「Calendar」是一個奇特的結構。是的,'DateFormat'包含'TimeZone',你可能需要知道什麼時候是什麼時候,你是什麼時候到了我下午3點。 – 2014-12-05 08:11:57

+1

感謝您的解釋!我檢查日曆字符串時,它被設置爲'HOUR_OF_DAY = 1',所以'DateFormat'必須已經將它轉換回'UTC'時間。 – GameDroids 2014-12-05 08:16:03

3

由長0所代表的時間是午夜1/1/1970 UTC。這恰好是凌晨1點,1/1/1970 CET。但是,由於您使用的是SimpleDateFormat其時區設置爲CET,

  • 1/1/1970凌晨1點是,當被格式化的日期顯示的時間;
  • 解析1/1/1970凌晨1點給你長0.1

如果你有一個SimpleDateFormat其時區設置爲UTC,所以行爲是完全不同的代表的時間。

如果您想使用除CET以外的時區,則可以使用DateFormatsetTimeZone方法。

1

另外兩個答案是正確的。

順便說一下,使用Joda-Time庫或java.time package(受Joda-Time啓發),這種日期時間工作更容易。這兩個庫都有具有明確分配時區的日期 - 時間類(與java.util.Date/.Calendar不同)。

Joda-Time和java.time都使用相同的epoch1970-01-01T00:00:00Z

在生成日期時間值的文本表示時,兩者都使用ISO 8601標準格式。

Joda-Time

在喬達時代2.7。

DateTime epoch = new DateTime(0 , DateTimeZone.UTC); 

java.time

在Java 8更新45

ZonedDateTime epoch = ZonedDateTime.ofInstant(Instant.EPOCH , ZoneOffset.UTC) ; 
相關問題