【问题标题】:Add milliseconds to Java date, when milliseconds is long当毫秒很长时,将毫秒添加到 Java 日期
【发布时间】:2010-08-10 21:28:26
【问题描述】:

当毫秒存储为“长”时,我正在寻找将毫秒添加到 Java 日期的最佳方法。 Java 日历有一个 add 函数,但它只需要一个 'int' 作为数量。

这是我提出的一种解决方案...

Calendar now = Calendar.getInstance();
Calendar timeout = Calendar.getInstance();

timeout.setTime(token.getCreatedOn());
timeout.setTimeInMillis(timeout.getTimeInMillis() + token.getExpiresIn());

还有其他建议吗?

【问题讨论】:

    标签: java datetime date


    【解决方案1】:

    java.time

    java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,改用modern Date-Time API*

    使用现代 API java.time 的演示:

    import java.time.Instant;
    
    public class Main {
        public static void main(String[] args) {
            Instant createdOn = Instant.ofEpochMilli(1_622_800_000_000L);
            System.out.println(createdOn);
    
            Instant timeout = createdOn.plusMillis(50_000L);
            System.out.println(timeout);
        }
    }
    

    看到这个code run live at IdeOne.com

    输出:

    2021-06-04T09:46:40Z
    2021-06-04T09:47:30Z
    

    Instant 表示UTC 中时间轴上的一个瞬时点。输出中的Z 是零时区偏移的timezone designator。它代表 Zulu 并指定 Etc/UTC 时区(时区偏移量为 +00:00 小时)。

    因此,您的问题的解决方案将是:

    Instant createdOn = token.getCreatedOn().toInstant();
    Instant timeout = createdOn.plusMillis(token.getExpiresIn());
    

    查看Date#toInstant 的文档以了解更多信息。

    Trail: Date Time了解更多关于java.timemodern Date-Time API*


    * 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

    【讨论】:

    • 这是每个人都应该想要的答案。您可能想通过证明可以添加50_000L 甚至5_000_000_000L 来强调可以添加long 值的观点。
    【解决方案2】:

    您还可以使用当前本地日期加上您需要添加为过期时间的毫秒数来创建日期

    import java.util.Date;
    
    long expiremilis = 60000l; //  1 minute
    // Expires in one minute from now
    Date expireDate = new Date(System.currentTimeMillis() + expiremilis);
    

    或与日历相同

    long expiremilis = 60000l; // 1 minute
    Calendar expireDate= Calendar.getInstance();
    // Expires on one minute from now
    expireDate.setTimeInMillis(System.currentTimeMillis() + expiremilis);
    

    如果您使用现有的 Date 对象,您可以这样做:

    import java.util.Date;
    
    long expiremilis = 60000l; // 1 minute
    // Expires on one minute from the date object date
    Date expireDate = new Date(myDate.getTime() + expiremilis);
    

    并且使用现有的日历对象

    long expiremilis = 60000l; // 1 minute
    Calendar expireDate= Calendar.getInstance();
    // Expires on one minute from the calendar date
    expireDate.setTimeInMillis(myCalendar.getTimeInMillis() + expiremilis);
    

    【讨论】:

      【解决方案3】:

      实际上,您的解决方案在我看来几乎很好。我最初通过Date 发布了一个答案,当时我没有正确考虑getTimeInMillissetTimeInMillis

      但是,您调用 setTime然后 setTimeInMillis 对我来说似乎有些多余。您的代码看起来与此等效:

      Calendar timeout = Calendar.getInstance();
      timeout.setTimeInMillis(token.getCreatedOn().getTime() + token.getExpiresIn());
      

      一般来说更好的选择是使用Joda Time :) 它通常是一个更好的日期/时间 API。

      【讨论】:

      • 我在某些实现中使用了 calendar.getInstance() 但不得不放弃它,因为如果 Date 带有 TimeZones,日历会破坏它。
      • @will824:我完全不明白你的评论 - Date 从不 有与之关联的时区。它总是距离 Unix 纪元只有几毫秒。
      • @Jon 实际上应该如您所说,但如果您检查 Date 对象,它总是带有某种时区。似乎 Java 在日期操作方面存在很多问题(这就是 Joda 诞生的原因),这就是其中之一。这正是我不能使用日历来解决我的问题而是不得不解决 Joda Millis 操作的原因。当然,我的问题非常具体,并且与从 1970 年 1 月 1 日过去应该为 0 的总秒数有关,但由于时区,我收到了一个负数。在我的情况下,使用日历会减少 1 小时 :(
      • @will824:不,java.util.Date 中没有时区。它真的没有 - 是什么让你认为它有?
      • @JonSkeet 我知道理论上它没有,但是如果你调试一个日期,它将有 2 个属性,其中一个将具有与时区相关的值。尝试用 1/1/1970 00:00:00 日期询问在基于 GMT 的服务器中创建的日期它有多少毫秒,令人惊讶的是它会返回一个负数。也许不是 Date 对象本身,而是它的实例化。
      【解决方案4】:

      Calendar 是一个相当昂贵的 Date 对象,它的功能并不是最好的。如果您想要一个通用的 Date 对象,我建议您查看JODA Time,它有一个功能可以满足您的需求。

      然而,一个更简单的 Java Date 对象是 @Dubas 指出的 Date 类。

      对于您正在执行的操作类型,更简单的是使用 long。这也快得多。

      long timeoutMS = token.getCreatedOn() + token.getExpiresIn(); 
      

      我对所有日期都使用 long(格林威治标准时间),并且仅将 Date 用于表示层。 IE。当您想将日期转换为文本时。

      【讨论】:

        猜你喜欢
        • 2014-10-12
        • 1970-01-01
        • 2023-01-19
        • 1970-01-01
        • 1970-01-01
        • 2014-05-24
        • 2012-04-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多