如何在Java中将公历转换为Unix时间?

15

我需要一种将GregorianCalendar对象转换为Unix时间(即long类型)的方法,同时还需要一种将Unix时间(long类型)转换回GregorianCalendar对象的方法。是否有现成的方法可以实现这个功能?如果没有,那么我该如何做呢?非常感谢您提供任何帮助。

GregorianCalendar类链接 --> http://download.oracle.com/javase/1.4.2/docs/api/java/util/GregorianCalendar.html

谢谢。

5个回答

31

getTimeInMillis()setTimeInMillis(long) 方法可以让您获取和设置时间(以毫秒为单位),该时间是 unix 时间乘以 1000。需要手动调整,因为 Unix 时间仅包含秒,不包括毫秒。

long unixTime = gregCal.getTimeInMillis() / 1000;
gregCal.setTimeInMillis(unixTime * 1000);

顺便说一句:如果您在应用程序中经常使用日期,特别是如果要转换日期或使用多个时区,则强烈建议使用 JodaTime 库。它非常完整且比 Java 自带的日历系统更易于理解。


Unix C编程中的time方法返回整数秒数。它一直如此。还有另一个方法utime,它使用一个具有两个long型成员变量的结构体:一个用于秒数,另一个用于微秒数。 - Erick Robertson
谢谢。setTimeInMillis 是我最后会寻找的东西。因为在 Java 1.0 中,他们有一个伟大的想法:不可变实例(String、Date、Integer、Long 等等),我不会期望在 1.1 中他们放弃了 Java 设计师曾经拥有的最好的想法。 - Martin

1

1

0

简而言之

myGregCal.toZonedDateTime().toEpochSecond()                     // Convert from troublesome legacy `GregorianCalendar` to modern `ZonedDateTime`.

而往另一个方向走...

GregorianCalendar.from(                                         // Convert from modern `ZonedDateTime` to troublesome legacy class `GregorianCalendar`.
    Instant.ofEpochSecond( yourCountOfWholeSecondsSinceEpoch )  // Moment in UTC.
        .atZone(                                                // Apply `ZoneId` to `Instant` to produce a `ZonedDateTime` object.
            ZoneId.of( "Africa/Tunis" ) 
        )
)                                                              

避免使用旧的日期时间类

其他答案都是正确而简短的。但是,值得注意的是,那些令人头疼的旧日期时间类,例如java.util.Datejava.util.Calendarjava.text.SimpleDateFormat现在已经成为遗留问题,被Java 8和Java 9内置的java.time类所取代。

因此,以下是如何转换并使用现代类来解决您的问题。

java.time

将传统类GregorianCalendar转换为现代类ZonedDateTime。调用添加到旧类的新方法。

ZonedDateTime zdt = myGregCal.toZonedDateTime() ;

而往另一个方向走...

GregorianCalendar myGregCal = GregorianCalendar.from( zdt ) ;

如果你所说的“Unix时间”是指自1970年1月1日UTC的第一个时刻,即1970-01-01T00:00:00Z以来的整秒数计数,请调用toEpochSecond。若需要了解更多信息,请参考{{link1:“Unix时间”}}和{{link2:纪元参考}}。
long secondsSinceEpoch = zdt.toEpochSecond() ;

如果您想要一个自1970年以来以UTC为基准的毫秒计数,请提取一个InstantInstant类表示时间线上的一个时刻,使用UTC作为参考,并具有纳秒的分辨率(最多九位小数)。

Instant instant = zdt.toInstant() ;

现在询问毫秒数的计数
long millisecondsSinceEpoch = instant.toEpochMill() ;

请记住,要求整秒或毫秒可能会涉及数据损失。 ZonedDateTimeInstant都解析为纳秒。 因此,在计算整秒或毫秒时,任何可能存在的微秒或纳秒都将被忽略。

关于 java.time

java.time 框架内置于 Java 8 及更高版本。这些类取代了老旧的 遗留 日期时间类,如 java.util.DateCalendarSimpleDateFormat

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

要了解更多信息,请参阅 Oracle 教程。并在 Stack Overflow 上搜索许多示例和说明。规范是 JSR 310

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

如何获取 java.time 类?

ThreeTen-Extra 项目通过添加额外的类扩展了 java.time。该项目是 java.time 可能未来增加内容的试验场。您可能会在这里找到一些有用的类,例如 IntervalYearWeekYearQuarter更多


0

你应该寻找的是 Calendar.getTimeInMillis()。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接