【问题标题】:How can I compare two different timestamps?如何比较两个不同的时间戳?
【发布时间】:2018-08-20 10:23:23
【问题描述】:

我编写了这段代码来比较两个时间值(以毫秒为单位)。 比较的是当前时间与数据库中定义的时间。

fun check_for_lecture(complete:(Boolean) -> Unit) : Int{

     for (x in UpdateScheduledLecturesService.lectures) {
         try {
             val start_time = x.start_time.toInt()
             val end_time = x.end_time.toInt()
             val timeRightnow = System.currentTimeMillis().toInt()

         // CompareTo returns a negative number if it's less than other, or a positive number if it's greater than other.
         //(also tried)if (timeRightnow == start_time || timeRightnow > start_time  && timeRightnow < end_time) {

             val compareWstarttime= timeRightnow.compareTo(start_time)
             val compareWendtime = timeRightnow.compareTo(end_time)
             if(compareWstarttime > 0 && compareWendtime < 0){
             count++
             lectureID = x.lectureID
             Log.d(TAG, "Test: lectureId assigned")
             complete(true)
             } else {
                 Log.d(TAG, "no lectures at this time")
                 complete(false)
             }
         } catch (e: ParseException) {
             Log.d(TAG, "Exception")
             e.printStackTrace()
             complete(false)
         }
     }

但是,它不起作用。我不确定我哪里出错了。

这是我打印它们时的示例:

当前时间:436239119,开始时间:1520845200,结束时间:1520848800。

【问题讨论】:

  • 将跟踪时间作为从 epoch 开始计数是笨拙的、容易出错的并且难以排除故障。而是使用 java.time 类。请参阅 Ole V.V. 的 the Answer。寻求更实用的方法。

标签: java android time kotlin datetime-comparison


【解决方案1】:

System.currentTimeMillis() 返回一个long 值,当转换为int 时,您将失去其精度。

示例:我现在运行了一个代码,System.currentTimeMillis() 返回了1520856967725。这超过了 1.5 万亿,太大而无法放入 intint 的最大值为 2147483647 - 大约 2.1 十亿)。

当您转换为 int 时,它只获取最后 32 位,而那个大值变为 438544942

10110001000011010001000111010101000101101 - 1520856967725
         00011010001000111010101000101101 - 438544942 (last 32 bits)

要使您的代码正常工作,请将您的开始时间和结束时间转换为 long,因为这是适合您要比​​较的值的正确类型。并且不要将currentTimeMillis 转换为int,因为它是long 值。

PS:另一个细节是currentTimeMillis返回自unix epoch以来的毫秒数。但有些 API 也适用于 。在比较之前,请确保您的开始时间和结束时间返回了哪些值(根据您的值,似乎开始和结束时间以秒为单位 - 如果是这样的话,您应该将currentTimeMillis 除以 1000,然后再将其转换为任何值。

【讨论】:

    【解决方案2】:

    您的问题是您的开始时间和结束时间是自纪元以来的,而System.currentTimeMillis()(顾名思义)给您毫秒时代。所以这些值不容易比较。

    平庸的解决方案是在比较之前将前两个相乘或第三个除以 1000。然而,这种对日期时间值的算术运算对于下一个试图阅读和理解代码的程序员来说并不是很友好。

    相反,我建议您使用库类来进行转换和比较。 Instant 来自 java.time,现代 Java 日期和时间 API,是您需要的。很抱歉我不会编写 Kotlin 代码,但我相信从 Java 翻译不会太难:

        long start_time = x.getStart_time();
        long end_time = x.getEnd_time();
        Instant timeRightnow = Instant.now();
        if (timeRightnow.isAfter(Instant.ofEpochSecond(start_time)) 
                && timeRightnow.isBefore(Instant.ofEpochSecond(end_time))) {
            // do something
        }
    

    如果您可以在数据库中使用 datetime 数据类型而不是存储自纪元以来的秒数,那就更好了。这将使查询到数据库的输出更具可读性,并且通常有助于调试。并消除您的问题。

    问题:我可以在 Android 上使用 java.time 吗?

    是的,您可以在 Android 上使用 java.time。它只需要至少 Java 6

    • 在 Java 8 及更高版本以及更新的 Android 设备上,内置了现代 API。
    • 在 Java 6 和 7 中,获取 ThreeTen Backport,即新类的后向端口(对于 JSR 310,ThreeTen;请参阅底部的链接)。
    • 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从 org.threeten.bp 导入日期和时间类以及子包。

    链接

    【讨论】:

      【解决方案3】:

      您可以使用下面的 joda apis.Example

      import org.joda.time.DateTime;
      
      public class CompareDateTimes {
      
        public static void main(String[] args) {
      
          // dt1 and dt2 have the same date and time
          DateTime dt1 = new DateTime();
          DateTime dt2 = new DateTime(dt1);
      
          // dt3 is one day later
          DateTime dt3 = new DateTime(dt2.plusDays(1));
      
          System.out.println("dt1.equals(dt2): " + dt1.equals(dt2));
          System.out.println("dt1.equals(dt3): " + dt1.equals(dt3));
      
          System.out.println("dt1.isAfter(dt3): " + dt1.isAfter(dt3));
          System.out.println("dt1.isBefore(dt3): " + dt1.isBefore(dt3));
        }
      }
      

      【讨论】:

      • 我无法将毫秒传递给 DateTime 参数,它会抛出此错误:“1520845200”在“0”处格式错误。
      • 仅供参考... Joda-Time 项目现在处于维护模式,其作者建议迁移到 java.time 类。对于早期的 Android,请参阅 ThreeTen-BackportThreeTenABP 项目。
      猜你喜欢
      • 2021-04-25
      • 1970-01-01
      • 2012-02-04
      • 2016-08-06
      • 2015-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-13
      相关资源
      最近更新 更多