【问题标题】:What is the best way to operate with time in kotlin?在 kotlin 中随时间操作的最佳方式是什么?
【发布时间】:2020-01-21 17:06:50
【问题描述】:

我正在使用 Kotlin 开发 Android 应用,我希望实现以下目标:

  1. 让用户选择从当前时间到下一个 24 小时的警报时间 (hh:mm) 例如16:00 用户想在明天 15:00 发出警报。
  2. 一旦用户设置了警报,我想显示警报激活前的剩余时间 (hh:mm) 例如显示一个带有文本的小对话框:还剩 3 小时:15 分钟。

在 Kotlin 中处理时间操作(将当前时间减去警报时间)的最佳方法是什么?

【问题讨论】:

  • 看起来是这样的,是的。但我一直在寻找(也许我的问题不清楚)以最 kotlin 惯用的方式处理这种情况的最佳方法(并知道是否已经存在处理它的方法,以及它是否未被弃用,如Date 来自 Java.util 是)。我在这里问之前读过你对那个问题的回答,但它没有回答我的问题。非常感谢您的回答:)

标签: java android kotlin


【解决方案1】:

您的所有问题都已在 Stack Overflow 上被多次询问和回答。所以我会简短。搜索以了解更多信息。

只使用 java.time 类,不要使用糟糕的遗留类,例如 DateCalendar

对于 26 之前的 Android,请参阅 ThreeTen-Backport 库及其 Android 特定的包装器 ThreeTenABP

LocalTime 表示一天中的某个时间。

LocalTime targetLocalTime = LocalTime.of( 15 , 0 ) ;

获取当前时刻。需要时区。像 CST 这样的 2-4 个字母代码不是实时时区。真实区域命名为Continent/Region

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;

比较时间部分。提取LocalTime 进行比较。

Boolean runToday = now.toLocalTime().isBefore( targetLocalTime ) ;

确定下一个闹钟时间。

ZonedDateTime zdt = now.with( targetLocalTime ) ; 

或者如果第二天需要,明天。

ZonedDateTime zdt = now.toLocalDate().plusDays( 1 ).atStartOfDay( z ).with( targetLocalTime ) ;

计算经过的时间。通过提取 Instant 来调整到 UTC。

Duration d = Duration.between( now.toInstant() , zdt.toInstant() ) ;

以标准 ISO 8601 格式生成字符串。

String output = d.toString() ;

或者通过调用Duration::to…Part 方法生成另一种格式的字符串。

至于触发警报,在纯 Java 中使用 Executors 框架,特别是 ScheduledExecutorService。这个框架使得运行在某个时刻触发任务Runnable 的后台线程变得简单。嗯,几乎可以肯定——CPU 上的垃圾收集或线程/进程调度可能会出现轻微的延迟,但对于商业应用程序来说已经足够好了(对于 NASA 来说还不够好)。

Android 还可能提供一些闹钟设置功能。 (不知道)

永远不要从后台线程访问或操作您的用户界面。使用 Android 提供的任何钩子从另一个线程更新 UI,例如刷新 UI 小部件或呈现通知。

【讨论】:

  • 您的第一段不应成为答案的一部分。这更像是对问题的评论。
【解决方案2】:

根据 Basil Bourque 的说法,以下是他提出的(用 Java 语言)转换为 Kotlin 的代码,以防万一有人感兴趣。


// Credit to Basil Bourque Answer
// https://stackoverflow.com/questions/59846004/what-is-the-best-way-to-operate-with-time-in-kotlin/59846550#59846550

lateinit var zdt: ZonedDateTime
val targetLocaltime = LocalTime.of(21, 0)
val z = ZoneId.of("Europe/Madrid")
val now = ZonedDateTime.now(z)
val runToday = now.toLocalTime().isBefore(targetLocaltime)

zdt = if (runToday){
    now.with(targetLocaltime)
}
else{
    now.toLocalDate().plusDays(1).atStartOfDay(z).with(targetLocaltime)
}
val eta = Duration.between(now.toInstant(), zdt.toInstant()).toMinutes()
if(eta > 60){
    val hours = eta / 60
    val minutes = eta % 60
    print("$hours:$minutes remaining")
}
else{
    print("$eta minutes remaining")
}

【讨论】:

    猜你喜欢
    • 2012-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 2010-11-18
    • 2021-11-17
    • 1970-01-01
    相关资源
    最近更新 更多