体面的日期时间库
您应该在 Java 8 中使用Joda-Time或新的java.time,因为旧的 java.util.Date 和 .Calendar 类是出了名的麻烦。
时区
你不应该忽视时区的问题。省略时区意味着您的 JVM(主机)的默认时区将适用。你的结果会有所不同。
“一天”和“昨天”的定义取决于您的特定时区。
使用适当的时区名称(主要是大陆斜线城市)。避免使用 3 或 4 个字母代码,因为它们既不标准化也不独特。
如果您的输入字符串没有时区偏移量,即它是UTC格式,则使用内置常量指定DateTimeZone.UTC
。
间隔
Joda-Time 提供了Interval类来定义时间跨度。在您的情况下,跨度是两天,到期日加上前一天。(顺便说一句,如果您像我在前一句中所做的那样更加努力地集中精力和简化您的问题,那么您发布的问题和您的编程都会得到改善。)
半开
通常在日期时间工作中,我们使用“半开”方法来定义跨度。这意味着出于比较的目的,开头是包容性的,而结尾是排他性的。因此,出于您的目的,我们希望从first moment of the day before due date
最高(但不包括)运行first moment of the day *after* due date
.
ISO 8601
您的输入字符串几乎采用ISO 8601标准格式。只需将 SPACE 替换为T
. Joda-Time 有内置的 ISO 8601 格式解析器。
示例代码
Joda-Time 2.3 中的示例代码。
String inputDueDateRaw = "2014-05-09 11:36:41.816"
String inputDueDate = inputDueDateRaw.replace( " ", "T" );
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime due = new DateTime( inputDueDate, timeZone ); // Note the time zone by which to interpret the parsing of the string.
DateTime dayBeforeDue = due.withTimeAtStartOfDay().minusDays( 1 ).withTimeAtStartOfDay();
DateTime dayAfterDue = due.withTimeAtStartOfDay().plusDays( 1 ).withTimeAtStartOfDay(); // Half-open. Up to but not including day after.
Interval renewalInterval = new Interval( dayBeforeDue, dayAfterDue );
测试当前时刻是否在该区间内,使用半开方法进行比较。
boolean isNowEligibleForRenewal = renewalInterval.contains( DateTime.now() );