日期格式化使用 YYYY-MM-dd 的潛在問題
- 測試邏輯:
- 創(chuàng)建兩個日期格式化,一個是出問題的YYYY-MM-dd,另一個是正確用法yyyy-MM-dd
- 分別去格式化兩個不同的日期:2020年12月26日(周六),2020年12月27日(周日)
- 代碼如下
@Test
public void dateTest() {
// 指定了兩個時間
// 通過指定具體的 年月日時分秒 構(gòu)建 一個 LocalDateTime 對象(無時區(qū)), 綁定 到 北京時區(qū),轉(zhuǎn)為 實(shí)例,構(gòu)建Date 對象
test(Date.from(LocalDateTime.of(2020,12,27,12,1,35).atZone(ZoneId.of("Asia/Shanghai")).toInstant()));
test(Date.from(LocalDateTime.of(2020,12,26,12,1,35).atZone(ZoneId.of("Asia/Shanghai")).toInstant()));
}
private void test(Date date) {
String loY = "yyyy-MM-dd HH:mm:ss";
String upY = "YYYY-MM-dd HH:mm:ss";
SimpleDateFormat loF = new SimpleDateFormat(loY);
SimpleDateFormat upF = new SimpleDateFormat(upY);
System.out.println("小Y格式化:" + loF.format(date));
System.out.println("大Y格式化:" + upF.format(date));
System.out.println("===========================");
}
小Y格式化:2020-12-27 12:01:35
大Y格式化:2021-12-27 12:01:35
===========================
小Y格式化:2020-12-26 12:01:35
大Y格式化:2020-12-26 12:01:35
===========================
-
結(jié)果分析
發(fā)現(xiàn)當(dāng)日期為 2020-12-27 時,兩個 SimpleDateFormat 對象的轉(zhuǎn)換的出來年份不一樣,原因時一個的樣式使用的 年份的 標(biāo)識不同 "YYYY" 和 "yyyy"
具體原因時,"Y"是表示周年,表示:當(dāng)天所在的周屬于的年份,一周從周日開始,周六結(jié)束,只要本周跨年,那么這周就算入下一年
對于周年的具體解釋:
參考:GregorianCalendar#getWeekYear() 這個方法上的注釋
返回此公歷所代表的周年。從“1”到“最大周數(shù)”之間的周中的日期具有相同的“周年”值,可以是“年(日歷年)”值的前一年,也可以是“年(日歷年)”值的后一年。
此方法在計算周年之前調(diào)用
就是說對于年份的區(qū)分,是把一年的天數(shù),分成多少周(能整除的天數(shù),就算這個周年表示的年份和當(dāng)前的公歷年份相同),后面多余不滿一周當(dāng)年的多余天數(shù)的就表示是下一個周年(就是當(dāng)前公歷年份的下一年)
-
說明
這里為了舉例方便使用了 SimpleDateFormat 類,但是該類是線程不安全得,已經(jīng)不推薦使用,需要特別注意,建議使用 DateTimeFormatter 類進(jìn)行時間格式化
-
SimpleDateFormat 類上的注釋中的一些說明
Letter
| Date or Time Component
| Presentation
| Examples
|
G
| Era designator
| Text
| AD
|
y
| Year
| Year
| 1996 ; 96
|
Y
| Week year
| Year
| 2009 ; 09
|
M
| Month in year (context sensitive)
| Month
| July ; Jul ; 07
|
L
| Month in year (standalone form)
| Month
| July ; Jul ; 07
|
w
| Week in year
| Number
| 27
|
W
| Week in month
| Number
| 2
|
D
| Day in year
| Number
| 189
|
d
| Day in month
| Number
| 10
|
F
| Day of week in month
| Number
| 2
|
E
| Day name in week
| Text
| Tuesday ; Tue
|
u
| Day number of week (1 = Monday, ..., 7 = Sunday)
| Number
| 1
|
a
| Am/pm marker
| Text
| PM
|
H
| Hour in day (0-23)
| Number
| 0
|
k
| Hour in day (1-24)
| Number
| 24
|
K
| Hour in am/pm (0-11)
| Number
| 0
|
h
| Hour in am/pm (1-12)
| Number
| 12
|
m
| Minute in hour
| Number
| 30
|
s
| Second in minute
| Number
| 55
|
S
| Millisecond
| Number
| 978
|
z
| Time zone
| General time zone
| Pacific Standard Time ; PST ; GMT-08:00
|
Z
| Time zone
| RFC 822 time zone
| -0800
|
X
| Time zone
| ISO 8601 time zone
| -08 ; -0800 ; -08:00
|
|