计算接下来30天的交替日期的TimeInMillis值会在Kotlin中给出错误的日期



我想获得从任何选定日期开始的未来30天的备用日期的TimeInMillis值。我试着用for循环来获取日期的值。但代码总是将最后3个日期返回为错误。有没有其他更好的方法来实现我正在做的事情?

fun calculateDates(startDate: Long) {
val singeDateDifference = 86400000
val cancelledDates = arrayListOf<Long>()
for (i in 2..30 step 2) {
val difference = i * singeDateDifference
cancelledDates.add(startDate + difference)
}
}

我得到的答案是这样的。为了更好地理解,我已经将Long值记录为日期。

startDate: 01/01/2022
[02/01/2022, 04/01/2022, 06/01/2022, 08/01/2022, 10/01/2022, 12/01/2022, 14/01/2022, 16/01/2022, 18/01/2022, 20/01/2022, 22/01/2022, 24/01/2022, 07/12/2021, 09/12/2021, 11/12/2021]

我总是收到上个月的最后3次约会。我搞不清代码出了什么问题。

在行

val difference = i * singeDateDifference

您使用的是整数类型(Kotlin中的Int(,因此对于足够大的乘法结果,您将获得整数溢出(因为Int.MAX_VALUE2147483647(,这意味着乘法的结果将是负值。最后3个差值会发生这种情况,这会导致最后3个日期滞后1个月。

只要确保乘法是用Long类型完成的,一种简单的方法是将日期差因子设置为Long。

// ensure we use Long when calculating with epoch millis
val singeDateDifference = 86400000L 

这将导致用Long值执行乘法,并且结果也将是Long值。这将修复错误,并按照您的期望打印日期。

在一般情况下,时间、日期和日历不容易正确,而且多年的工作都被放入了时间API等API中。在处理时间和日期时,我的建议是改用Time API类和方法。它们在包装java.time(java.time.*(中。文件如下:https://developer.android.com/reference/java/time/package-summary

这将防止出现类似您所遇到的错误,因为它允许您使用更高级别的概念,如.plusHours(24).plusDays(1)(并非在所有情况下都相同!(,而不是手动进行所有计算。即使你有自己的测试,你迟早会在时间、日期和日历上出错。我知道,并不是所有的日子都是24小时,令人震惊:(这只是我们对时间的一长串看法中的第一个,这些看法根本不是真的。

如果你必须支持旧的Android API级别(低于26(,你需要至少v4.0.0+的Android Gradle插件才能使用Time API(支持核心库降级(。

如果由于某种原因无法使用它,请添加JSR-310 Android Backport(ThreeTen ABP(作为依赖项。这将在包org.threeten.bp.*下添加相同的Time API,其类和方法与Time API相同,后者仅在Android上从API 26+级(不支持核心库降级(可用。请注意,推荐的方法是切换到最新版本的Android Gradle插件,因为该库的支持正在逐步减少。

请参见此处:https://github.com/JakeWharton/ThreeTenABP

最新更新