最近发现了一个存在系统中的坑。
在一段按月分表访问的代码逻辑中,使用了以下方法进行时间格式转换:
public static String
dateToString(Date date
, String formatType) {
SimpleDateFormat formatter =
new SimpleDateFormat(formatType)
;
String str = formatter.format(date)
;
return str
;
}
调用时,一开始传的formatType是'YYYYMM':
String dateStr = dateToString
(date
,
'YYYYMM'
)
;
发现一个奇怪的现象,正常来说默认建表逻辑只会预先创建当月以及下个月的分表,
但看到库中201612这个分表已经被创建了,查看该表,也已经存在数据。
数据产生的时间范围是在2015-12-27至2015-12-31期间。
在不知道原因之前,因为数据和表名都对应12月份,一度怀疑是系统时间的问题。-_-\\\
针对2015-12-26、2015-12-27这2个日期分别使用**YYYYMM和yyyyMM格式化**,
得到的结果分别是:
YYYYMM:201512、201
612
yyyyMM:201512、201512
原因定位到“YYYYMM”格式化这里面。查看JavaDoc,发现上面描述:
y表示Year, Y表示Week Year。 r> 'If week year 'Y' is specified and the calendar doesn't support any week years, the calendar year ('y') is used instead. The support of week years can be tested with a call to getCalendar().isWeekDateSupported().'
如果Week Year不支持,同时又使用了Y的话,那么会默认当成y使用。
Week Year又是什么意思呢?
'Week number according to the ISO-8601 standard, weeks starting on Monday. The first week of the year is the week that contains that year's first Thursday (='First 4-day week'). The highest week number in a year is either 52 or 53.
'
根据ISO-8601标准,每周从星期一开始计算。每年第一个星期四所在的那个星期为当年的第一周。(1月份至少有4天在该星期)
按这个说法,查看了2015-12-27所在当月的日历,它应该算2015年的第52周,为什么会得到201612呢?见javadoc中的描述:
public int
getMinimalDaysInFirstWeek()
Gets what the minimal days required in the first week of the year
are; e.g., if the first week is defined as one that
contains the first day of the first month of a year, this method
returns1. If the minimal days required must be a full week, this method
returns 7.
Returns:
the minimal days required in the first week of the year.
public int getFirstDayOfWeek()
Gets what the first day of the week is; e.g., SUNDAY in the U.S.,
MONDAY in France.
Returns:
the first day of the week.
原来默认情况下(我使用的是JDK7),JDK返回的值:
getFirstDayOfWeek=1 (星期天)
getMinimalDaysInFirstWeek=1
需要设置first day of week为星期一,而且 minimal days first
week为4才与ISO-8601标准一致。
在默认情况下,2015-12-27属于2016年的第一周(星期天开始,并且2016年有一天在该周),所以得到“201612”。
当设置getFirstDayOfWeek=2(星期一)、getMinimalDaysInFirstWeek=4时,就能得到正确的“201512”了。
当然,最正确的做法还是使用yyyyMM,而不是YYYYMM。
这里是引用
http://blog.sina.cn/dpool/blog/s/blog_7afaccae0102wdq7.html?vt=4