【问题标题】:Java Built In Date Manipulation and ComparisonJava 内置日期操作和比较
【发布时间】:2014-05-28 14:52:48
【问题描述】:

我希望创建一个日期时间戳,然后添加 10 小时,然后进行线程检查以查看时间是否已过。

我通读了Time comparison,但对于如此简单的事情来说似乎有点复杂/令人费解。尤其是当您的时间比较跨越午夜时。

我的理解是java的底层日期时间,假设是一个long,如果这是真的,有没有一种简单的方法可以添加另一个long,比如相当于10小时的数字?还是其他一些方法,例如添加两个日期?

注意:解决方案需要是核心 java 的一部分,不能是 3rd 方库的一部分。

【问题讨论】:

  • 不是更好地安排线程在给定时间运行,而不是让它轮询时间条件变为真吗? (java.util.concurrent 中的ScheduledExecutorService)
  • @guido 我喜欢这个建议。我实际上计划进行民意调查,然后在不同的时间睡觉,这似乎是同一件事,只是你的似乎更合适。我计划这样做,因为代码最终将在 android 设备上运行,所以我不能保证程序会一直运行,所以这个简单可能会在启动或恢复时发生。我会更多地研究您的建议,因为我认为我可以在您的简历/启动时做同样的事情。谢谢。

标签: java date


【解决方案1】:

您可以使用Calendar 来执行该数学运算,

Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR, 10); // Add 10 hours.
Date date2 = cal.getTime(); // Now plus 10 hours.
Date date = new Date(); // Now.

【讨论】:

  • 如果这跨越夏令时更改会发生什么?日历如何处理?
  • @AaronDigulla 正确!只要时区数据正确。当法律发生变化时,Oracle 会更新。
  • 在这种情况下什么是正确的?如果 DST 开始,那么一天中的一小时就会消失(我们跳过 2:00 到 3:00 之间的一小时)。那么如果date 是午夜,那么date2 是11:00、10:00 还是9:00? datedate2 之间的实际秒数是多少?我的猜测是 OP 在 date2 中需要 11:00,但它实际上包含 10:00。
【解决方案2】:

您可以使用Date.getTime() 方法获取底层时间戳,时间戳基本上是自定义的基本时刻(1970-01-01 00:00:00 IIRC)以来经过的毫秒数。

System.currentTimeMillis() 让您可以直接获得“现在”的瞬间,而无需使用DateCalendar 等。

然后可以通过基本数学操作时间戳:

 timestamp += TimeUnit.MILLISECONDS.convert(10, TimeUnit.HOURS);

添加 10 小时的示例:

long nowInMilliSince1970 = System.currentTimeMillis();
long tenHoursAsMilli = TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES);
long tenHoursLater = nowInMilliSince1970 + tenHoursAsMilli;
System.out.println("now in milliseconds: \t\t" + nowInMilliSince1970);
System.out.println("10 hours in milliseconds: \t" + tenHoursAsMilli);
System.out.println("10 hours from now: \t\t" + tenHoursLater);

检查时间戳是否在过去很简单:

 if (timestamp < System.currentTimeMillis()) {
     System.out.println("timestamp is in the past");
 }

请注意,直接时间戳数学没有夏令时和时区的概念。如果您愿意,请使用 Calendar 进行数学运算 - Calendar 为此实施了肮脏的例外规则。

【讨论】:

  • +1 我实际上更喜欢这个解决方案,因为它不容易因时区、夏令时和日历的其他疯狂......功能而出错。
  • 谢谢亚伦。我基于其简单性接受了另一个答案,但在我接受答案后看到了您的其他担忧。我认为两者都很好,但正如您所说,这更好。
【解决方案3】:

仅使用 JDK 内置的东西来实现它的另一种方法是:

long tenHoursFromNow = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(10);

然后在您的线程中检查:

if(System.currentTimeMillis() > tenHoursFromNow)
{
        //Do something as the time has elapsed 
}

尽管我认为使用 Calendar 和 Date 可以更清楚地了解代码的意图。

【讨论】:

    【解决方案4】:

    捆绑的 java.util.Date 和 .Calendar 是出了名的麻烦。他们真的应该避免。

    您声明了不添加库的要求。因此,请参阅我的答案的 java.time 部分,使用新添加到 Java 8 的新包。但我敦促您重新考虑您不愿意添加库,特别是如果您还不能迁移到 Java 8 ; j.u.Date/Calendar 真的很糟糕。

    两个库都处理异常,例如夏令时。

    考虑指定时区而不是依赖 JVM 的默认值。一般最好在UTC工作,然后翻译成当地时区呈现给用户。

    java.time

    java.time package 新添加到Java 8。受Joda-Time 启发,但经过重新设计。由JSR 310 定义。由threeten-extra 项目扩展。

    ZonedDateTime tenHoursLater = ZonedDateTime.now().plusHours( 10 );
    

    乔达时间

    使用Joda-Time 2.3 库。

    DateTime tenHoursLater = DateTime.now().plusHours( 10 );
    

    有关这种 Joda-Time 使用的更多信息,请参阅my answer 以解决类似问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多