在 Java 中将 Long 转换为 Date 返回1970

我从 Web 服务下载了一个长值列表(例如: 1220227200,1220832000,1221436800...)。我必须把它转换成日期。不幸的是,这种方式,例如:

Date d = new Date(1220227200);

返回1970年1月1日,有人知道其他正确的转换方法吗?

412226 次浏览

Date构造函数(点击链接!)接受时间作为 毫秒中的 long,而不是秒。您需要将它乘以1000,并确保将其作为 long提供。

Date d = new Date(1220227200L * 1000);

这里显示

2008年8月31日星期日格林尼治标准时间20:00-04:00

看起来你的长度是秒,而不是毫秒。日期构造函数以毫秒为单位,所以

Date d = new Date(timeInSeconds * 1000);

这些可能是 几秒钟中的时间戳,而不是 java 新的 Date (long)构造函数所需的 毫秒中的时间戳。只要把它们乘以1000就行了。

New Date (number)返回的日期是1970年1月1日之后的 number毫秒。很可能你的日期格式没有显示小时、分钟和秒,你看到的只是1970年1月1日之后的一点点。

您需要根据正确的解析路由来解析日期。我不知道1220227200是什么,但是如果它是1970年1月1日之后的秒,那么将它乘以产生毫秒。如果不是,那么在1970年之后以某种方式将其转换为毫秒(如果您想继续使用 java.util 的话)。日期)。

我没问题。你可能想用1000乘以1000,因为你得到的是1970年的秒,你必须传递1970年1月1日的毫秒

1220227200对应于1980年1月15日(确实是新的日期(1220227200)。ToString ()返回“ Thu Jan 1503:57:07 CET 1970”)。如果向一个日期传递一个长值,即在01/01/1970之前,那么它实际上将返回一个日期01/01/1970。确保您的值不在这种情况下(小于82800000)。

试试这个:

Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(1220227200 * 1000);
System.out.println(cal.getTime());

较长的值很可能对应于 时代时间戳,这些值是:

1220227200 = Mon,01 Sep 200800:00:00 GMT

1220832000 = Mon,08 Sep 200800:00:00 GMT

1221436800 = Mon,15 Sep 200800:00:00 GMT

考虑到 java.util 这一事实,可以将这些长值转换为 Java.util 日期。Date 使用毫秒——正如前面提到的,但有一些缺陷——比如:

// note: enforcing long literals (L), without it the values would just be wrong.
Date date = new Date(1220227200L * 1000L);

现在,为了正确显示日期,可以使用 java.text. DateFormat,如下所示:

DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("Wrong date time value: " + date);
System.out.println("Correct date time value: " + df.format(date));

下面是将转换后的长值显示为 java.util.Date 而不显示的结果 使用日期格式:

Date wrong (off by 2 hours): Mon Sep 01 02:00:00 CEST 2008
Correct date : Monday, 1 September 2008 00:00:00 o'clock UTC

只在 Calendar 对象上设置 Mills 中的时间

Calendar c = Calendar.getInstance();
c.setTimeInMillis(1385355600000l);
System.out.println(c.get(Calendar.YEAR));
System.out.println(c.get(Calendar.MONTH));
System.out.println(c.get(Calendar.DAY_OF_MONTH));
// get Date
System.out.println(c.getTime());

博士

java.time.Instant                    // Represent a moment as seen in UTC. Internally, a count of nanoseconds since 1970-01-01T00:00Z.
.ofEpochSecond( 1_220_227_200L )     // Pass a count of whole seconds since the same epoch reference of 1970-01-01T00:00Z.

认识你的资料

人们使用不同的精度跟踪时间作为一个数字,因为一个 新纪元。因此,当您获得一些数字,并将其解释为一个纪元以来的计数时,您必须确定:

  • 什么时代?许多纪元的日期已在各种系统中得到应用。通常使用的是 POSIX/Unix 时间,其中的纪元是1970年 UTC 的第一个时刻。但是你不应该 假设这个时代。
  • 什么样的精度? 从那个时代以来,我们说的是秒、 毫秒微秒还是 纳秒
  • 什么时区?通常一个计数是在 协调世界时/GMT 时区,也就是说,没有任何时区偏移。但有时,当涉及到没有经验或在日期时间上无知的程序员时,可能会有一个隐含的时区。

