您的所有问题都已在 Stack Overflow 上被多次询问和回答。所以我会简短。搜索以了解更多信息。
只使用 java.time 类,不要使用糟糕的遗留类,例如 Date 和 Calendar。
对于 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 小部件或呈现通知。