-4

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

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。

4

3 回答 3

3

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

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

当您转换为 时int,它仅获得最后 32 位,并且该大值变为438544942

10110001000011010001000111010101000101101 - 1520856967725
         00011010001000111010101000101101 - 438544942 (last 32 bits)

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

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

于 2018-03-12T12:25:07.140 回答
1

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

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

相反,我建议您使用库类进行转换和比较。Instant来自现代 Java 日期和时间 API 的 java.time 是您需要的。很抱歉我不会编写 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 吗?

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

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

链接

于 2018-03-12T13:39:41.277 回答
0

您可以使用 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));
  }
}
于 2018-03-12T11:56:26.470 回答