这些天,我不再需要使用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 Date Nuances的痛苦提醒相关推荐

  1. 学习java很痛苦_Java日期细微的痛苦提醒

    学习java很痛苦 这些天我不再需要使用java.util.Date了,但是最近选择这样做,这让我想起了使用与Java Date关联的API的痛苦 . 在这篇文章中,我看了弃用的参数化Date构造函数 ...

  2. java str2date,java date类与string类实例代码分享

    Date类用来指定日期和时间,其构造函数及常用方法如下: publicDate() 从当前时间构造日期时间对象. publicStringtoString() 转换成字符串. publiclongge ...

  3. Java Date Time 教程

    原文链接 作者:Jakob Jenkov  译者:魏嘉鹏 目录 Java 8 Date Time API Java 7 Date Time API 当你初次尝试弄明白怎么去使用Java的date ti ...

  4. java 日期 解析_Java日期解析(Java DATE Parsing)

    Java日期解析(Java DATE Parsing) 我有一个java.util.Date的愚蠢问题. 我有这一行代码,但我不明白为什么这个日期是用这种格式无法解析的. public class T ...

  5. java Date获取 年月日时分秒

    转载自   java Date获取 年月日时分秒 package com.util;import java.text.DateFormat; import java.util.Calendar; im ...

  6. Java Date Time 教程-java.sql.Date

    Java的java.sql.Date类在JDBC API中被使用.如果你需要在java.sql.PreparedStatement上设置日期或者从java.sql.ResultSet获取日期,你将会和 ...

  7. java date只保存年月日_java date 只保留年月日

    java date 只保留年月日 [2021-01-30 22:42:23]  简介: php去除nbsp的方法:首先创建一个PHP代码示例文件:然后通过"preg_replace(&quo ...

  8. java date转换timestamp_Java Date转Timestamp

    Java Date转Timestamp 1 Java Date转Timestamp的介绍 我们可以使用java.sql.Timestamp类的构造函数在Java中将Date转换为Timestamp. ...

  9. Java Date getTime()方法具有什么功能呢?

    转自: Java Date getTime()方法具有什么功能呢? 下文笔者讲述java中Date实例对象之getTime()方法的功能简介说明,如下所示: Date getTime()方法功能简介说 ...

最新文章

  1. angularjs ngTable -Custom filter template-calendar
  2. Phalcon和YII的优点
  3. 理解矩阵 的一些评论
  4. 【ARM】ARM汇编程序设计(三) 循环结构
  5. linux进程cpu资源分配命令nice,renice,taskset
  6. 手机拍照显示_最值得购买的4款5G手机,每款都有一技之长,有你在用的吗?
  7. ASA 9.21 in Vmware Workstation 10
  8. 罚款200元的交通违法行为
  9. [react] 你对immutable有了解吗?它有什么作用?
  10. echarts源码:图标类插件开发
  11. 关于机器学习 Machine Learning中loss函数参数正则化的一点思考
  12. libcurl 发送邮件_libcurl smtp发送邮件附件大小限制问题
  13. 第二十二篇 定义函数的三种形式以及函数的返回值
  14. Hbuilder如何创建并运行Vue项目
  15. 【window操作系统下Github版本的回滚问题】
  16. 详解《云原生架构白皮书》,附下载链接
  17. 质疑江民电脑保护系统,涉嫌抄袭
  18. Thinkpad R60 驱动下载及安装方法 for windows XP
  19. windows 10 账号密码策略及规则
  20. c语言51单片机调节led亮度,51单片机中用PWM控制LED亮度调节

热门文章

  1. 最新后端架构师技术图谱
  2. Tomcat的web项目部署方式
  3. java中的break与continue用法
  4. 张老师讲Python~
  5. 20级、19级 | 一天一瞬间!【日更】
  6. ssh(Spring+Spring mvc+hibernate)——applicationContext.xml
  7. linux将光驱挂载到目录下,Linux操作系统下关于光驱的挂载
  8. java design按钮_DesignJava 设计模式,讲述 的各种 方便在项目中进行 框架结构 Develop 238万源代码下载- www.pudn.com...
  9. oxyen eclipse 启动 报错 se启动提示javaw.exe in your current PATH、No java virtual machine
  10. python3多线程第三方库_Python3 多线程