卷心了!春节遇到的程序一个Bug!
漫话编程   漫话编程   2020-01-10

2019 年最后一角,城里里看着跨年晚会,享受着这一年最后一角的悠闲时光,女朋友在一旁玩手机。瞧了一会下她突然问我一些很奇怪的题材。

 

图表来自 Pexels

 

于是乎我拿过他的无绳电话机,观看了下面这一幕:

这是微信官方出的群众号管理的 App,地方赫然写着一篇文章的公报日期是 2020/12/29。

 

SimpleDateFormat

SimpleDateFormat 是 Java 提供的一个格式化和分析日期的工具类。他允许进行格式化(日期→文本)、剖析(文本→日期)和多元化。

SimpleDateFormat 有效可以选择任何用户定义之日子-时光格式的全封闭式。

在 Java 官方,可以运用 SimpleDateFormat 的 format 办法,名将一个 Date 品种转化成 String 品种,并且可以指定输出格式。

     
  1. // Date转String 
  2. Date data = new Date(); 
  3. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
  4. String dataStr = sdf.format(data); 
  5. System.out.println(dataStr); 

上述代码,转移的结果是:2018-11-25 13:00:00,日期和时间格式由“日期和时间模式”字符串指定。如果你想要转换成其他格式,只要指定不同之年华模式就行了。

在 Java 官方,可以运用 SimpleDateFormat 的 parse 办法,名将一个 String 品种转化成 Date 品种。

     
  1. // String转Data 
  2. System.out.println(sdf.parse(dataStr)); 

 

日期和时间模式表达方法

在采取 SimpleDateFormat 的时节,要求通过字母来叙时间元素,并组装成想要的日子和时间模式。

公用的年华元素和字母的回应表(JDK 1.8)如下: 

分立式字母通常是重复的,他数量确定他准确表示。如前面我们用过的"yyyy-MM-dd HH:mm:ss"。 

 

什么是 Week Year

咱们掌握,不同之国度对于一周之起始和竣工之概念是不同之。如在中华,咱们把星期一作为一周之首要角,而在塞尔维亚,她们把星期日作为一周之首要角。

同样,如何定义哪一周是一年当中的首要周?这也是一番问题,有很多种艺术。

比如下图是 2019 年 12 月-2020 年 1 月的一份日历:

 

到底哪一周才算 2020 年之首要周呢?不同之地域和国度,甚至不同之人数,都有不同之了解:

  • 1 月 1 日是周三,到副周三(1 月 8 日),这 7 远处算作这一年之首要周。
  • 因为周日(星期一)才是一周之首要角,故此,要下 2020 年之程序一个周日(星期一)起来后推 7 远处才算这一年之首要周。
  • 因为 12.29、12.30、12.31 是 2019 年,而 1.1、1.2、1.3 才是 2020 年,而 1.4 周末是副一周之起始,故此,着重周应该只有 1.1、1.2、1.3 这三角。
  •  

    ISO 8601

    因为不同人对于日期和时间之表示方法有不同之了解,于是乎,大家就共同制定了了一番国际标准:ISO 8601 。

    国际标准组织的国际规范 ISO 8601 是日期和时间之表示方法,全称为《数量存储和交换形式·消息交换·日期和时间之表示方法》。

    在 ISO 8601 官方,对于一年之程序一个日历星期有以下四种等效说法:

  • 本年度第一个星期四所在的周日。
  • 1 月 4 日所在的周日。
  • 本年度第一个至少有 4 远处在同一星期内的周日。
  • 星期一在上年 12 月 29 日至当年 1 月 4 日之内的周日。
  • 根据这个标准,咱们可以推算出:2020 年着重周:2019.12.29-2020.1.4。

    故此,根据 ISO 8601 专业,2019 年 12 月 29 日、2019 年 12 月 30 日、2019 年 12 月 31 日这三角,其实不属于 2019 年之最终一周,而是属于 2020 年之首要周。

     

    JDK 针对 ISO 8601 提供的支持

    根据 ISO 8601 官方关于日历星期和日表示法的概念,2019.12.29-2020.1.4 是 2020 年之首要周。

    一般说来工作中,咱们可能有这样的急需:咱们盼望输入一个日期,下一场程序告诉我们,根据 ISO 8601 官方关于日历日期的概念,其一日子到底属于哪一年。

    比如我输入 2019-12-20,她告诉我是 2019;而我输入 2019-12-30 的时节,她告诉我是 2020。

    为了提供这样的多寡,Java 7 引入了「YYYY」表现一个新的日期模式来作为标识。

    采用「YYYY」表现标识,再通过 SimpleDateFormat 就足以得到一个日期所属的周属于哪一年了。

    故此,咱们通过代码可以检验:

         
    1. public class WeekYearTest { 
    2.  
    3.     public static void main(String[] args) { 
    4.  
    5.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 
    6.         SimpleDateFormat sdf1 = new SimpleDateFormat("YYYY"); 
    7.         System.out.println(sdf1.format(sdf.parse("2019-12-01"))); 
    8.         System.out.println(sdf1.format(sdf.parse("2019-12-30"))); 
    9.         System.out.println(sdf1.format(sdf.parse("2020-01-01"))); 
    10.     } 

    进出口结果为:

         
    1. 2019 
    2. 2020 
    3. 2020 

    可见, 2019-12-30 日因为属于 2020 年之首要周,故此返回的年度是 2020 年。

    而如果将「YYYY」转移「yyyy」的话,进出口结果就为:

         
    1. 2019 
    2. 2019 
    3. 2020 

    因为有这样的状况,故此我们常见开支的时节,如果把 y 写成了 Y,那就可能导致日期输出的结果不符合我们的预料。

    顶我们要表示日期的时节,永恒要使用 yyyy-MM-dd 而不是 YYYY-MM-dd ,这两头之返回结果大多数情况下都一样,但是极端情况就会有问题了。

    因为作者的 IDEA 官方安装了<阿里巴巴支付手册的软件>,故此在代码中采用「YYYY」的时节,IDEA 会弹出以下提示:

    好啦,大家快去排查下你的编码,有没有'YYYY-MM-dd'这种形式的编码吧,如果有之话,永恒要改掉哦!~

    【编纂推荐】

    1. Redis多极化高并发下的秒杀性能
    2. 迪斯尼宣布加入 OpenJDK 品种
    3. GitHub终于推出手机版App,富有开发者与用户互动
    4. 2019 OPPO 开发者大会亮点抢先看:“名将不会再有纯粹意义上的无绳电话机公司”
    5. Java 开发者需要研究 JDK,Linux 开发者需要研究 Kernel
    【义务编辑: 武晓燕 TEL:(010)68476606】

     

    分享到朋友圈 分享到微博
  • 手机
  • ISO
  • JDK
  • 相关推荐

    任正非:鸿蒙系统已上点,前途将把运用到手机、机械、电视机系列产品上

    2020-01-30 16:17:22

    让电影动漫统统变丝滑,480帧毫无卡顿,清华博士生开源插帧软件

    2020-01-29 19:35:17

    11款值得推荐的工具类小程序

    2020-01-29 19:34:57

    Copyright © 2005-2020 51CTO.COM 必发娱乐登入
    情节话题
    必发娱乐登入 移步 传感器 系统 安全 网络 必发娱乐登录 虚拟化 付出
    热门产品
    51CTO必发娱乐登录 51CTO高招 移步开发者服务联盟网+ 51CTO博客 WOT碰头会