学习java很痛苦

这些天我不再需要使用java.util.Date了,但是最近选择这样做,这让我想起了使用与Java Date关联的API的痛苦 。 在这篇文章中,我看了弃用的参数化Date构造函数的一些令人惊讶的API期望,该构造函数接受六个整数 。

在2016年,如果使用Java SE 8编写新代码,则Java开发人员很可能会使用Java 8的新Date / Time API,如果使用Java的版本,则可能会使用第三方Java日期/时间库(例如Joda-Time) 。 Java早于Java8。我选择最近在一个非常简单的基于Java的工具中使用Date ,我希望将它作为单个Java源代码文件交付(无需构建工具即可轻松编译),并且不依赖于外部的任何库。 Java SE。 此简单工具的目标部署环境是Java SE 7,因此不能选择Java 8 Date / Time API。

接受六个整数的Date构造函数的缺点之一是这六个整数之间的区别,并确保按正确的顺序提供它们。 即使强制执行正确的命令,指定月份和年份也会有一些细微的意外。 正确实例化Date对象的最简单方法也许是通过SimpleDateFormat 。 parse(String)或通过不建议使用的Date(long)构造函数接受从时期零开始的毫秒数。

我的第一个代码清单演示了一个用0小时,0分钟和0秒表示一个表示“ 2016年9月26日”的Date实例。 此代码清单使用String通过SimpleDateFormat.parse(String)实例化Date实例。

final SimpleDateFormat formatter = new SimpleDateFormat(DEFAULT_FORMAT);
final Date controlDate = formatter.parse(CONTROL_DATE_TIME_STR);
printDate("Control Date/Time", controlDate);

运行上述命令时,打印结果将达到预期效果,并且输出日期与为Date实例提供并分析的字符串匹配。

=============================================================
= Control Date/Time -> Mon Sep 26 00:00:00 MDT 2016
=============================================================

使用接受整数以表示Date实例的不同“字段”的Date构造函数可能会很诱人,但它们会带来前面提到的细微差别。

下一个代码清单显示了一种非常幼稚的方法来调用Date构造函数,该构造函数接受按以下顺序表示这些字段的六个整数:年,月,日期,小时,分钟,秒。

// This will NOT be the intended Date of 26 September 2016
// with 0 hours, 0 minutes, and 0 seconds because both the
// "month" and "year" parameters are NOT appropriate.
final Date naiveDate = new Date(2016, 9, 26, 0, 0, 0);
printDate("new Date(2016, 9, 26, 0, 0, 0)", naiveDate);

运行上述代码的输出与前面显示的“控制”案例没有相同的月份(10月而不是9月)或年份(不是2016年)。

=============================================================
= new Date(2016, 9, 26, 0, 0, 0) -> Thu Oct 26 00:00:00 MDT 3916
=============================================================

本月比我们预期的要晚(10月而不是9月),因为month参数是从零开始的参数,一月由0表示,九月由8而不是9表示。这是处理以下问题的最简单方法之一从零开始的月份,对Date构造函数的更可读的调用是为月份使用适当的java.util.Calendar字段。 下一个示例演示如何使用Calendar.SEPTEMBER进行此操作。

// This will NOT be the intended Date of 26 September 2016
// with 0 hours, 0 minutes, and 0 seconds because the
// "year" parameter is not correct.
final Date naiveDate = new Date(2016, Calendar.SEPTEMBER, 26, 0, 0, 0);
printDate("new Date(2016, Calendar.SEPTEMBER, 26, 0, 0, 0)", naiveDate);

刚刚列出的代码段修复了月份规范,但是年份仍然不正确,如下面显示的关联输出所示。

=============================================================
= new Date(2016, Calendar.SEPTEMBER, 26, 0, 0, 0) -> Tue Sep 26 00:00:00 MDT 3916
=============================================================

