如果做一个新的日期(0L),时代不是时代。为什么?

时间:2010-03-12 17:27:47

标签: java date epoch

我的问题很简单:

如果我这样做:

public class Main {

public static void main(String[] args) throws Exception {
        Date d = new Date(0L );
        System.out.println(d);
}

}

我得到以下输出:Thu Jan 01 01:00:00 CET 1970

根据文件,我期待:Thu Jan 01 00:00:00 CET 1970

我想错了...

编辑: 实际上,我读得太快了。我应该在格林威治标准时间1970年1月1日00:00:00

那么,我如何强制使用GMT,并忽略所有当地时间?

编辑,解决方案:

public static void main(String[] args) throws Exception {
    SimpleDateFormat sdf = new SimpleDateFormat("H:m:s:S");
SimpleTimeZone tz = new SimpleTimeZone(0,"ID");
sdf.setTimeZone(tz) ;
Date d = new Date(0L );
System.out.println( sdf.format(d));
}

4 个答案:

答案 0 :(得分:6)

Epoch定义为1970-1-1 UTC的00:00:00。由于CET是UTC + 1,因此它等于你的时间凌晨1点。

如果查看Date(long)构造函数,您会发现它希望该值为自纪元以来的毫秒数UTC

  

分配Date对象和   初始化它来代表   指定的毫秒数   标准基准时间称为“   时代“,即1970年1月1日,   00:00:00 GMT。

关于强制GMT而不是当地时区的愿望:简而言之,Date实例总是使用GMT。如果您只想格式化输出String,以便它使用GMT,那么DateFormat类就是setTimeZone()类,具体来说就是{{3}}方法。

答案 1 :(得分:3)

这可能与您的区域设置有关。假设您是法语而不是法语 - 加拿大语,您的时间戳似乎被视为没有时区的时间戳,而Date构造函数会尝试对此进行更正,并在日期中添加一小时。

如果这是无证件的行为,我不能告诉你。

编辑:读取错误:CET!= UTC:/

所以是的,Locale时区。

Reedit:为了彻底和绝对清晰。

输出:Thu Jan 01 01:00:00 CET 1970

您的预期输出:Thu Jan 01 00:00:00 CET 1970

实际预期输出:Thu Jan 01 00:00:00 GMT 1970(≡ThuJan 01 01:00:00 CET 1970)

答案 2 :(得分:3)

TL:博士

Instant.EPOCH
       .toString()
  

1970-01-01T00:00:00Z

Date::toString谎言

您已经了解了避免使用java.util.Date/Calendar类的众多原因之一:Date实例没有时区信息,但它是{{1}在渲染字符串以供显示时,} method使用默认时区。令人困惑,因为它暗示Date有一个时区,实际上它没有。

避免使用toString / Date

而不是日期/日历,您应该使用Joda-Time或JSR 310中的新Java 8类java.time。*。

java.time

使用Instant类相当于Calendar,在UTC时间轴上的一个时刻。

Date

对于纪元参考日期,请使用常量。

Instant.now()
  

1970-01-01T00:00:00Z

如果通过"忽略所有时间"你的意思是你真的想要一个没有时间的仅限日期的值,使用Instant.EPOCH.toString() 类。

LocalDate
  

1970-01-01

Joda-Time示例

更新:Joda-Time项目现在处于维护模式,团队建议迁移到java.time类。

在Joda-Time中,DateTime实例确实知道自己的时区。如果需要,您可以使用格式化程序在其他时区创建字符串输出。

这里的代码针对Unix time Epoch,但使用的是Joda-Time 2.3。

LocalDate.ofEpochDay( 0L )

转储到控制台...

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

DateTimeZone timeZone_Paris = DateTimeZone.forID( "Europe/Paris" );

DateTime epochParis = new DateTime( 0L, timeZone_Paris );
DateTime epochUtc = new DateTime( 0L, DateTimeZone.UTC );

跑步时......

System.out.println( "epochParis: " + epochParis );
System.out.println( "epochUtc: " + epochUtc );

转换为UTC / GMT

  

那么,我如何强制使用GMT,并忽略所有当地时间?

要使用UTC / GMT(无时区偏移),请执行以下操作:

  • 将DateTime转换为具有不同时区的另一个实例
    (Joda-Time使线程安全不可变,因此我们实际上不进行转换,我们根据旧实例创建新实例。)
  • 使用格式化程序创建为指定时区显示的字符串。
epochParis: 1970-01-01T01:00:00.000+01:00
epochUtc: 1970-01-01T00:00:00.000Z

转储到控制台...

// To use UTC/GMT instead of local time zone, create new instance of DateTime.
DateTime nowInParis = new DateTime( timeZone_Paris );
DateTime nowInUtcGmt = nowInParis.toDateTime( DateTimeZone.UTC );

跑步时......

System.out.println( "nowInParis: " + nowInParis );
System.out.println( "nowInUtcGmt: " + nowInUtcGmt );

答案 3 :(得分:1)

CET比GMT提前一小时,这是用来定义大纪元的时区。