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

学习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很痛苦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/335660.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何理解程序保存数据就是输出,读取数据就是输入的含义(程序中输入input/输出output的含义如何理解)

文章目录程序是如何保存数据的为什么保存数据的类名称都表达一种输出意思,例如:output程序如何读取数据为什么读取数据的类名称都表达一种输入意思,例如:input总结程序是如何保存数据的 对象的序列化就是持久化,就是把…

hazelcast_HazelCast的Spring-Boot和Cache抽象

hazelcast以前,我们是使用spring提供的默认Cache Manager来开始Spring Cache抽象的。 尽管这种方法可能适合我们对简单应用程序的需求,但是在出现复杂问题的情况下,我们需要使用具有更多功能的其他工具。 Hazelcast就是其中之一。 当涉及到基…

eclipse preference没有server_Java Web开发的前期准备工作,部署Tomcat服务器和Server环境创建...

Java Web: 顾名思义,就是用Java的方式来解决Web开发,我也不讲太多的理论问题,直接将如何上手来进行Java Web开发。那么,我们一般进行Java Web开发,可以使用的工具很多,我这里使用eclipse。选择eclipse的版本…

类似TH养车的电商系统设计思路

平台运营模式B2CO2O,汽车用品全部平台自营,允许线下汽车服务门店入驻,门店运营模式O2O汽车服务全部标准化,由平台创建和维护服务商品根据商品实际使用需要关联服务商品线下汽车服务门店根据自己实际运营的情况选择有能力提供的汽车…

java int不将0忽略_Java微服务:蛋糕是骗人的,但您不能忽略它

java int不将0忽略构建微服务实际上意味着什么? 通过微服务框架的眼光回答 忽略微服务的趋势已变得不可能。 有些人会说这只是另一个难以忍受的流行语,而另一些人会背诵打破巨石的优势或采取逆势方法并关注负面因素。 在本文中,我们将全面了…

4怎么放大字体_Word字体怎么放大?简单教你几招轻松搞定

一般情况下我们都会选择用Word编辑文章。文章编辑完成之后我们通常会对文章进行排版。在排版的过程中如果我们需要将Word字体放大该怎么办呢?下面我就来教大家几个Word字体放大的小技巧,一起来看看吧。下面以放大“字体演示”为例为大家演示操作过程。一…

js splice坑_JavaScript的splice()方法在for循环中使用可能会遇到的坑!!!

在我们日常敲代码的时候,常常会用到splice()方法来删除数组中的元素(就是以截取的方式),因为它会直接对数组进行修改。在使用splice之前,必备条件是,要先有一个数组。var arr new Array(1,2,3,4,5); // 初始化一个数组var delete…

java crud_Java 8流中的数据库CRUD操作

java crud在开始使用新工具时要克服的最大障碍是让您着手处理小事情。 到目前为止,您可能对新的Java 8 Stream API的工作方式充满信心,但是您可能尚未将其用于数据库查询。 为了帮助您开始使用Stream API创建,修改和读取SQL数据库&#xff0c…

HH SaaS电商系统的线下服务商品库存和采购设计

线下服务商品库存和采购整体思路 线下服务商品直接在商品编辑页面编辑库存数量即可,服务端直接修改服务商品的销售库存即可线下服务商品则不必生成采购单和出库单线下服务商品无需发货,但是需要商家核销服务权益

HH SaaS电商系统的仓储系统设计

如果商城或者店铺选择开通了供应系统,那么就必然有仓储系统,如果选择不开通供应系统,可以独立开通仓储系统 未开通仓储系统 商城和店铺如果不需要仓储系统,那么商城和店铺就不会有仓储模块,所以无法手动创建库存单据…

wps如何将字体竖着排列_WPS文字中怎么竖着打字?wps文字竖排的设置方法介绍

wps中怎么样才能让文字竖着写啊?WPS现在的应用比较多,其实WPS文字和Word相差不过,都是一个办公软件,我们有时候在编辑的时候需要把文字竖排,那么,wps文字怎么竖排呢?接下来脚本之家小编就给大家…

cloudfoundry_在Cloudfoundry上部署RESTful服务

cloudfoundry在本文中,我们将使用Pivotal Cloud Foundry(PCF)开发人员在Cloudfoundry上部署RESTful服务。 由于创建静态Web服务不是本文的一部分,因此我已经创建了employee-service ,它具有静态后端,可以从…

HH SaaS电商系统的线上服务商品库存和采购设计

文章目录线上服务商品库存和采购整体思路线上服务商品的采购单状态线上服务商品的出库单状态商家完成服务线上服务商品库存和采购整体思路 线上服务商品直接在商品编辑页面编辑库存数量即可,服务端自动生成类型为“调整入库”的入库单和类型为“调整出库”的出库单…

arm linux gif 显示_100ASK_IMX6ULL arm板子如何显示图片、汉字、划线、背景色

最近在研究基于imx6ull开发板,想让开发板支持显示图片、字符串、背景色的功能。 操作的主要步骤如下:移植设备树和驱动移植libjpeg库编写测试程序一、移植设备树和驱动开发板原厂SDK已经移植了lcd对应的设备树和驱动。具体可以参考韦东山老师的文章https…

动态代码生成 静态代码生成_将速度提升到自己的个人代码生成器中

动态代码生成 静态代码生成Speedment是一个开源工具包 ,可用于生成Java实体和管理器以与数据库进行通信。 如果您需要域模型的对象关系映射,那么这很好,但是在某些情况下,您可能希望使用数据库作为模板来生成完全不同的东西。 在本…

HH SaaS电商系统的库存调整单设计

为了更加灵活地变动商品的库存,以及其它原因导致系统库存数和实际库存数不一致,可以通过库存调整单进行校正。 简简单单设计,没有状态管理,不需要通过审核,直接变更库存数~ 原型设计 库存调整单列表 库存调整单详情…

mysql优化 运维_MySQL运维---MySQL优化

一、优化1、优化的角度2、优化的方向3、数据库优化思路4、MySQL优化介绍5、优化工具介绍二、操作系统优化1、top命令1)CPU2)内存3)slab分配器---Linux内存4)page cache5)swap分区修改成不使用swap分区:永久生效,修改配置文件:2、大页内存机制…

微基准测试 r_在您的构建过程中添加微基准测试

微基准测试 r介绍 作为一个行业,我们正在采用更高的透明度和更可预测的构建过程,以降低构建软件的风险。 持续交付的核心原则之一是通过反馈循环收集反馈。 在Dev9中 ,我们采用了与CD原则一致的“ 先知道 ”原则,这意味着我们&…

HH SaaS电商系统服务商品在移动端下单结算的交互设计

服务商品只能单独下单购买,不允许加入购物车我们知道服务商品有三种形式:线上服务、到店服务、上门服务,因为不同服务形式买家和卖家所需的信息不同,所以交互界面也会不同,前端需要判断当前服务商品的服务形式&#xf…

linux 远程备份mysql数据库_使用脚本自动化远程备份MySQL数据库

通常情况下、MySQL都需要备份,备份的方法有很多种。下面是我用脚本配合计划任务完成的自动备份远程的数据库。一、 确认备份方案:备份机:ip192.168.8.51数据库服务器:ip192.168.8.46备份的内容:对mysql的studydb、cour…