Java:Unix时间戳记中的日期


237

我需要将unix时间戳转换为日期对象。
我尝试了这个:

java.util.Date time = new java.util.Date(timeStamp);

时间戳值为: 1280512800

日期应该是“ 2010/07/30-22:30:00”(因为我是通过PHP获得的),但我却得到了Thu Jan 15 23:11:56 IRST 1970

应该怎么做?


3
如果您使用Java 8或更高版本:请查看以下答案:stackoverflow.com/a/24703644/1115554
micha

1
仅供参考,麻烦的旧日期时间类(例如java.util.Date现在已遗留)已由java.time类取代。请参见Oracle教程
罗勒·布尔克

Answers:


429

对于1280512800,请乘以1000,因为java期望的是毫秒:

java.util.Date time=new java.util.Date((long)timeStamp*1000);

如果您已经有毫秒,那么 new java.util.Date((long)timeStamp);

文档中

分配一个Date对象,并将其初始化为表示自标准基准时间(即“纪元”)以来的指定毫秒数,即格林尼治标准时间1970年1月1日。


40
强制转换(long)为非常重要:没有它,整数就会溢出。
mneri 2014年

2
@TomasK java.util.Date是该类的完全限定名称。如果您在类中导入包,Date则可能完全相同java.util
巴勃罗·圣克鲁斯

5
不需要强制转换为long。time = new java.util.Date(timeStamp * 1000L)也可以正常工作(因为1000L很长,因此时间戳会在乘法运算之前转换为很长的时间)
Tony BenBrahim

2
我个人将这样做:Date time = new Date(TimeUnit.MILLISECONDS.convert(unixTimestamp, TimeUnit.SECONDS));
Ryan Amaral

3
仅供参考,麻烦的旧日期时间类(例如java.util.Date现在已遗留)已由java.time类取代。请参见Oracle教程
罗勒·布尔克

59

java.time

Java 8引入了一个用于处理日期和时间的新API:java.time包

使用java.time,您可以分析自1970年1月的1970年第一时刻的纪元参考以来的整秒计数,时间为1970-01-01T00:00Z。结果是Instant

Instant instant = Instant.ofEpochSecond( timeStamp );

如果您需要java.util.Date与尚未为java.time更新的旧代码进行互操作,请转换。调用添加到旧类中的新转换方法。

Date date = Date.from( instant );

3
尽管此“答案”在技术上是正确的,但请注意,java.time类取代了麻烦的旧日期时间类,例如java.util.Date。旧类是遗留的,应避免使用。尽管您确实可以与旧类和java.time类进行相互转换,但最好尽可能使用java.time。
罗勒·布尔克


27

日历似乎是一种新的处理方式:

Calendar mydate = Calendar.getInstance();
mydate.setTimeInMillis(timestamp*1000);
out.println(mydate.get(Calendar.DAY_OF_MONTH)+"."+mydate.get(Calendar.MONTH)+"."+mydate.get(Calendar.YEAR));

最后一行只是如何使用它的示例,该行将显示例如“ 14.06.2012”。

如果使用System.currentTimeMillis()保存时间戳,则不需要“ * 1000”部分。

如果字符串中包含时间戳,则需要首先将其解析为long:Long.parseLong(timestamp)。

https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html


8
警告:如果timestamp是整数,则需要将其(long)首先转换为整数,否则将以错误的日期结尾。mydate.setTimeInMillis((long) timestamp*1000);
svenkapudija,2012年

我已经修复了链接。
Ricbit 2015年

仅供参考,麻烦的旧日期,时间类,如java.util.Datejava.util.Calendarjava.text.SimpleDateFormat现在的遗产,由取代java.time内置到Java 8和更高等级。请参见Oracle 教程
罗勒·布尔克

26

tl; dr

Instant.ofEpochSecond( 1_280_512_800L )

2010-07-30T18:00:00Z

java.time

Java 8及更高版本中内置的新java.time框架是Joda-Time的后继者。

这些新类包括一个方便的工厂方法,用于从历元转换整秒的计数。您Instant在UTC的时间轴上获得的时间高达纳秒级。

Instant instant = Instant.ofEpochSecond( 1_280_512_800L );

Instant.toString():2010-07-30T18:00:00Z

看到该代码在IdeOne.com上实时运行

