`uuuu` versus` yyyy` in` DateTimeFormatter` formatting code templates in Java?

The documentation for the DateTimeFormatter class talks about its formatting codes for the year:

year 2004; 04

year 2004; 04

...

Year: The number of letters defines the minimum field width below which the pad is used. If the number of letters is two, the abbreviated two-digit form is used. For printing, this gives the rightmost two digits. For parsing, this will be analyzed using a base value of 2000, resulting in a range of 2000 to 2099 inclusive during the year. If the number of letters is less than four (but not two), then the sign is displayed only for negative years in accordance with SignStyle.NORMAL. Otherwise, the sign is displayed if the width of the strip is exceeded, according to SignStyle.EXCEEDS_PAD.

No other mention of the "era".

What is the difference between these two codes, u compared to y , year compared to year-of-era ?

When should you use something like this uuuu-MM-dd pattern and when yyyy-MM-dd when working with dates in Java?

It seems that the example code written by those who know uses uuuu , but why?

Other formatting classes, such as the deprecated SimpleDateFormat , only have yyyy , so I'm confused why java.time brings this uuuu for the "year of the era."

+19
source share
3 answers

Within java.time -package we can say:

  • It is safer to use "u" instead of "y" because DateTimeFormatter would otherwise insist on having an era combined with "y" (= year of an era). Therefore, the use of "u" avoids some possible unexpected exceptions during strict formatting / parsing. See also this SO post . Another minor thing that has been enhanced by the u -symbol compared to y is the printing / analysis of negative Gregorian years (in the distant past).

  • Otherwise, we can clearly state that using "u" instead of "y" destroys long-standing habits in Java programming . It is also not clear that β€œand” means any year, because a) the first letter of the English word β€œyear” does not match this character and b) SimpleDateFormat used β€œand” for another purpose, since Java -7 ( ISO-day-number weeks ). Confusion guaranteed - forever?

  • We should also see that using eras (the β€œG” symbol) in the ISO context is generally dangerous when looking at historical dates . If "G" is used with "u", then both fields are not related to each other. And if "G" is used with "y", then the formatter is satisfied, but still uses the light Gregorian calendar, when the historical date requires different calendars and date processing.

Initial Information:

When developing and integrating the JSR-310 ( java.time -package s), the designers decided to use the CLDR / LDML specification as the basis for the template characters in DateTimeFormatter . The symbol "u" ​​was already defined in the CLDR as the year of the proletarian Gregorian, so this value was transferred to the new upcoming JSR-310 (but not to SimpleDateFormat for reasons of backward compatibility).

However, this decision to follow the CLDR was not entirely consistent, because the JSR-310 also introduced new pattern characters that were not and are not in the CLDR, see also this old CLDR ticket . The proposed β€œI” character was changed by the CLDR to β€œVV” and finally replaced by the JSR-310, including the new β€œx” and β€œX” characters . But "n" and "N" still do not exist in the CLDR, and since this old ticket is closed, it is not at all clear whether the CLDR will ever support it in the sense of JSR-310. In addition, the symbol β€œp” is not mentioned in the ticket (the fill instruction in JSR-310, but not defined in the CLDR). Therefore, we still do not have perfect agreement between template definitions in different libraries and languages.

And about the "u": we also should not lose sight of the fact that the CLDR associates this year of the era with at least some mixed Julian-Gregorian year, and not with the proleptic Gregorian year like JSR-310 (leaving strangeness negative years aside). So there is no perfect agreement between CLDR and JSR-310.

+17
source

The javadoc section for Formatting and Analysis Templates for DateTimeFormatter lists the following 3 corresponding characters:

 Symbol Meaning Presentation Examples ------ ------- ------------ ------- G era text AD; Anno Domini; A u year year 2004; 04 y year-of-era year 2004; 04 

Just for comparison, these other characters are easy enough to understand:

  D day-of-year number 189 d day-of-month number 10 E day-of-week text Tue; Tuesday; T 

day-of-year , day-of-month and day-of-week - this is obviously the day within this area (year, month, week).

So, year-of-era means the year within a given area (era), and right above it, era displayed with an approximate value of AD (another value, which, of course, is BC ).

year - the signed year, where year 0 is 1 BC , year -1 is 2 BC , etc.

To illustrate: When was the Killer Julius Caesar ?

  • March 15, 44 BC (using the MMMM d, y GG template)
  • March 15, -43 (using the MMMM d, u pattern)

Of course, the difference will only matter if the year is zero or negative, and since this is rare, most people don’t care, although they should.

Conclusion: If you use y , you should also use G Since G rarely used, the correct character is the year u , not y , otherwise a non-positive year will not display correctly.

This is called defensive programming :

Defensive programming is a form of defensive design designed to provide continuous function of a piece of software in unforeseen circumstances .


Note that DateTimeFormatter corresponds to SimpleDateFormat :

 Letter Date or Time Component Presentation Examples ------ ---------------------- ------------ -------- G Era designator Text AD y Year Year 1996; 96 

Negative years have always been a problem, and now they have fixed it by adding u .

+13
source

In short

  1. For 99% of the goals, you can throw a coin, no matter if you use yyyy or uuuu (or whether you use yy or uu for a two-digit year).
  2. It depends on what you want to happen a year earlier than 1 CE (1 AD). The fact is that in 99% of programs this year will never happen.

The other two answers have already presented the facts of how u and y very well, but I still felt that something was missing, so I give a slightly more opinion-based answer.

To format

Assuming that you do not expect the year up to 1 CE to be formatted, the best you can do is check this assumption and react accordingly if it breaks. For example, depending on the circumstances and requirements, you may print an error message or throw an exception. One of the very soft ways of refusing can be to use a template with y (year of an era) and G (era) in this case and a template with u or y in the usual case of the current era. Please note that if you print the current date or the date when your program was compiled, you can be sure that it is in the general era and may skip the check.

To parse

In many (most?) Cases, analysis also means checking that you have no guarantee what your input string looks like. This usually comes from the user or from another system. Example: a date string looks like 2018-09-29. Here the choice between uuuu and yyyy should depend on what you want to do if the line contains year 0 or negative (for example, 0000-08-17 or -012-11-13 ). Assuming this would be a mistake, yyyy immediate answer: use yyyy so that there is a yyyy exception in this case. Even better: use uuuu and after analysis, check the range of the analyzed date. The latter approach takes into account both a more accurate check and a better error message in case of a check error.

Special case (already mentioned by Meno Hochschild): If your formatter uses a strict recognizer style and contains y without G , parsing will always be unsuccessful because, strictly speaking, the year of an era is ambiguous without an era: 1950 could mean 1950 A.D. or 1950 BC (1950 BC), So in this case you will need u (or providing a default era, this is possible via DateTimeFormatterBuilder ).

In short again

Explicitly checking your date range, especially your age, is better than relying on the choice between uuuu and yyyy to identify unexpected very early years.

+1
source

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


All Articles