前言
记录下最近在用java处理日期格式的时候遇到的一些坑,虽然是挺简单的一些点,但是如果不了解清楚在使用的时候还是会走很多弯路的。
相关类
Java8 之后,涉及日期处理的类基本都分到了 java.time 包下,非常清楚,功能也做了强化。而在这之前,如果我们要处理日期,就只能组合的使用 java.util 以及 java.text 这两个包,感觉十分凌乱。当然,以后我们就不用再纠结这些了,直接用 java.time 包就行了。这个包下有众多类,不过一般在做日期转换的时候主要关注下面这几个:
1 | LocalDate |
前四个类是用来保存日期的,DataTimeFormatter 使用来将日期进行格式化和解析的,剩下的是用来从格式化的时间数据中提取信息的,分工明确。看起来挺简单的,但是在用的时候还是有一些坑。。。
一些坑
日期本地化
很经典的一个例子就是给一个格式化的日期串,比如 Sun Feb 13 15:00:10 +0000 2011
我们该怎么把他提取到 LocalDateTime 里。
看上去没难度,查一下 DateTimeFormatter 的文档,找到每个部分对应的 pattern 即可:
1 | public void test() { |
然而,这段代码却极大可能会报错:
1 | Exception in thread "main" java.time.format.DateTimeParseException: Text 'Sun Feb 13 15:00:10 2011' could not be parsed at index 0 |
说是无法解析,研究了半天才发现 DateTimeFormatter 这个类默认进行了本地化的设置,如果默认环境是中文,那么他只能解析用中文表示的字符串,类似 星期日 二月 13 15:00:10 2011
。。。
解决的方法也很简单,强行传入一个本地化参数即可:
1 | public void test() { |
带时区的数据
如果我们希望打印带时区信息的格式串,一定要用 ZonedDateTime 而不能用 LocalDateTime ,比如
1 | public void test() { |
正常的会打印出 Sun Mar 11 14:22:43 +0800 2018
,而错误的就会报下面的错:
1 | Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: OffsetSeconds |
正确使用格式串
关于格式串的含义可以参考 java doc,这里有很多意义相近的表示方法,用的时候要用心区分。
比如文档里有这两行:
1 | Symbol Meaning Presentation Examples |
所以我们指的年到底是哪个年呢?这个要好好区分,其实我们一般用的年是指 ‘year-of-era’ ,如果用了另外一个就会发生解析错误。