Java中的日期时间类型表(现代和旧式)

Asia/Kabul还是Asia/Tehran时区?

您报告的时间值是22:30,而不是此处看到的18:00。我怀疑您的PHP实用工具暗中应用了默认时区以从UTC进行调整。我在这里的值是UTC,由ZZulu,表示UTC的缩写)表示。您的机器OS或PHP是否被设置为Asia/KabulAsia/Tehran时区?我想,当您IRST在输出中报告时,这显然意味着伊朗时间。目前,在2017年,这些区域是唯一夏季时间比UTC提前四个半小时的区域。

指定适当的时区名称,格式continent/region,如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用3-4字母缩写,例如ESTIST或,IRST因为它们不是真实的时区,不是标准化的,甚至不是唯一的(!)。

如果您通过特定区域的时区的镜头来查看自己的时刻,请应用ZoneId来获取ZonedDateTime。同步时刻仍然相同,但是挂钟时间却有所不同。

ZoneId z = ZoneId.of( "Asia/Tehran" ) ;
ZonedDateTime zdt = instant.atZone( z );  // Same moment, same point on timeline, but seen as different wall-clock time.

2010-07-30T22:30 + 04:30 [亚洲/德黑兰]

从java.time转换为旧类

您应该坚持使用新的java.time类。但是,如果需要,您可以转换为旧版本。

java.util.Date date = java.util.Date.from( instant );

乔达时代

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

仅供参考,Joda-Time DateTime的构造函数类似:乘以一千即可生成一个long(而不是int!)。

DateTime dateTime = new DateTime( ( 1_280_512_800L * 1000_L ), DateTimeZone.forID( "Europe/Paris" ) );

最好避免臭名昭著的java.util.Date和.Calendar类。但是,如果必须使用日期,则可以从Joda-Time转换。

java.util.Date date = dateTime.toDate();

关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar,和SimpleDateFormat

现在处于维护模式Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*

在哪里获取java.time类?

  • Java SE 8 Java SE 9和更高版本
    • 内置的
    • 标准Java API的一部分,具有捆绑的实现。
    • Java 9添加了一些次要功能和修复。
  • Java SE 6 Java SE 7
    • java.time的许多功能在ThreeTen- Backport中都被反向移植到Java 6和7 。
  • 安卓
    • 更高版本的Android捆绑了java.time类的实现。
    • 对于早期的Android(<26),ThreeTenABP项目改编了ThreeTen-Backport(如上所述)。请参阅如何使用ThreeTenABP…

ThreeTen-额外项目与其他类扩展java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多


11

Date的构造函数期望timeStamp值以毫秒为单位。将时间戳记的值乘以1000,然后传递给构造函数。


7

如果要在另一台计算机上转换时间戳记值,则还应该检查该计算机的时区。例如;

如果使用EST或UTC时区,则上述说明将产生不同的Date值。

设置时区;又称UTC,您只需重写即可;

    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    java.util.Date time= new java.util.Date((Long.parseLong(timestamp)*1000));

6
我不建议这样做,因为这为整个jvm设置了时区,而不仅仅是解析过程!

1

对于科特林

fun unixToDate(timeStamp: Long) : String? {
    val time = java.util.Date(timeStamp as Long * 1000)
    val sdf = SimpleDateFormat("yyyy-MM-dd")
    return sdf.format(time)

}

0

有时您需要进行调整。

不要长时间使用演员表!使用纳米调整。

例如,使用Oanda Java API进行交易,您可以获得UNIX格式的日期时间。

例如:1592523410.590566943

    System.out.println("instant with nano = " + Instant.ofEpochSecond(1592523410, 590566943));
    System.out.println("instant = " + Instant.ofEpochSecond(1592523410));

你得到:

instant with nano = 2020-06-18T23:36:50.590566943Z
instant = 2020-06-18T23:36:50Z

另外,请使用:

 Date date = Date.from( Instant.ofEpochSecond(1592523410, 590566943) );

-4
Date d = new Date(i * 1000 + TimeZone.getDefault().getRawOffset());

3
没有更多的文字说明,为什么这个问题比其他问题更可取,目前尚不清楚。你能澄清一下吗?
Duncan Jones

这将修改日期,而不是转换日期!
反斜杠
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.