当前位置: 首页 > 科技观察

为什么阿里巴巴在格式化日期时要求y代表年份,而不是Y?

时间:2023-03-17 21:38:21 科技观察

Java中的日期处理你一定很熟悉。我们经常需要在代码中进行日期转换和日期格式化。一般我们在格式化日期的时候都会用到SimpleDateFormat工具。之前有一篇文章介绍了SimpleDateFormat的线程安全(https://www.hollishuang.com/archives/3017),这篇文章再介绍一个和SimpleDateFormat相关的,容易被忽视,一旦忽视可能会导致重大故障.SimpleDateFormatSimpleDateFormat是Java提供的一个日期格式化和解析的工具类。它允许格式化(日期->文本)、解析(文本->日期)和规范化。SimpleDateFormat允许选择任何用户定义的日期时间格式模式。在Java中,可以使用SimpleDateFormat的format方法将Date类型转换为String类型,并可以指定输出格式。//日期为StringDatedata=newDate();SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");StringdataStr=sdf.format(data);System.out.println(dataStr);以上代码,转换结果为:2018-11-2513:00:00,日期时间格式由“日期时间模式”字符串指定。如果要转换为另一种格式,只需指定不同的时间模式即可。在Java中,可以使用SimpleDateFormat的parse方法将String类型转换为Date类型。//字符串到DataSystem.out.println(sdf.parse(dataStr));日期时间模式表达方法在使用SimpleDateFormat时,需要用字母来描述时间元素,并组装成想要的日期时间模式。常用时间元素与字母的对应表(JDK1.8)如下:模式字母通常会重复出现,其数量决定了其精确表示。就像我们之前使用的“yyyy-MM-ddHH:mm:ss”。我们知道y其实是year的缩写,所以我们都知道用y来表示年份。默认情况下,我们都使用y而不是Y,那么这两者有什么区别呢?如果用错了会有什么后果?其实在规定中,y是year的意思,Y是WeekYear的意思!什么是周年?我们知道不同的国家对一周的开始和结束有不同的定义。比如在中国,我们把星期一作为一周的第一天,而在美国,他们把星期日作为一周的第一天。同样,您如何定义哪一周是一年中的第一周?这在很多方面也是一个问题。比如下图是2019年12月到2020年1月的日历,2020年的第一周是哪一周?不同的地区和国家,甚至不同的人,都有不同的理解。1、1月1日为周三,到下周三(1月8日)为止,这7天算作一年的第一周。2、由于星期日(星期一)是一周的第一天,所以一年的第一周必须从2020年的第一个星期日(星期一)算起7天后计算。3、因为12.29、12.30、12.31是2019年,而1.1、1.2、1.3是2020年,1.4周日是下一周的开始,所以第一周应该只有1.1、1.2、1.3。ISO8601因为不同的人对日期和时间的表示方法有不同的理解,所以大家共同制定了一个国际规范:ISO8601。国际标准化组织的国际标准ISO8601是日期和时间的表示方法,全称是《数据存储和交换形式·信息交换·日期和时间的表示方法》。在ISO8601中,一年的第一个日历周有四个等价物:1,一年中的第一个星期四;2、1月4日那一周;3、一年中的前四天同一天星期几;4、去年12月29日至今年1月4日的那一周的星期一;根据这个标准,我们可以计算出:2020年第一周:2019.12.29-2020.1.4所以,根据ISO8601标准,2019年12月29日、2019年12月30日、12月31日这两天,2019其实不属于2019年的最后一周,而是属于2020年的第一周。JDK对ISO8601提供的支持根据ISO8601中日历周和日表示法的定义,2019.12.29-2020.1.4是2020年的第一周。我们要输入一个日期,程序根据ISO8601中日历日期的定义,告诉我们这个日期属于哪一年。比如我输入2019-12-20,他告诉我现在是2019;当我输入2019-12-30时,他告诉我现在是2020年。为了提供这样的数据,Java7引入了“YYYY”作为新的日期模式作为标识符。使用“YYYY”作为标识符,然后使用SimpleDateFormat获取日期的星期所属的年份。因此,我们可以通过代码进行验证:(sdf.parse("2019-12-01")));System.out.println(sdf1.format(sdf.parse("2019-12-30")));System.out.println(sdf1.format(sdf.parse("2020-01-01")));}}输出结果为:201920202020可见,2019-12-30属于2020年的第一周,所以返回的年份为2020年。和如果将“YYYY”改为“yyyy”,则输出结果为:201920192020由于这种情况,如果我们在日常开发中将y写成Y,可能会导致日期输出结果与我们的预期不一致。当我们要表示日期时,我们必须使用yyyy-MM-dd而不是YYYY-MM-dd。两者的返回结果大部分情况下是一样的,但是极端情况下会出现问题。而这个需求在《阿里巴巴Java开发手册》中也有类似的需求:?好了,大家去检查一下你的代码吧。是否有“YYYY-MM-dd”形式的代码?如果是这样,那一定是要除掉哦!~