Java 8 LocalDate- 确定没有年份的 Feb-29 日期的年份?

Java 8 LocalDate- determining the year of a yearless Feb-29 date?

我和我的同事有一个有趣的问题。我们使用的旧系统仅 returns 格式 ddMMM 的日期数据。如果 day/month 是当前年份的过去日期,那么我们将假定此日期适用于明年。否则适用于当年。

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

但是,由于 29FEB 是闰年,因此不清楚如何确定年份。我们不能用年份实例化它而不可能抛出错误。我们在尝试为本年度创建 LocalDate 时依赖 try/catch。如果抓住,我们假设它属于明年。

有没有更符合犹太洁食标准的方法?

  • 将值解析为 MonthDay,因为这就是您所拥有的。
  • 如果月日不是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日
      • 如果明年不是闰年,你又需要一个规则

这很有希望概述了您需要考虑的三个 "odd" 条件 - 我们没有足够的信息来告诉您在这些条件下该怎么做。

java.time

现代方法是使用 java.time classes。具体来说,MonthDay 你的情况。

请注意,您应始终指定 Locale 以确定翻译月份名称时使用的人类语言。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "ddMMM" , Locale.ENGLISH );

String input = "29FEB";
MonthDay md = MonthDay.parse( input , f );

您可以将此应用于年份以获得 LocalDate 对象,即年月日的日期值。

LocalDate

LocalDate class 表示没有时间和时区的仅日期值。

时区对于确定日期至关重要。对于任何给定时刻,日期在全球范围内因地区而异。例如,Paris France is a new day while still “yesterday” in 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 中的默认行为是在要求 29 日为非闰年时简单地回退到 2 月 28 日。没有抛出异常。

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

关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.

Joda-Time project, now in maintenance mode,建议迁移到java.time。

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

从哪里获得java.time classes?

  • Java SE 8 and SE 9 及更高版本
    • 内置。
    • 标准 Java API 的一部分,带有捆绑实施。
    • Java 9 添加了一些小功能和修复。
  • Java SE 6 and SE 7
  • Android
    • ThreeTenABP项目专门为Android改编了ThreeTen-Backport(上面提到的)。
    • 参见

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.