【问题标题】:Java: Date from unix timestampJava:来自unix时间戳的日期
【发布时间】:2011-03-23 05:29:30
【问题描述】:

我需要将 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

应该怎么做?

【问题讨论】:

标签: java unix timestamp


【解决方案1】:

对于1280512800,乘以 1000,因为 java 需要毫秒:

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

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

来自documentation

分配一个 Date 对象和 初始化它以表示 指定的毫秒数 标准基准时间称为“ 纪元”,即 1970 年 1 月 1 日, 格林威治标准时间 00:00:00。

【讨论】:

  • 转换为(long) 非常重要:没有它整数溢出。
  • @TomasK java.util.Date 是类的完全限定名。 Date 可能是完全相同的东西,前提是您在班级中导入了 java.util 包。
  • 不需要转换为 long。 time=new java.util.Date(timeStamp*1000L) 也可以正常工作(因为 1000L 很长,所以在乘法之前时间戳将向上转换为 long)
  • 我个人会这样做:Date time = new Date(TimeUnit.MILLISECONDS.convert(unixTimestamp, TimeUnit.SECONDS));
  • 仅供参考,诸如 java.util.Date 这样麻烦的旧日期时间类现在是 legacy,被 java.time 类所取代。见Tutorial by Oracle
【解决方案2】:

java.time

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

使用 java.time,您可以解析自 1970 年第一刻(UTC,1970-01-01T00:00Z)的纪元参考以来的整秒数。结果是Instant

Instant instant = Instant.ofEpochSecond( timeStamp );

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

Date date = Date.from( instant );

【讨论】:

  • 虽然此答案在技术上是正确的,但请注意 java.time 类取代了麻烦的旧日期时间类,例如 java.util.Date。旧课程是遗留的,应该避免。虽然您确实可以在 legacy 和 java.time 类之间进行转换,但最好尽可能坚持使用 java.time。
【解决方案3】:

这是正确的方法:

Date date = new Date ();
date.setTime((long)unix_time*1000);

【讨论】:

    【解决方案4】:

    tl;博士

    Instant.ofEpochSecond( 1_280_512_800L )
    

    2010-07-30T18:00:00Z

    java.time

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

    这些新类包括来自 epoch 的 handy factory method to convert a count of whole seconds。您会收到一个Instant,它是 UTC 时间线上的一个时刻,分辨率高达纳秒级。

    Instant instant = Instant.ofEpochSecond( 1_280_512_800L );
    

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

    看到code run live at IdeOne.com

    Asia/KabulAsia/Tehran 时区?

    您报告得到的时间值是 22:30,而不是此处看到的 18:00。我怀疑您的 PHP 实用程序隐式应用默认时区以从 UTC 进行调整。我这里的值是 UTC,由 Z 表示(Zulu 的缩写,表示 UTC)。您的机器操作系统或 PHP 是否有可能设置为 Asia/KabulAsia/Tehran 时区?我想当您在输出中报告IRST 时,这显然意味着伊朗时间。目前在 2017 年 those are the only zones 在夏令时运行,比 UTC 早四个半小时。

    continent/region 的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用 3-4 个字母的缩写,例如 ESTISTIRST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。

    如果您通过特定地区的时区镜头看到自己的时刻,请申请ZoneId 以获取ZonedDateTime。仍然是同一时刻,但被视为不同的wall-clock time

    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 项目现在位于maintenance mode,团队建议迁移到java.time 类。

    仅供参考,Joda-TimeDateTime 的构造函数类似:乘以一千得到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 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

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

    从哪里获得 java.time 类?

    • Java SE 8Java SE 9 及更高版本
      • 内置。
      • 标准 Java API 的一部分,带有捆绑实现。
      • Java 9 添加了一些小功能和修复。
    • Java SE 6Java SE 7
      • ThreeTen-Backport 中的大部分 java.time 功能都向后移植到 Java 6 和 7。
    • Android
      • 更高版本的 Android 捆绑包实现 java.time 类。
      • 对于早期的 Android (ThreeTenABP 项目采用 ThreeTen-Backport(如上所述)。见How to use ThreeTenABP…

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

      【解决方案5】:

      看起来日历是新的方式:

      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

      【讨论】:

      • 警告:如果timestamp 是一个整数,你需要先将它转换为(long),否则你会得到错误的日期。 mydate.setTimeInMillis((long) timestamp*1000);
      • 仅供参考,麻烦的旧日期时间类,如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 及更高版本中内置的 java.time 类所取代.见Tutorial by Oracle
      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

        如果您在不同的机器上转换时间戳值,您还应该检查该机器的时区。例如;

        如果您使用 EST 或 UTC 时区运行,上述说明将产生不同的日期值。

        设置时区;又名UTC, 你可以简单地重写;

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

        【讨论】:

        • 我不建议这样做,因为这会为整个 jvm 而不仅仅是解析过程设置时区!
        【解决方案8】:

        对于科特林

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

        【讨论】:

          【解决方案9】:

          有时您需要进行调整。

          不要使用cast to long!使用微调整。

          例如,使用 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) );
          

          【讨论】:

            【解决方案10】:
            Date d = new Date(i * 1000 + TimeZone.getDefault().getRawOffset());
            

            【讨论】:

            • 没有更多的文字,不清楚为什么这个答案比这个问题中的许多其他答案更可取。你能澄清一下吗?
            • 这将修改日期而不是转换它!
            猜你喜欢
            • 1970-01-01
            • 2013-04-26
            • 1970-01-01
            • 2014-05-22
            • 1970-01-01
            • 1970-01-01
            • 2010-10-02
            • 2011-10-01
            相关资源
            最近更新 更多