我正在尝试制作一个闹钟应用程序,但在设置闹钟响起的时间时遇到困难。我的应用程序让用户选择他们希望闹钟响起的日期,类似于 Android 闹钟,用一个 7 的 boolean 数组来表示。
我的想法是设置最近一天的时钟,即如果今天是星期一并且闹钟设置为星期三和星期五,则闹钟将在星期三响起,然后在星期五自行重置。
我想知道日历是否可以返回一周,我认为这会让事情变得更容易。
最佳答案
避免旧的日期时间类
避免使用麻烦的旧遗留日期时间类。而是使用 java.time 类。
DayOfWeek
枚举 & EnumMap
DayOfWeek
enum为一周中的 7 天(周一至周日)预定义了 7 个对象。
EnumSet
和 EnumMap
是 Set
和 Map
的非常快速且低内存的实现,用于处理枚举值的集合。在您的情况下,您可以定义一个包含所有 7 天的 EnumMap
,每个映射到 LocalTime
来表示警报何时应触发(或 null 表示当天没有警报)。
EnumMap< DayOfWeek , LocalTime > dowToTimeMap = new EnumMap< DayOfWeek , LocalTime >( DayOfWeek.class );
dowToTimeMap.put( DayOfWeek.MONDAY , LocalTime.of( 6 , 0 ) ); // 6 AM.
dowToTimeMap.put( DayOfWeek.TUESDAY , LocalTime.of( 6 , 0 ) );
…
dowToTimeMap.put( DayOfWeek.SATURDAY , LocalTime.of( 8 , 0 ) ); // Sleep in until 8 AM on Saturday.
dowToTimeMap.put( DayOfWeek.SUNDAY , LocalTime.of( 7 , 0 ) );
要获取当前日期,请指定时区 ( ZoneId
)。 LocalDate
类表示仅日期值,没有时间和时区。
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
向 map 询问今天星期几的闹钟时间。
LocalTime alarmTimeToday = dowToTimeMap.get( today.getDayOfWeek() );
您可能会找到ZonedDateTime
, Instant
,和 Duration
类可用于确定下一个警报之前的耗时。
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
LocalDate tomorrow = today.plusDays( 1 );
LocalTime alarmTimeTomorrow = dowToTimeMap.get( tomorrow.getDayOfWeek() );
ZonedDateTime nextAlarmZdt = ZonedDateTime.of( tomorrow , alarmTimeTomorrow , z );
Instant now = Instant.now();
Duration duration = Duration.between( now , nextAlarmZdt.toInstant() );
检查持续时间是否为负数,即时间倒退。这意味着下一个闹钟时间要么早于现在,要么非常接近,以至于在该代码运行时就到期了。
if( duration.isNegative() ) {
// Oops, the next alarm was within a second or so of current time, a shorter time than it took to execute this code.
… // Handle the problem.
}
您还可以验证今天和明天,因为如果此代码在午夜执行,情况可能会发生变化。
然后,您可以询问整秒、毫秒或纳秒的持续时间
,无论您的闹钟设置需要什么。
关于java.time
java.time框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧类 legacy日期时间类,例如 java.util.Date
, Calendar
, & SimpleDateFormat
.
Joda-Time项目,现在位于 maintenance mode ,建议迁移到java.time类。
要了解更多信息,请参阅 Oracle Tutorial 。并在 Stack Overflow 上搜索许多示例和解释。规范为JSR 310 .
您可以直接与数据库交换java.time对象。使用JDBC driver符合JDBC 4.2或稍后。不需要字符串,不需要 java.sql.*
类。
从哪里获取java.time类?
- Java SE 8 , Java SE 9 , Java SE 10 , 然后
- 内置。
- 是标准 Java API 的一部分,具有 bundle 实现。
- Java 9 添加了一些小功能和修复。
- Java SE 6和 Java SE 7
- 许多 java.time 功能已向后移植到 ThreeTen-Backport 中的 Java 6 和 7 .
- Android
- 更高版本的 Android bundle 了 java.time 类的实现。
- 对于早期的 Android (<26),ThreeTenABP项目采用ThreeTen-Backport(如上所述)。请参阅How to use ThreeTenABP… .
ThreeTen-Extra项目通过附加类扩展了 java.time。该项目是 java.time future 可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如 Interval
, YearWeek
, YearQuarter
,和 more .
关于java - 计算闹钟的闹钟时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36493703/