Java 8 LocalDate - determining a year without an annual date in February-29?

My colleague and I have an interesting problem. We are working with an old system that returns date data only in ddMMM format. If the day / month was last in the current year, then we must assume that this date refers to the next year. Otherwise, it applies to the current year.

So today is 4/30/2015 . If the system returned records from 12MAR , then this date is transferred to 3/12/2016 . If the date reads 07MAY , then it translates to 5/7/2015 .

However, it is unclear how to determine the year for 29FEB , as this is a leap year. We cannot create a copy of this year without the possibility of its release. We relied on try/catch when trying to create a LocalDate for it this year. If he catches, we assume that he belongs to the next year.

Is there a more kosher way to do this?

+6
source share
2 answers
  • Separate the value as a MonthDay , like what you have.
  • If month-month is not February 29th, just treat it as usual
  • If it's February 29th, you need in a special case:
    • Determine if the current year is a leap year with Year.isLeap(long)
    • If this:
    • If he is currently not earlier than February 29, then the result will be February 29 of this year.
    • If you currently need the rules after February 29, you can choose March 1 of the next year or February 28 of the next year.
    • If it is not (leap year this year)
    • If it is currently no earlier than February 28, you again need to apply the rules, perhaps returning from March 1 or February 28 of this year.
    • If it is currently after February 28, then the date logically refers to the next year ...
      • If there is a leap year next year, the result is supposedly February 29 of the next year.
      • If there is no leap year next year, again you need a rule

We hope that we have identified three "strange" conditions that you need to consider - we do not have enough information to tell you what to do in these conditions.

+7
source

java.time

The modern way is java.time classes. In particular, MonthDay in your case.

Please note that you must always specify Locale to determine the human language for translation in the translation of the month name.

 DateTimeFormatter f = DateTimeFormatter.ofPattern( "ddMMM" , Locale.ENGLISH ); String input = "29FEB"; MonthDay md = MonthDay.parse( input , f ); 

You can apply this to the year to get the LocalDate object, the date value of the entire year-month-day.

LocalDate

The LocalDate class represents a value only for a date with no time and no time zone.

The time zone is critical for determining the date. At any given moment, the date changes around the world by zone. For example, a few minutes after midnight in Paris, France is a new day, still "yesterday" in Montreal Quebec .

 ZoneId z = ZoneId.of( "America/Montreal" ); LocalDate today = LocalDate.now( z ); 

If we look at February 29th, mark Leap Year. If this is not a leap year, then you said you want to move to the next year. But what if there is no leap year next year too? You have to keep going until you reach the Leap Year.

 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 ); } 

Return to the 28th

There was a special business rule on the issue of moving to the next year if the month-month is February 29 in a non-leap year. But for other people, it should be known that the default behavior in java.time is simply to return to February 28, when you ask for the 29th year, not related to the temple. No exception selected.

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

About java.time

The java.time framework is built into Java 8 and later. These classes supersede the nasty old legacy time classes such as java.util.Date , .Calendar and java.text.SimpleDateFormat .

The Joda-Time project, now in maintenance mode , advises switching to java.time.

To learn more, see the Oracle Tutorial . And search for qaru for many examples and explanations. JSR 310 specification .

Where to get java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is proof of possible future additions to java.time. Here you can find useful classes such as Interval , YearWeek , YearQuarter and more .

0
source

Source: https://habr.com/ru/post/986316/


All Articles