Java 8 LocalDate-确定2月29日无年的日期?

时间:2015-04-30 17:22:39

标签: java date java-8 jodatime

我的同事和我有一个有趣的问题。我们使用的旧系统只返回ddMMM格式的日期数据。如果当天的日期/月份是过去的,那么我们假设这个日期适用于明年。否则它适用于当年。

今天是4/30/2015。如果系统返回包含12MAR的记录,则该日期将转换为3/12/2016。如果日期显示为07MAY,则会转换为5/7/2015

但是,目前尚不清楚如何确定29FEB的年份,因为它是闰年。我们无法在一年内实例化它而不会抛出错误。我们在尝试为当年创建try/catch时依赖LocalDate。如果它捕获,我们认为它属于明年。

有更多犹太洁食方式吗?

2 个答案:

答案 0 :(得分:8)

  • 将值解析为"cmd /c cd\\ && cd\\data\\commands && wscript \"invisible.vbs\" \"Ready2Go.bat\" ,这就是你所拥有的。
  • 如果月日 2月29日,请正常处理
  • 如果 2月29日,你需要特殊情况:
    • 使用Year.isLeap(long)
    • 确定当前年份是否为闰年
    • 如果是:
    • 如果它当前在2月29日或之前,那么结果是今年2月29日
    • 如果它目前在 2月29日之后,您需要申请规则 - 您可以选择明年3月1日或明年2月28日
    • 如果不是(今年是闰年)
    • 如果它目前在2月28日或之前,您需要再申请规则,可能会在今年3月1日或2月28日返回
    • 如果它当前 2月28日之后,则该日期在逻辑上属于明年......
      • 如果明年是闰年,结果可能是明年2月29日
      • 如果明年闰年,那么您需要一个规则

有希望概述您需要考虑的三个“奇怪”条件 - 我们没有足够的信息告诉您在这些情况下该怎么做。

答案 1 :(得分:2)

java.time

现代方法是使用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 );
}

回到第28位

如果月份是非闰年的2月29日,该问题有一个特殊的商业规则,即跳到下一年。但是对于其他人来说,请注意java.time中的默认行为是回到2月28日,当时要求第29个非闰年。没有例外。

LocalDate february28 = 
    MonthDay.of( 2 , 29 )
            .atYear( myNonLeapYearNumber );  // 29th becomes 28th.

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date.Calendar和& java.text.SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore