在Java中处理Calendar对象的简洁方法

时间:2014-06-10 05:12:28

标签: java calendar

Calendar对象中一些最常用的方法返回void并且不可链接,例如add()。更重要的是,该类似乎是可变的,如果您向Calendar对象添加一天,则原始Calendar对象将使用新日期进行修改。

我写了这个:

Calendar currentTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
// report.time() returns a Calendar instance
if(report.time().after(currentTime.getTime().add(Calendar.DATE, 1)) || currentTime.after( report.time().add(Calendar.MONTH, 5) )){
    validTime=false;
}

这不能编译,因为在after()返回void和after()的参数中使用的add()方法需要一个Calendar实例,而不是void。

我能想到的唯一其他解决方案是非常丑陋和臃肿:

Calendar currentTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
Calendar nextDay = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
nextDay.add(Calendar.DATE, 1))
Calendar nextMonths = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
nextMonths.add(Calendar.MONTH, 5))
if(report.time().after(nextDay) || currentTime.after(nextMonths )){
   validTime=false;
}

有更简洁的方法吗?

1 个答案:

答案 0 :(得分:0)

我不确定您的日期时间有效范围的业务逻辑,因为您的代码似乎是矛盾的。

这里有Joda-Time中的一些代码,可以帮助您朝着正确的方向前进。我们假设目标日期时间在3天前到明天之间有效,为期5天(3天前,今天,明天)。

通常,定义时间跨度的最佳做法是"半开放"做法。在这种方法中,跨度的开始是包容性的,而结尾是独占的。所以包括明天意味着我们希望每个时刻都能达到但不包括明天之后的第一个时刻;所以我们在下面的代码中添加两个天而不是一个。搜索StackOverflow以获得更多关于"半开放"。

的讨论和示例

方法withTimeAtStartOfDay会调整到当天的第一时刻。由于夏令时或其他异常,该时刻并不总是00:00:00。在UTC中,这一天总是在那个时候开始,但作为一种习惯,你应该避免在特定时间进行硬编码(让Joda-Time为你工作)。

不确定你想要什么,但似乎你想定义"明天"按UTC我们在这里这样做。

DateTime now = DateTime.now( DateTimeZone.UTC );
DateTime momentAfterTomorrow = now.plusDays( 2 ).withTimeAtStartOfDay(); 
DateTime threeDaysAgo = now.minusDays( 3 ).withTimeAtStartOfDay();
Interval validInterval = new Interval( threeDaysAgo, momentAfterTomorrow );  // ( inclusive, exclusive )

测试我们的目标日期时间是否在该时间间隔内发生。

DateTime target = now.minusDays( 1 );  // Arbitrary choice.
boolean targetIsValid = validInterval.contains( target );  // True

另一项测试。

DateTime target2 = now.minusDays( 111 );  // Arbitrary choice.
boolean target2IsValid = validInterval.contains( target2 );  // False

顺便说一句,Joda-Time提供了三个类来定义各种时间范围:Period,Interval和Duration。