计算接下来 30 天的隔天的 TimeInMillis 值会给我在 Kotlin 中的错误日期

Posted

技术标签:

【中文标题】计算接下来 30 天的隔天的 TimeInMillis 值会给我在 Kotlin 中的错误日期【英文标题】:Calculating TimeInMillis value for alternate days for the next 30 days gives me wrong dates in Kotlin 【发布时间】:2022-01-20 20:37:33 【问题描述】:

我想获取从任何选定日期开始的接下来 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 个日期。我无法弄清楚代码有什么问题。

【问题讨论】:

顺便说一句,日子并不总是 24 小时。天数可以是 23、23.5、25 或其他小时数。 【参考方案1】:

排队

val difference = i * singeDateDifference

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

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

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

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

在一般情况下,时间、日期和日历并不容易正确设置,并且已经将多年的工作投入到诸如 Time API 之类的 API 中。 在处理时间和日期时,我的建议是改用 Time API 类和方法。它们在包java.time (java.time.*) 中。 文档在这里:https://developer.android.com/reference/java/time/package-summary

这将防止像您遇到的那样的错误,因为它允许您使用更高级别的概念,例如 .plusHours(24).plusDays(1)(并非在所有情况下都相同!)而不是执行所有手动计算。即使您有自己的测试,迟早您会在时间、日期和日历方面出现问题。并不是所有的日子都是 24 小时,我知道这很令人震惊 :) 这只是 a long list of things that we believe about time, that are simply not true. 上的第一天

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

如果由于某种原因您不能使用它,请将 JSR-310 Android Backport (ThreeTen ABP) 添加为依赖项。 这将在 org.threeten.bp.* 包下添加与 Time API 相同的类和方法的相同 Time API,否则只能在 API 级别 26+ 的 Android 上使用(不支持核心库脱糖)。请注意,推荐的方法是切换到最新版本的 Android Gradle 插件,因为该库的支持正在逐渐减少。

请看这里: https://github.com/JakeWharton/ThreeTenABP

【讨论】:

以上是关于计算接下来 30 天的隔天的 TimeInMillis 值会给我在 Kotlin 中的错误日期的主要内容,如果未能解决你的问题,请参考以下文章

过去 30 天的移动平均线

练习四:日期计算(输入某年某月某日计算出这一天是该年第几天的方法)

微软office excel里的TEXT函数[d]没法计算超过30天的时间差?

1080p的监控摄像头,所需的存储容量怎样计算?比如30个摄像头,满足30天的存储要求,需要多大的

过去 30 天的平均值,不包括当前记录(混合日期和基于行的条件)

C语言输入年月日,判断第几天的问题最后计算是第几天出错了