Java8 时间格式化 DateTimeFormatter
本文最后更新于:2020年12月30日 凌晨
场景
吾辈在使用 Java8 的 LocalDateTime
想要根据某种格式格式化字符串为日期时间,本以来会简单的事情,事实上却出乎预料!
问题
想要格式化一个字符串为日期时间。例如常见的 yyyy-MM-dd hh:mm:ss
格式的 2017-12-11 10:11:05
,吾辈习惯性的写出以下代码
1 |
|
谜之音:JVM 不想理你,并抛给了你一个 Error
1 |
|
大意便是无法解析,去 Google 了一下,在 StackOverflow 上发现了这个问题:DateTimeParseException: Text could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor
里面的答案说是使用 HH
(每小时)而非 hh
(每小时上午时钟),所以吾辈修改了代码,变成了下面这样
1 |
|
然而确实能正常解析了!??**#黑人问号**
根源
去看了一下 Java8 的 DateTimeFormatter
日期时间格式化类,发现了 class 上一段有趣的注释
All letters ‘A’ to ‘Z’ and ‘a’ to ‘z’ are reserved as pattern letters. The
following pattern letters are defined:
Symbol | Meaning | Presentation | Examples |
---|---|---|---|
G |
era | text | AD; Anno Domini; A |
u |
year | year | 2004; 04 |
y |
year-of-era | year | 2004; 04 |
D |
day-of-year | number | 189 |
M/L |
month-of-year | number/text | 7; 07; Jul; July; J |
d |
day-of-month | number | 10 |
Q/q |
quarter-of-year | number/text | 3; 03; Q3; 3rd quarter |
Y |
week-based-year | year | 1996; 96 |
w |
week-of-week-based-year | number | 27 |
W |
week-of-month | number | 4 |
E |
day-of-week | text | Tue; Tuesday; T |
e/c |
localized day-of-week | number/text | 2; 02; Tue; Tuesday; T |
F |
week-of-month | number | 3 |
a |
am-pm-of-day | text | PM |
h |
clock-hour-of-am-pm (1-12) | number | 12 |
K |
hour-of-am-pm (0-11) | number | 0 |
k |
clock-hour-of-am-pm (1-24) | number | 0 |
H |
hour-of-day (0-23) | number | 0 |
m |
minute-of-hour | number | 30 |
s |
second-of-minute | number | 55 |
S |
fraction-of-second | fraction | 978 |
A |
milli-of-day | number | 1234 |
n |
nano-of-second | number | 987654321 |
N |
nano-of-day | number | 1234000000 |
V |
time-zone ID | zone-id | America/Los_Angeles; Z; -08:30 |
z |
time-zone name | zone-name | Pacific Standard Time; PST |
O |
localized zone-offset | offset-O | GMT+8; GMT+08:00; UTC-08:00; |
X |
zone-offset ‘Z’ for zero | offset-X | Z; -08; -0830; -08:30; -083015; -08:30:15; |
x |
zone-offset | offset-x | +0000; -08; -0830; -08:30; -083015; -08:30:15; |
Z |
zone-offset | offset-Z | +0000; -0800; -08:00; |
p |
pad next | pad modifier | 1 |
' |
escape for text | delimiter | |
'' |
single quote | literal ‘ | |
[ |
optional section start | ||
] |
optional section end | ||
# |
reserved for future use | ||
{ |
reserved for future use | ||
} |
reserved for future use |
是的,这是一个日期格式的说明,在这里确实可以看到 HH
才代表的是 24 小时,而 hh
则是将小时分为 am/pm
(上午/下午)。
附:这里吐槽一下,Java 的格式化规则居然和标准的有偏差,
uuuu
也能当作更好的yyyy
使用(主要针对负的年份)
所以现在也只能将格式化时间的 pattern 修改为 uuuu-MM-dd HH:mm:ss
便能正常匹配了!
解决
那么,既然知道日期时间格式化模式的规则,那么接下来就可以直接写模式字符串了
- 日期:
uuuu-MM-dd
- 时间:
HH:mm:ss
- 常见的日期时间:
uuuu-MM-dd HH:mm:ss
- 标准的日期时间:
DateTimeFormatter.ISO_DATE_TIME
(Java8 time 库中已存在)
将字符串转换为日期时间大致有两种方式
1 |
|
那么,Java8
的踩坑之路还在继续,不知还有多少人在用 Java7-
呢?\(@ ̄ ∇  ̄@)/