2020年来临之前,日期格式化操作也为程序员准备了一个跨年级别的bug,不知你的系统是否遇到?

临近2020年元旦的几天,不少网站出现了类似2020/12/29,2020/12/30,2020/12/31这样的日期显示。神奇不?就连微信的提供的订阅号助手工具都出现了这样的错误。

下面两张图是本公众号“程序新视界”在12月31日订阅号助手助手中的截图。

新增粉丝时间显示的部分内容。

评论区的时间显示的部分内容。

上图中,新增粉丝显示的时间和评论的时间均为“2020/12/31”。那么,下面我们就来分析一下出现此bug的原因。实例胜千言,先用示例还原一下此bug。

示例一,还原示例:

public class DateFormatBug {    public static void main(String[] args) throws ParseException {        // 示例一        printBugDate();    }    private static void printBugDate() throws ParseException {        SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");        Date date = sdf.parse("2020-1-1 13:12:12");        System.out.println(date);        String dateStr = sdf.format(date);        System.out.println(dateStr);    }}

猜猜第一行和第二行打印的结果分别是什么?如果猜对一个说明很聪明,因为上面已经说了,此实例为还原bug。

打印日志为:

Sun Dec 29 13:12:12 CST 20192020-12-29 13:12:12

神奇不?把字符串“2020-1-1 13:12:12”解析成日期打印出来竟然成2019年12月29日了!!!然后再对日期进行处理竟然变成2020-12-29日了!彻底乱套了,我们想要的是2020-1-1的日期啊。

示例二,延伸示例:

private static void printBugDateExtend() throws ParseException {    SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");    Date date = sdf.parse("2019-12-31 13:12:12");    System.out.println(date);    String dateStr = sdf.format(date);    System.out.println(dateStr);}

这次只是把日期从2020-1-1改为2019-12-31,猜猜打印结果是什么?保证你猜不到。下面是打印结果:

Sun Dec 30 13:12:12 CST 20182019-12-30 13:12:12

2018年12月30?这次连年份都错了。

好了,不卖关子了,如果你的IDE上安装的有阿里巴巴操作规范手册的插件。你会发现“YYYY-MM-dd HH:mm:ss”上面已经有提示信息了。同样,如果你打开新版(华山版)阿里巴巴Java开发手册,对此问题已经进行了明确的说明了。

那么,哪里可以获得新版的《阿里巴巴Java开发手册》?关注公众号“程序新视界”的朋友,只需回复“005”即可获得PDF版本。新的一年,没事看看大厂的开发手册,借鉴一下经验,避免踩坑也是不错的。当然,关注公众号持续学习也是另外一种不错的选择。

同时,也可参看javadoc中对week-based-year的说明,相关链接如下:https://docs.oracle.com/javase/8/docs/api/java/time/temporal/WeekFields.html

A week is defined by:(1) The first day-of-week. For example, the ISO-8601 standard considers Monday to be the first day-of-week.(2) The minimal number of days in the first week. For example, the ISO-8601 standard counts the first week as needing at least 4 days.Together these two values allow a year or month to be divided into weeks.

总结一下就是:在基于周的年份中,每周仅属于某一年。一年中的第1周要求从一周的第一天开始,并且天数要大于4天(the minimum number of days),所以跨年周具体是哪一年还得看具体情况。

不过无论怎样,最好的方法就是避免使用大写的“Y”来代表年份。

尽信书不如无书,我们将代码中“Y”修改为“y”,再执行一遍看看效果。

private static void printDate() throws ParseException {    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    Date date = sdf.parse("2020-1-1 13:12:12");    System.out.println(date);    String dateStr = sdf.format(date);    System.out.println(dateStr);}private static void printDateExtend() throws ParseException {    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    Date date = sdf.parse("2019-12-31 13:12:12");    System.out.println(date);    String dateStr = sdf.format(date);    System.out.println(dateStr);}

打印结果显示如下:

Wed Jan 01 13:12:12 CST 20202020-01-01 13:12:12Tue Dec 31 13:12:12 CST 20192019-12-31 13:12:12

很显然,这个跨年bug被修复了。

经过这个问题,我们是否会思考一个问题:高手与新手的差不在哪里?或许上面的问题就能够回答,同样是日期格式化,在正常情况下两种写法都可正常运行,无法区分高手与新手。而只有在某时某刻某些极端情况下才能看出高手之高。

那么高手是从哪里来的?是从坑中跳出来的。或许他比你早掉进去早出来了,或许他博览群书有那么一次“不期而遇”,也或许就是像你现在一样看到这篇文章。

本文首发来自微信公众号:程序新视界。一个软实力、硬技术同步学习的平台。

oracle 日期格式化_日期格式化跨年bug,是否与你不期而遇?相关推荐

  1. java 解析日期格式_日期/时间格式/解析,Java 8样式

    java 解析日期格式 自Java 几乎 开始以来,Java开发人员就通过java.util.Date类(自JDK 1.0起)和java.util.Calendar类(自JDK 1.1起 )来处理日期 ...

  2. dateutil 日期计算_日期时间 - 日期时间工具-DateUtil - 《Hutool 参考文档》 - 书栈网 · BookStack...

    日期时间工具-DateUtil 由来 考虑到Java本身对日期时间的支持有限,并且Date和Calendar对象的并存导致各种方法使用混乱和复杂,故使用此工具类做了封装.这其中的封装主要是日期和字符串 ...

  3. oracle 日期排序_日期居然用字符串保存?我笑了

    点击上方"后端技术精选",选择"置顶公众号" 技术文章第一时间送达! 作者:张乘辉 来自:后端进阶 我发现数据库有些日期居然用字符串保存?于是跟几个小伙伴讨论了 ...

  4. mysql 日期减法_日期格式处理的几种方法

    转眼2021都快过了一个月了,不知道大家是否在写日期的时候还是会不自觉地写下"2020-XX-XX"? 日常的工作和生活中,日期的书写随处可见,对分析师而言,日期和时间的处理更如一 ...

  5. layui 日期重置_日期时间插件--日期时间组件文档 - layui.laydate

    样式: /*这里我引的是我本地的js*/ layui.use('laydate', function () { var laydate = layui.laydate; var start = { / ...

  6. getdate 日期间隔_日期getDate()方法以及JavaScript中的示例

    getdate 日期间隔 JavaScript Date getDate()方法 (JavaScript Date getDate() method) getDate() method is a Da ...

  7. 多选月份的日期选择器_日期多选,月份多选,年份多选,季度多选,日历区间选择...

    年月日季度日历多选设置初始值demo /*季度样式修改*/.datepicker-cell-block{display:block;width:100%;height:40px;line-height ...

  8. oracle将字符串的日期格式化,oracle格式化字符串 oracle 怎么把字符串转换成日期...

    Oracle数据库中如何将字符串格式化为日期 可以用 to_date('日期类型字符串','要转化的日期类型')函数进行日期格式转换 sql:select to_date('1990-12-12 12 ...

  9. android java 时间格式化_(Java / Android)计算两个日期之间的日期,并以特定格式显示结果...

    我试图在2个日期之间计算日期如下: >获取当前日期 >获取过去或未来的日期 >计算不同的差异. 1和否2 >以下列格式显示日期 >如果结果是在过去(2天前)或将来(在2天 ...

最新文章

  1. 网站本地测试安装流程
  2. TOJ 1702.A Knight's Journey
  3. @Async的异步任务多起来了,如何配置多个线程池来隔离任务?
  4. jQuery给css增加!important
  5. css提取页面元素唯一性_一日一技:爬虫如何正确从网页中提取伪元素?
  6. SAP Spartacus使用到的技术栈
  7. 两个富翁打赌_打赌您无法解决这个Google面试问题。
  8. Vue手动封装实现一个五星评价得效果
  9. 发生系统错误53_SAP那些事-推理剧-36-奇怪的付款清账(F-53)报错“TABLE_INVALID_INDEX”...
  10. 好男人往往找不到女朋友
  11. android循环滚动textview,Android 循环上下滚动
  12. for循环中++i 和 i++ 的区别
  13. led灯条维修_海尔液晶电视LD32U3100背光通病维修(非灯条问题)
  14. Linux C/C++开发、嵌入式软件开发面试记录 ( 四)
  15. Centos 关闭密码字典检查
  16. 十分钟快速自制CMSIS_DAP仿真器~将ST-LINK-V2变身DAP仿真器~
  17. 淘宝/天猫上传图片到淘宝 API
  18. MIT License探讨
  19. ubuntu 20.04 耳机没有声音
  20. 2019年十大让人欲罢不能的消费潮流 | 财见年终观察

热门文章

  1. STL源码剖析-map
  2. php 最大限制,php – ModSecurity最大发布限制(PCRE限制错误)
  3. centos7 cuda测试_CentOS 7 安装cuda环境
  4. 多目标优化算法_阿里提出多目标优化全新算法框架,同时提升电商GMV和CTR
  5. java 中aop 博客园_Java 10.Spring--AOP编程
  6. java构建大根堆_构建大根堆
  7. 物资管理系统c语言运行程序,C语言实现仓库物资管理系统.pdf
  8. redhat 6安装mysql5.7_RedHat6.5/CentOS6.5安装Mysql5.7.20的教程详解
  9. Git从现有仓库新建干净版本(清除版本commit记录)
  10. centos6下安装php7的memcached扩展