Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_017ic4b3fvyFpxThdRxcozLx
45 lines
2.5 KiB
Markdown
45 lines
2.5 KiB
Markdown
# datetimeformatter
|
|
|
|
Companion code for the ankurm.com post *"DateTimeFormatter Cheat Sheet: Patterns, the yyyy vs YYYY Bug, Locales and ISO Formats."*
|
|
Module in `java-core-examples`, the Java-core series. All explanation lives in the post; this module holds the code and the captured output.
|
|
|
|
## Versions this was built and tested against
|
|
|
|
| Component | Version | Notes |
|
|
|---|---|---|
|
|
| JDK | 25.0.5+8 (Temurin, LTS) | `java.time` arrived in Java 8. Locale data is CLDR; the narrow no-break space before AM/PM comes from the CLDR 42 update that shipped in JDK 20. |
|
|
| JUnit Jupiter | 5.11.0 | |
|
|
| Maven | 3.9.11 | |
|
|
|
|
## Quickstart
|
|
|
|
```bash
|
|
export JAVA_HOME=/path/to/jdk-25
|
|
mvn compile
|
|
scripts/run.sh WeekYearBugDemo # one demo
|
|
scripts/run-all.sh # regenerate every file in output/
|
|
```
|
|
|
|
## What's in here
|
|
|
|
| File | What it shows | Output |
|
|
|---|---|---|
|
|
| `PatternLettersDemo.java` | About fifty pattern strings applied to one fixed moment: how repeat count changes `M`, `E`, `S`, `z`, `X`, `O`, and what `A`, `n`, `e`, `B`, `w`, `W` give. | `output/01` |
|
|
| `WeekYearBugDemo.java` | `yyyy` vs `YYYY` vs `uuuu`: the same date in four locales, and how many days in 2020-2030 each locale gets wrong. | `output/02` |
|
|
| `LocaleDemo.java` | en_IN, hi_IN, mr_IN; `Sept`; lowercase `pm`; the U+202F character before AM/PM the parse failure it causes, and `parseLenient()` as the fix. | `output/03` |
|
|
| `ParsingDemo.java` | `STRICT` / `SMART` / `LENIENT` on 31-02-2026, `yyyy` vs `uuuu` under STRICT, digit counts, two-digit years, case sensitivity, and `SimpleDateFormat` for comparison. | `output/04` |
|
|
| `IsoFormatsDemo.java` | Every predefined ISO constant on one value. | `output/05` |
|
|
| `ErrorsDemo.java` | The eleven exceptions people actually meet, with the real messages. | `output/06` |
|
|
| `ThreadSafetyDemo.java` | One shared `SimpleDateFormat` vs one shared `DateTimeFormatter`, 8 threads. Counts for `SimpleDateFormat` drift between runs. | `output/07` |
|
|
| `DateTimeFormatterTest.java` | Pins every claim above as an assertion, 18/18 passing. | `output/08` |
|
|
|
|
## Notes worth knowing before reading the post
|
|
|
|
- **`YYYY` is the week-based year.** On 2026-12-29 it prints `2027` in `en_US` and `en_IN` and `2026` in `en_GB` and `fr_FR` (`output/02`).
|
|
- **The default resolver style is `SMART`**, which parses `31-02-2026` as 28 February 2026 instead of failing (`output/04`).
|
|
- **`ofLocalizedTime(SHORT)` puts U+202F, not a space, before `PM`**, so a typed `3:30 PM` does not parse back (`output/03`).
|
|
|
|
## License
|
|
|
|
MIT - see the [repo-wide LICENSE](../LICENSE).
|