这一年仍然相距1900年(而不是2016年为3916年)。 这是因为决定将六整数Date构造函数的第一个整数参数指定为年份,减去1900年。因此,提供“ 2016”作为第一个参数,将年份指定为2016 + 1900 = 3916。要解决此问题,我们需要改为提供116(2016-1900)作为构造函数的第一个int参数。 为了使对此感到惊讶的普通人更容易理解,我喜欢将其字面编码为2016-1900,如下面的代码清单所示。

final Date date = new Date(2016-1900, Calendar.SEPTEMBER, 26, 0, 0, 0);
printDate("new Date(2016-1900, Calendar.SEPTEMBER, 26, 0, 0, 0)", date);

在使用从零开始的月份并将预期年份表示为当前年份减去1900的情况下,正确地实例化了Date ,如在下一个输出列表中所示。

=============================================================
= new Date(2016-1900, Calendar.SEPTEMBER, 26, 0, 0, 0) -> Mon Sep 26 00:00:00 MDT 2016
=============================================================

Date的Javadoc文档确实描述了这些细微差别,但这提醒人们,最好使用清晰,可理解的API,不需要注释中描述的细微差别。 Date(int,int,int,int,int,int)构造函数的Javadoc确实宣告,年需要减去1900,并且月份由0到11之间的整数表示。它还描述了为什么此六整数构造函数已弃用 :“从JDK版本1.1开始,由Calendar.set(年+ 1900,月,日期,小时,分钟,秒)或GregorianCalendar(年+ 1900,月,日期,小时,分钟,秒)代替。”

相似的六整数GregorianCalendar(int,int,int,int,int,int)构造函数没有被弃用,尽管它仍然期望从零开始的month参数,但是当证明证明时,它不希望它减去1900的实际年份。年参数。 当使用适当的Calendar month常数指定月份时,当可以在年份中传递2016年并且可以在月份中传递Calendar.SEPTEMBER时,API调用将更具可读性。

我现在很少直接使用Date类,以至于我忘记了它的细微差别,并且在极少数场合让我再次使用Date时必须重新学习它们。 因此,我将这些有关Date观察留给我自己。

  1. 如果使用Java 8+,请使用Java 8 Date / Time API。
  2. 如果使用Java之前的Java 8版本,请使用Joda-Time或其他改进的Java库。
  3. 如果无法使用Java 8或第三方库,请尽可能使用Calendar而不是Date ,尤其是用于实例化。
  4. 如果使用Date反正实例化Date使用任一SimpleDateFormat.parse(String)的方法或使用Date(long)来实例化Date因为历元零基于毫秒。
  5. 如果使用Date构造函数分别接受表示日期/时间分量的多个整数,请使用适当的Calendar month字段使API调用更具可读性,并考虑编写一个简单的构造器来“包装”对六整数构造函数的调用。

通过使用他人的API,我们可以学到很多有关什么使API有用且易于学习以及使API更加难以学习的知识。 希望这些经验教训将有助于我们编写自己的API。 这篇文章的重点是Date(int, int, int, int, int, int)构造函数,它提出了一些问题,这些问题导致API不够理想。 相同类型的多个参数可以轻松地乱序提供参数,而与提供年份和月份有关的“不自然”规则给客户端开发人员增加了负担,使他们不得不阅读Javadoc来理解这些不太明显的内容规则。

翻译自: https://www.javacodegeeks.com/2016/09/painful-reminder-java-date-nuances.html

学习java很痛苦

