我的同事和我有一个有趣的问题。我们使用的旧系统只返回ddMMM
格式的日期数据。如果当天的日期/月份是过去的,那么我们假设这个日期适用于明年。否则它适用于当年。
今天是4/30/2015
。如果系统返回包含12MAR
的记录,则该日期将转换为3/12/2016
。如果日期显示为07MAY
,则会转换为5/7/2015
。
但是,目前尚不清楚如何确定29FEB
的年份,因为它是闰年。我们无法在一年内实例化它而不会抛出错误。我们在尝试为当年创建try/catch
时依赖LocalDate
。如果它捕获,我们认为它属于明年。
有更多犹太洁食方式吗?
答案 0 :(得分:8)
"cmd /c cd\\ && cd\\data\\commands && wscript \"invisible.vbs\" \"Ready2Go.bat\"
,这就是你所拥有的。Year.isLeap(long)
有希望概述您需要考虑的三个“奇怪”条件 - 我们没有足够的信息告诉您在这些情况下该怎么做。
答案 1 :(得分:2)
现代方法是使用java.time类。具体而言,在您的情况下MonthDay
。
请注意,您应始终指定Locale
以确定用于翻译月份名称的人类语言。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "ddMMM" , Locale.ENGLISH );
String input = "29FEB";
MonthDay md = MonthDay.parse( input , f );
您可以将此应用于一年,以获得LocalDate
对象,即仅为日期的年 - 月 - 日值。
LocalDate
LocalDate
类表示没有时间且没有时区的仅限日期的值。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
如果我们查看2月29日,请检查闰年。如果这不是闰年,那么你说你想搬到明年。但是,如果明年也不是闰年呢?你需要坚持到达闰年。
int yearNumber today.getYear();
LocalDate ld = null;
if( md.equals( MonthDay.of( 2 , 29 ) && ( ! Year.of( today ).isLeap() ) ) {
// If asking for February 29, and this is not a leap year, move to next year, per our business rule.
… keep adding years until you find a year that *is* a leap year.
ld = md.atYear( yearNumber + x );
} else {
ld = md.atYear( yearNumber );
}
如果月份是非闰年的2月29日,该问题有一个特殊的商业规则,即跳到下一年。但是对于其他人来说,请注意java.time中的默认行为是回到2月28日,当时要求第29个非闰年。没有例外。
LocalDate february28 =
MonthDay.of( 2 , 29 )
.atYear( myNonLeapYearNumber ); // 29th becomes 28th.
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,.Calendar
和& java.text.SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。