在您的例子中,正如其他人指出的那样,似乎从 Unix 时代以来,您已经获得了几秒钟的时间。但是您将这些秒传递给一个预期毫秒的构造函数。所以解决方案是乘以1000。

经验教训:

  • 确定,不要假设,接收数据的意义。
  • 阅读 医生

Graph showing various granularities of resolution in date-time systems including whole seconds, milliseconds, microseconds, and nanoseconds.

你的资料

你的数据好像只有几秒钟。如果我们假设一个时代是1970年初,如果我们假设协调世界时的时区,那么 1,220,227,200就是2008年9月第一天的第一个时刻。

Joda 时间

Java.util.日期及。与 Java 绑定的日历类是出了名的麻烦。避开他们。改用 Java8中捆绑的 Joda 时间库或新的 Java.time 软件包(受 Joda-Time 的启发)。

请注意,与 j.u.Date 不同,Joda-Time 的 DateTime确实知道自己分配的 时区。因此,在下面的示例 Joda-Time 2.4代码中,请注意我们首先使用默认的 UTC 假设来解析毫秒。然后,第二,我们分配一个巴黎的时区来调整。同样的宇宙年表但是不同的 挂钟时间。为了演示,我们再次调整为 UTC。显式地指定您想要的/期望的时区总是比依赖隐式默认时区要好(隐式默认时区通常是日期时间工作中出现问题的原因)。

我们需要几毫秒来构造一个日期时间。以秒为单位,乘以1000。注意,结果必须是64位的 long,因为我们会溢出32位的 int

long input = 1_220_227_200L;  // Note the "L" appended to long integer literals.
long milliseconds = ( input * 1_000L ); // Use a "long", not the usual "int". Note the appended "L".

将毫秒计数提供给构造函数。这个特定的构造函数假定计数是1970年 Unix 时代的。因此,根据需要调整施工后的时区。

使用 正确的时区名称,它是大陆和城市/地区的组合。不要使用3或4个字母代码,如 EST,因为它们既不是标准化的,也不是唯一的。

DateTime dateTimeParis = new DateTime( milliseconds ).withZone( DateTimeZone.forID( "Europe/Paris" ) );

为了演示,请再次调整时区。

DateTime dateTimeUtc = dateTimeParis.withZone( DateTimeZone.UTC );
DateTime dateTimeMontréal = dateTimeParis.withZone( DateTimeZone.forID( "America/Montreal" ) );

转到控制台。注意这个日期在蒙雷阿勒是如何不同的,因为新的一天在欧洲已经开始,但是在美国还没有。

System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeUTC: " + dateTimeUtc );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );

跑步的时候。

dateTimeParis: 2008-09-01T02:00:00.000+02:00
dateTimeUTC: 2008-09-01T00:00:00.000Z
dateTimeMontréal: 2008-08-31T20:00:00.000-04:00

爪哇时间

Joda-Time 的制造商已经要求我们尽快迁移到它的替代品 爪哇时间框架上。虽然 Joda-Time 继续得到积极的支持,但所有未来的开发都将在 ThreeTen-Ultra 项目中的 java.time 类及其扩展上完成。

Java-time 框架由 JSR 310定义并构建到 Java8及更高版本中。Time 类已经在 310-后端口项目中移植到 Java6 & 7,在 三个十分项目中移植到 Android。

协调世界时中,Instant是时间线上的一个瞬间,分辨率为纳秒。它的纪元是世界协调时1970年的第一个时刻。

Instant instant = Instant.ofEpochSecond( 1_220_227_200L );

应用 从协调世界时偏移 ZoneOffset得到 OffsetDateTime

更好的是,如果知道,应用一个时区 ZoneId得到一个 ZonedDateTime

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

Table of all date-time types in Java, both modern and legacy

尝试调整日期格式。

long longtime = 1212580300;
SimpleDateFormat dateFormat = new SimpleDateFormat("MMddyyHHmm");
Date date = (Date) dateFormat.parseObject(longtime + "");
System.out.println(date);

注: 检查为24小时或12小时周期。

因为1220227200毫秒 = 338,952小时。 Java.util.Date 具有构造函数 new Date (Long milliseconds)-分配一个 Date 对象,并初始化它以表示自标准基准时间“ the epoch”(即1970年1月1日,00:00:00 GMT)以来指定的毫秒数。 所以,在你的情况下,只要记住1秒 = 1000毫秒