学习java很痛苦_Java日期细微的痛苦提醒相关推荐

  1. 学习java的步骤_java学习的基本步骤

    Java是一个通用的编程语言,其实可以干很多事,怎么学Java就看怎么用了.但有一些基本的步骤: 熟悉一种文本编辑器, 比如:Vim, Emacs, Notepad++, TextMate等.知道哪些 ...

  2. java时间规范化_Java日期时间使用总结

    一.Java中的日期概述 日期在Java中是一块非常复杂的内容,对于一个日期在不同的语言国别环境中,日期的国际化,日期和时间之间的转换,日期的加减运算,日期的展示格式都是非常复杂的问题. 在Java中 ...

  3. 每天学习java一小时_java再学感受 - 编程一小时的个人空间 - OSCHINA - 中文开源技术交流社区...

    首先的是,我买了一本新的有关于java的书,刚开始看,其实在此之前我已经学了一本java语法的书本,现在我买的这本书是我用来提升自己的java认知水平的,首先是对这本书的第一印象吧,里面的内容比较详细 ...

  4. java 格式化解析_java日期格式化、解析

    今天移植别人的通用工具类,涉及到了日期的格式化.解析,学习结果记录如下. 日期的格式化器普用的是SimpleDateFormat,它继承了了DateFormat.SimpleDateFormat为用户 ...

  5. java date 操作_java日期操作-java Date-java Calendar-嗨客网

    Java日期操作类教程 在生产开发过程中,会用到和时间相关的信息,所以 JavaDate类 说明 Date 类是定义时间对象的一个类,它是一个较为简单的操作类. 案例 package com.haic ...

  6. java当月最后一天_Java日期循环,Java获取当月的第一天和最后一天 | 学步园

    1.Java日期循环 SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd"); String dateStr1 ...

  7. java timestamp 格式化_java日期处理(Timestamp)

    要写一些与数据库连接时的日期处理,pstmt.setDate()的类型是java.sql.Date类型,这种符合规范的类型其实并没有把时分秒存进数据库,所以存取时就应该用setTimestamp()或 ...

  8. java 时间类_Java日期和时间类简介

    Java 的日期和时间类位于 java.util 包中.利用日期时间类提供的方法,可以获取当前的日期和时间,创建日期和时间参数,计算和比较时间. Date 类 Date 类是 Java 中的日期时间类 ...

  9. java 公元前时间_Java日期和时间类简介

    Java 的日期和时间类位于 java.util 包中.利用日期时间类提供的方法,可以获取当前的日期和时间,创建日期和时间参数,计算和比较时间. Date 类 Date 类是 Java 中的日期时间类 ...

最新文章

  1. 广汽研究院BMS软件工程师_八大高手齐聚CATIA决赛,3人获“广汽技术创新能手”...
  2. Oracle入门(十四.20)之创建DML触发器:第一部分
  3. mysql多实例脚本_mysql多实例脚本
  4. 手把手教你使用Pandas读取结构化数据
  5. [php]php总结(2)
  6. javascript:使用canvas绘图2D图形
  7. DT时代释放金融数据价值,驱动金融商业裂变
  8. zabbix利用traceroute命令监控主备链路状态
  9. 【Ian Goodfellow 强推】GAN 进展跟踪 10 大论文(附下载)
  10. python实现时间戳和时间格式转换以及当前时间,特定时间的前后偏移
  11. 海康威视错误代码0xf_技术讨论 | 看我如何重置海康威视IP摄像机的管理员密码...
  12. 西门子plc语句表是c语言吗,分享精心整理的西门子PLC指令表
  13. 修己,以清心为要。涉世,以慎言为先。
  14. stm32cubeMX学习十八、SD卡虚拟U盘实验
  15. 怎样将excel表格导入天正_怎样把天正里面的表格转换到Excel里面?
  16. android2.3.5中阿拉伯文字符显示顺序不是从右至左显示
  17. 逻辑与() 逻辑或(||)
  18. R7 5800H和i5 11300H参数对比差距大不大
  19. Three.js 教程
  20. 如何分别在Android、iOS、Windows Phone三大平台进行“触摸屏”开发?

热门文章

  1. YbtOJ-变量观测【鸽笼原理】
  2. CF39C-Moon Craters【dp】
  3. P6628-[省选联考 2020 B 卷] 丁香之路【欧拉回路,最小生成树】
  4. YbtOJ#652-集合比较【Treap】
  5. jzoj4739-[雅礼联考GDOI2017模拟9.2]Ztxz16学图论【LCT,树状数组】
  6. P2414-[NOI2011]阿狸的打字机【AC自动机,树状数组】
  7. 欢乐纪中某A组赛【2019.7.11】
  8. ssl2345-繁忙的都市
  9. AtCoder Beginner Contest 178 总结
  10. 跟我学 Java 8 新特性之 Stream 流(三)缩减操作