Java时间:从1970年1月1日凌晨1点开始?

时间:2014-12-05 07:57:43

标签: java date time

我错过了什么? Date()是自1970年1月1日午夜以来经过的毫秒数。午夜不应该从凌晨0点开始?

参考文献:

我的测试计划:

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点。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:3)

长0所代表的时间是UTC时间1/1/1970午夜。这恰好是1970年1月1日至19日的CET。但由于您使用的SimpleDateFormat时区设置为CET,

  • 1/1/1970 1am是格式化日期时显示的时间;
  • 解析1/1/1970 1am为您提供由长0表示的时间。

如果您的时区设置为UTC SimpleDateFormat,则行为将完全不同。

如果您想使用CET以外的时区,则可以使用setTimeZone DateFormat方法。

答案 2 :(得分: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 Update 45的java.time中。

ZonedDateTime epoch = ZonedDateTime.ofInstant( Instant.EPOCH , ZoneOffset.UTC ) ;