我的输入是开始日期和结束日期。我想检查它是在12月1日到3月31日之间。(这一年可能会发生变化,并且只有日期,或者在此期间之外的日期)。
到目前为止,我没有找到Joda-time的任何解决方案。有人能给我一个起点怎么做(不是代码,只是逻辑)? 我还没有检查代码,但它非常难看,我想找到一个算法解决方案
public static boolean isInWinter(Contract contract) {
logger.info("begin isInWinter:");
DateTime beginDate = contract.getBeginningDate();
DateTime endDate = contract.getEndDate();
/*
* If the year is different (etc 2012 dec,2013 marc) check that the
* beginning month is december, and the end month is jan,feb,marc
*/
if (endDate.getYear() - beginDate.getYear() == 1) {
if ((beginDate.getMonthOfYear() == 12)
&& ((endDate.getMonthOfYear() == 1
|| endDate.getMonthOfYear() == 2 || endDate
.getMonthOfYear() == 3))) {
logger.info("return true different year");
return true;
}
/*
* Same year can be if begin and end date is december or begin and
* and date is jan,febr,marc TODO REMOVE Auto formatter
*/
} else if (endDate.getYear() - beginDate.getYear() == 0) {
if ((beginDate.getMonthOfYear() == 12 && endDate.getMonthOfYear() == 12)
|| ((beginDate.getMonthOfYear() == 1
|| beginDate.getMonthOfYear() == 2 || beginDate
.getMonthOfYear() == 3) && (endDate
.getMonthOfYear() == 1
|| endDate.getMonthOfYear() == 2 || endDate
.getMonthOfYear() == 3))) {
logger.info("return true same year");
return true;
}
}
logger.info("return false");
return false;
}
答案 0 :(得分:2)
Joda-Time及其Interval类使用overlap
方法正是您所需要的。很容易。
与java.util.Date不同,DateTime确实知道其分配的时区。通常更好地指定比依赖默认。请注意,如果您要跟踪日期+时间(DateTime而不是LocalDate),则时区至关重要。 “日”开始和结束的定义取决于时区。跨时区工作的企业可以选择使用UTC来实现此目的。
仅供参考,除了Interval之外,Joda-Time还提供适用于一段时间的期间和持续时间等级。
使用日期时间值但关注“日期”时,请将时间部分调整为该特定时区的当天的第一时刻。在Joda-Time中,只需调用withTimeAtStartOfDay
方法即可。
避免与“午夜”相关的类和方法。 Joda-Time团队不再推荐它们。
Joda-Time在比较时间跨度时使用“半开”方法。包容性和结束性的开头是排他性的。这意味着,因为您希望从12月1日到3月31日我们定义the first moment of the day of December 1
到the first moment of the day of April 1
的间隔。如果你仔细考虑这个问题,并在“joda间隔”上搜索StackOverflow其他帖子,你就会看到这种方法的智慧。
Interval类提供了方便的比较方法:contains
,abuts
,overlap
和gap
。请务必阅读文档以了解具体细节。
Java 8带来了新的java.time包,受JSR 310定义的Joda-Time的启发.Joda-Time继续在Java 8中工作,但你可能想学习java.time而不是Joda-Time如果你是日期工作的新手。
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Budapest" ); // Or, perhaps DateTimeZone.UTC
// Inputs
DateTime contractStart = new DateTime( 2014, 1, 2, 0, 0, 0, timeZone );
DateTime contractStop = new DateTime( 2014, 5, 6, 0, 0, 0, timeZone );
Interval contractInterval = new Interval( contractStart, contractStop );
// Target to test
DateTime targetStart = new DateTime( 2013, DateTimeConstants.DECEMBER, 1, 0, 0, 0, timeZone );
DateTime targetStop = targetStart.plusMonths( 4 );
Interval targetInterval = new Interval( targetStart, targetStop );
boolean targetContainsContract = targetInterval.contains( contractInterval );
boolean targetOverlapsContract = ( targetInterval.overlap( contractInterval ) != null );
转储到控制台...
System.out.println( "contractInterval: " + contractInterval );
System.out.println( "targetInterval: " + targetInterval );
System.out.println( "targetContainsContract: " + targetContainsContract );
System.out.println( "targetOverlapsContract: " + targetOverlapsContract );
跑步时......
contractInterval: 2014-01-02T00:00:00.000+01:00/2014-05-06T00:00:00.000+02:00
targetInterval: 2013-12-01T00:00:00.000+01:00/2014-04-01T00:00:00.000+02:00
targetContainsContract: false
targetOverlapsContract: true
答案 1 :(得分:1)
创建一个间隔,其中包含您作为输入的开始日期和结束日期。
创建从3月到12月的间隔。
如果有以下情况,您的情况属实:
在代码中:
marchToDecember.contains(interval) || marchToDecember.overlap(interval) == null
答案 2 :(得分:1)
由于您提到日期将同时处于期间或期间,您只需要测试其中一个。
因此,只需测试beginDate.getMonthOfYear()
是否返回12,1,2或3。