2

The following code (in main)

LocalDate d ;
DateTimeFormatter formatter;

d = LocalDate.of(2021, 11, 14);
System.out.println(d);

formatter = DateTimeFormatter.ofPattern("MM.dd.YYYY");
System.out.println(formatter.format(d));

formatter = DateTimeFormatter.ofPattern("YYYY/MM/dd");
System.out.println(formatter.format(d)+ "\n");
            
d = LocalDate.of(2021, 1, 1);
System.out.println(d);
                
formatter = DateTimeFormatter.ofPattern("MM.dd.YYYY");
System.out.println(formatter.format(d));

formatter = DateTimeFormatter.ofPattern("YYYY/MM/dd");
System.out.println(formatter.format(d));

outputs in my Netbeans 12.5 with the latest or fairly recent Oracle Java 17

run:
2021-11-14
14.11.2021
2021/11/14

2021-01-01
01.01.2020
2020/01/01
BUILD SUCCESSFUL (total time: 0 seconds)

The formatted output for today, 14-NOV-2021, is ok, but output for 01-JAN-2021 is wrong. Formatted output prints 2020 , one year off.

Can you repeat this? If so: Any ideas why this happens?

Jens Piegsa
  • 7,399
  • 5
  • 58
  • 106
duaw
  • 29
  • 2
  • 1
    I am unable to reproduce your output. I got valid output with year as 2021. Something to do with Locale? – Vasanth Subramanian Nov 14 '21 at 11:19
  • In my pc, it was `2021/01/01` the last output.@duaw are you missing something? or just mistake? I think it is you env problem. – Dolphin Nov 14 '21 at 11:19
  • I had the same output as you. Changing the pattern to `"MM.dd.yyyy"` displayed 2021 instead of 2020 – Flav Nov 14 '21 at 11:22
  • 1
    I am able to reproduce your output by changing Locale as UK. Example: DateTimeFormatter.ofPattern("MM.dd.YYYY", Locale.UK) & DateTimeFormatter.ofPattern("YYYY/MM/dd", Locale.UK) – Vasanth Subramanian Nov 14 '21 at 11:24
  • @VasanthSubramanian Well spotted. The problem is locale dependent because different locales have different definitions of week numbers and hence of week-based-year. Which, as the answers explain, is what upper case `YYYY` gives you. – Ole V.V. Nov 14 '21 at 12:17

2 Answers2

4

According to the Javadoc of java.time.format.DateTimeFormatter

  • y (lowercase) represents the year-of-era and
  • Y (uppercase) represents the week-based-year.

The week-based date/time system is defined in ISO 8601 (see: Wikipedia article).

Jens Piegsa
  • 7,399
  • 5
  • 58
  • 106
1

You want u, not Y:

  • Y is week-based year. If you're an accountant, this is important. If you're not, this is the devil: It seems right almost always, except in certain highly exotic dates, such as jan 1st. Weeks customarily are defined as: "Whatever year it is on the thursday of that week, that's the year that week belongs to", so if e.g. Jan 1st falls on a friday, then the week that contains Jan 1st is of the previous year (as the thursday of that week was dec 31st).

  • y is year as you mostly know it, except it doesn't really do what you want when go to BC years. It's not likely to come up, but then neither is the week-based-year thing. Nobody likes Year-2k style bugs, right?

  • u truly does what you imagined. It just gives you the year. Negative if need be.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • And to make matters worse, your definition of week-based year is correct for your locale and mine, but not for all locales. *the devil* describes pretty precisely. – Ole V.V. Nov 14 '21 at 12:29