我正在尝试创建一个应用程序,并且如果今天是在学年,我会陷入困境。用户输入两个日期,没有年份,每年重复发生。这些是学年的开始和结束日期。
我想检查当前日期是否在这两者之间,即使它重叠了两年。因此,如果学校于11月开课,并于6月结束,如果今天是1月22日,它应该返回true。但如果它的七月,它应该返回虚假。
我确实发现了这个问题:Php - work out what academic year it is,但它适用于没有假期的学年。
BTW我有joda时间,如果有帮助的话。
提前致谢。
答案 0 :(得分:0)
好吧,我想了一下,找到了一些解决方案,但这似乎最简单。
private boolean isInSchoolYear(DateTime now, DateTime schoolYearStart, DateTime schoolYearEnd){
int thisYear = now.getYear();
schoolYearStart = schoolYearStart.withYear(thisYear);
schoolYearEnd = schoolYearEnd.withYear(thisYear);
if(schoolYearStart.isBefore(schoolYearEnd)){
return new Interval(schoolYearStart, schoolYearEnd).contains(now);
}
else{
return !(new Interval(schoolYearEnd, schoolYearStart).contains(now));
}
}
这样,如果学年重叠2年或1年,它就会起作用。
答案 1 :(得分:0)
你的问题不清楚。
首先,如果用户输入的日期不是一年,那么他们就不会输入日期。他们输入的是月份编号和月份编号。
也许问题是:
确定给定的目标日期(可能是今天)是否包含在由一对月份和一对来定义的两个区间中的任何一个区域内。每月的数字(“月日”),我们认为该货币对(a)在日期年份结束或(b)从日期年份开始。我们假设这对代表了不到一年的时间跨度。
如果那是问题,那么这里有一些使用Joda-Time 2.7的代码。两个警告:
事实证明Joda-Time有一个MonthDay
类,正是您所需要的。
MonthDay mdStart = new MonthDay ( DateTimeConstants.NOVEMBER, 1 );
MonthDay mdStop = new MonthDay ( DateTimeConstants.JUNE, 1 );
请注意,时区对于确定月份和时间至关重要。像现在这样的一天。例如,在巴黎午夜之后的某个时刻,蒙特利尔仍然是“昨天”。使用proper time zone names,绝不使用3-4个字母代码。
DateTime target = DateTime.now ( DateTimeZone.forID ( "Africa/Casablanca" ) ); // Using current date-time, but could be any date-time.
toDateTime
方法从MonthDay
(月份编号和日期编号)获取数据字段,并将其应用于现有DateTime
以创建新的DateTime
实例。 Joda-Time使用immutable objects,因此我们基于旧实例创建一个新实例,而不是修改旧实例。
让我们考虑两个可能的时间跨度:
首先是较早的间隔。
// Determine a span of time, moving the Start to previous year if need be.
DateTime earlierStart = mdStart.toDateTime ( target ); // Overlay the data fields of the MonthDay on top of the data fields of a DateTime to create a new DateTime object.
DateTime earlierStop = mdStop.toDateTime ( target );
if ( earlierStart.isAfter ( earlierStop ) ) { // If the start would land after the stop, then adjust the start to *previous* year.
earlierStart = earlierStart.minusYears ( 1 );
}
Joda-Time还提供Interval
类,用于将时间跨度定义为沿时间轴的一对特定点。
Interval earlierInterval = new Interval ( earlierStart, earlierStop );
// Determine a span of time, moving the Stop to next year if need be.
DateTime laterStart = mdStart.toDateTime ( target ); // Overlay the data fields of the MonthDay on top of the data fields of a DateTime to create a new DateTime object.
DateTime laterStop = mdStop.toDateTime ( target );
if ( laterStart.isAfter ( laterStop ) ) { // If the start would land after the stop, then adjust the start to *next* year.
laterStop = laterStop.plusYears ( 1 );
}
Interval laterInterval = new Interval ( laterStart, laterStop );
现在测试目标DateTime
是否包含在Interval
中。请注意,Joda-Time明智地使用半开放方法来定义时间跨度,其中开头是包含,而结尾是独占 。因此,在我们的示例中,6月1日在我们的范围内不。这意味着如果目标是11月1日我们会受到打击,但如果目标是6月1日我们就会错过。
Boolean earlierHasTarget = earlierInterval.contains ( target );
Boolean laterHasTarget = laterInterval.contains ( target );
Boolean targetContained = ( earlierHasTarget || laterHasTarget );
Java 8有java.time,一个受Joda-Time启发的新日期时间框架。虽然与Joda-Time大致相似,但它不是直接的替代品。每个都有其他缺乏的功能。特别是,java.time缺少与Interval
等效的任何等价物。