- 浏览: 1048214 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (1441)
- 软件思想&演讲 (9)
- 行业常识 (250)
- 时时疑问 (5)
- java/guava/python/php/ruby/R/scala/groovy (213)
- struct/spring/springmvc (37)
- mybatis/hibernate/JPA (10)
- mysql/oracle/sqlserver/db2/mongdb/redis/neo4j/GreenPlum/Teradata/hsqldb/Derby/sakila (268)
- js/jquery/jqueryUi/jqueryEaseyUI/extjs/angulrJs/react/es6/grunt/zepto/raphael (81)
- ZMQ/RabbitMQ/ActiveMQ/JMS/kafka (17)
- lucene/solr/nuth/elasticsearch/MG4J (167)
- html/css/ionic/nodejs/bootstrap (19)
- Linux/shell/centos (56)
- cvs/svn/git/sourceTree/gradle/ant/maven/mantis/docker/Kubernetes (26)
- sonatype nexus (1)
- tomcat/jetty/netty/jboss (9)
- 工具 (17)
- ETL/SPASS/MATLAB/RapidMiner/weka/kettle/DataX/Kylin (11)
- hadoop/spark/Hbase/Hive/pig/Zookeeper/HAWQ/cloudera/Impala/Oozie (190)
- ios/swift/android (9)
- 机器学习&算法&大数据 (18)
- Mesos是Apache下的开源分布式资源管理框架 (1)
- echarts/d3/highCharts/tableau (1)
- 行业技能图谱 (1)
- 大数据可视化 (2)
- tornado/ansible/twisted (2)
- Nagios/Cacti/Zabbix (0)
- eclipse/intellijIDEA/webstorm (5)
- cvs/svn/git/sourceTree/gradle/jira/bitbucket (4)
- jsp/jsf/flex/ZKoss (0)
- 测试技术 (2)
- splunk/flunm (2)
- 高并发/大数据量 (1)
- freemarker/vector/thymeleaf (1)
- docker/Kubernetes (2)
- dubbo/ESB/dubboX/wso2 (2)
最新评论
一般来说,用Calendar做日期处理的时候,都习惯于使用add方法:
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.SECOND, 1);
最近代码Review的时候看到有人用set方法来做日期的处理:
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + month);
于是第一时间跳出来,义正词严的告诉他写错了,可惜马上就被BS回来了,因为见下面的测试代码:
Calendar cal = Calendar.getInstance();
cal.set(2009, 02, 15);
Date testDate = cal.getTime();
System.out.println(testDate);
Calendar calendar = Calendar.getInstance();
calendar.setTime(testDate);
calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
Date testDate2 = calendar.getTime();
System.out.println(testDate2);
输出结果:
Sun Mar 15 11:21:18 CST 2009
Wed Apr 15 11:21:18 CST 2009
也就是说,set方法也可以用于字段操作!!
好在我是个勇于承认错误的人,在道歉后,得到了对方的原谅,但是心中一直无法接受这个事实,JDK也太土了吧,设计这么两个方法难道就没有任何区别吗?那还要add方法干吗?
带着上面的问题,今天又开始了代码Review,越想越想不通,没道理啊,算了,查查JDK文档吧,下面是JDK中Calendar类的注释:
可以使用三种方法更改日历字段:set()、add() 和 roll()。
set(f, value) 将日历字段 f 更改为 value。此外,它设置了一个内部成员变量,以指示日历字段 f 已经被更改。尽管日历字段 f 是立即更改的,但是直到下次调用 get()、getTime()、getTimeInMillis()、add() 或 roll() 时才会重新计算日历的时间值(以毫秒为单位)。因此,多次调用 set() 不会触发多次不必要的计算。使用 set() 更改日历字段的结果是,其他日历字段也可能发生更改,这取决于日历字段、日历字段值和日历系统。此外,在重新计算日历字段之后,get(f) 没必要通过调用 set 方法返回 value 集合。具体细节是通过具体的日历类确定的。
示例:假定 GregorianCalendar 最初被设置为 1999 年 8 月 31 日。调用 set(Calendar.MONTH, Calendar.SEPTEMBER) 将该日期设置为 1999 年 9 月 31 日。如果随后调用 getTime(),那么这是解析 1999 年 10 月 1 日的一个暂时内部表示。但是,在调用 getTime() 之前调用 set(Calendar.DAY_OF_MONTH, 30) 会将该日期设置为 1999 年 9 月 30 日,因为在调用 set() 之后没有发生重新计算。
add(f, delta) 将 delta 添加到 f 字段中。这等同于调用 set(f, get(f) + delta),但要带以下两个调整:
Add 规则 1。调用后 f 字段的值减去调用前 f 字段的值等于 delta,以字段 f 中发生的任何溢出为模。溢出发生在字段值超出其范围时,结果,下一个更大的字段会递增或递减,并将字段值调整回其范围内。
Add 规则 2。如果期望某一个更小的字段是不变的,但让它等于以前的值是不可能的,因为在字段 f 发生更改之后,或者在出现其他约束之后,比如时区偏移量发生更改,它的最大值和最小值也在发生更改,然后它的值被调整为尽量接近于所期望的值。更小的字段表示一个更小的时间单元。HOUR 是一个比 DAY_OF_MONTH 小的字段。对于不期望是不变字段的更小字段,无需进行任何调整。日历系统会确定期望不变的那些字段。
此外,与 set() 不同,add() 强迫日历系统立即重新计算日历的毫秒数和所有字段。
示例:假定 GregorianCalendar 最初被设置为 1999 年 8 月 31 日。调用 add(Calendar.MONTH, 13) 将日历设置为 2000 年 9 月 30 日。Add 规则 1 将 MONTH 字段设置为 September,因为向 August 添加 13 个月得出的就是下一年的 September。因为在 GregorianCalendar 中,DAY_OF_MONTH 不可能是 9 月 31 日,所以 add 规则 2 将 DAY_OF_MONTH 设置为 30,即最可能的值。尽管它是一个更小的字段,但不能根据规则 2 调整 DAY_OF_WEEK,因为在 GregorianCalendar 中的月份发生变化时,该值也需要发生变化。
roll(f, delta) 将 delta 添加到 f 字段中,但不更改更大的字段。这等同于调用 add(f, delta),但要带以下调整:
Roll 规则。在完成调用后,更大的字段无变化。更大的字段表示一个更大的时间单元。DAY_OF_MONTH 是一个比 HOUR 大的字段。
示例:请参阅 GregorianCalendar.roll(int, int)。
使用模型。为了帮助理解 add() 和 roll() 的行为,假定有一个用户界面组件,它带有用于月、日、年和底层 GregorianCalendar 的递增或递减按钮。如果从界面上读取的日期为 1999 年 1 月 31 日,并且用户按下月份的递增按钮,那么应该得到什么?如果底层实现使用 set(),那么可以将该日期读为 1999 年 3 月 3 日。更好的结果是 1999 年 2 月 28 日。此外,如果用户再次按下月份的递增按钮,那么该日期应该读为 1999 年 3 月 31 日,而不是 1999 年 3 月 28 日。通过保存原始日期并使用 add() 或 roll(),根据是否会影响更大的字段,用户界面可以像大多数用户所期望的那样运行。
仔细研究上述注释,终于发现了一丝蛛丝马迹,add方法跟set还是有区别的,应该是在自然日的处理上有所不同,于是有了下面的代码:
Calendar cal = Calendar.getInstance();
cal.set(2009, 02, 31);
Date testDate = cal.getTime();
System.out.println(testDate);
Calendar cal1 = Calendar.getInstance();
cal1.setTime(testDate);
cal1.add(Calendar.MONTH, 1);
Date testDate1 = cal1.getTime();
System.out.println(testDate1);
输出如下:
Tue Mar 31 11:27:41 CST 2009
Thu Apr 30 11:27:41 CST 2009
OK,结论出来了,add方法会处理自然月的增减来处理日期部分,set方法却只是当成30天来处理。事实证明原来的感觉是对的,希望以后少碰到类似错误!!
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.SECOND, 1);
最近代码Review的时候看到有人用set方法来做日期的处理:
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + month);
于是第一时间跳出来,义正词严的告诉他写错了,可惜马上就被BS回来了,因为见下面的测试代码:
Calendar cal = Calendar.getInstance();
cal.set(2009, 02, 15);
Date testDate = cal.getTime();
System.out.println(testDate);
Calendar calendar = Calendar.getInstance();
calendar.setTime(testDate);
calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
Date testDate2 = calendar.getTime();
System.out.println(testDate2);
输出结果:
Sun Mar 15 11:21:18 CST 2009
Wed Apr 15 11:21:18 CST 2009
也就是说,set方法也可以用于字段操作!!
好在我是个勇于承认错误的人,在道歉后,得到了对方的原谅,但是心中一直无法接受这个事实,JDK也太土了吧,设计这么两个方法难道就没有任何区别吗?那还要add方法干吗?
带着上面的问题,今天又开始了代码Review,越想越想不通,没道理啊,算了,查查JDK文档吧,下面是JDK中Calendar类的注释:
可以使用三种方法更改日历字段:set()、add() 和 roll()。
set(f, value) 将日历字段 f 更改为 value。此外,它设置了一个内部成员变量,以指示日历字段 f 已经被更改。尽管日历字段 f 是立即更改的,但是直到下次调用 get()、getTime()、getTimeInMillis()、add() 或 roll() 时才会重新计算日历的时间值(以毫秒为单位)。因此,多次调用 set() 不会触发多次不必要的计算。使用 set() 更改日历字段的结果是,其他日历字段也可能发生更改,这取决于日历字段、日历字段值和日历系统。此外,在重新计算日历字段之后,get(f) 没必要通过调用 set 方法返回 value 集合。具体细节是通过具体的日历类确定的。
示例:假定 GregorianCalendar 最初被设置为 1999 年 8 月 31 日。调用 set(Calendar.MONTH, Calendar.SEPTEMBER) 将该日期设置为 1999 年 9 月 31 日。如果随后调用 getTime(),那么这是解析 1999 年 10 月 1 日的一个暂时内部表示。但是,在调用 getTime() 之前调用 set(Calendar.DAY_OF_MONTH, 30) 会将该日期设置为 1999 年 9 月 30 日,因为在调用 set() 之后没有发生重新计算。
add(f, delta) 将 delta 添加到 f 字段中。这等同于调用 set(f, get(f) + delta),但要带以下两个调整:
Add 规则 1。调用后 f 字段的值减去调用前 f 字段的值等于 delta,以字段 f 中发生的任何溢出为模。溢出发生在字段值超出其范围时,结果,下一个更大的字段会递增或递减,并将字段值调整回其范围内。
Add 规则 2。如果期望某一个更小的字段是不变的,但让它等于以前的值是不可能的,因为在字段 f 发生更改之后,或者在出现其他约束之后,比如时区偏移量发生更改,它的最大值和最小值也在发生更改,然后它的值被调整为尽量接近于所期望的值。更小的字段表示一个更小的时间单元。HOUR 是一个比 DAY_OF_MONTH 小的字段。对于不期望是不变字段的更小字段,无需进行任何调整。日历系统会确定期望不变的那些字段。
此外,与 set() 不同,add() 强迫日历系统立即重新计算日历的毫秒数和所有字段。
示例:假定 GregorianCalendar 最初被设置为 1999 年 8 月 31 日。调用 add(Calendar.MONTH, 13) 将日历设置为 2000 年 9 月 30 日。Add 规则 1 将 MONTH 字段设置为 September,因为向 August 添加 13 个月得出的就是下一年的 September。因为在 GregorianCalendar 中,DAY_OF_MONTH 不可能是 9 月 31 日,所以 add 规则 2 将 DAY_OF_MONTH 设置为 30,即最可能的值。尽管它是一个更小的字段,但不能根据规则 2 调整 DAY_OF_WEEK,因为在 GregorianCalendar 中的月份发生变化时,该值也需要发生变化。
roll(f, delta) 将 delta 添加到 f 字段中,但不更改更大的字段。这等同于调用 add(f, delta),但要带以下调整:
Roll 规则。在完成调用后,更大的字段无变化。更大的字段表示一个更大的时间单元。DAY_OF_MONTH 是一个比 HOUR 大的字段。
示例:请参阅 GregorianCalendar.roll(int, int)。
使用模型。为了帮助理解 add() 和 roll() 的行为,假定有一个用户界面组件,它带有用于月、日、年和底层 GregorianCalendar 的递增或递减按钮。如果从界面上读取的日期为 1999 年 1 月 31 日,并且用户按下月份的递增按钮,那么应该得到什么?如果底层实现使用 set(),那么可以将该日期读为 1999 年 3 月 3 日。更好的结果是 1999 年 2 月 28 日。此外,如果用户再次按下月份的递增按钮,那么该日期应该读为 1999 年 3 月 31 日,而不是 1999 年 3 月 28 日。通过保存原始日期并使用 add() 或 roll(),根据是否会影响更大的字段,用户界面可以像大多数用户所期望的那样运行。
仔细研究上述注释,终于发现了一丝蛛丝马迹,add方法跟set还是有区别的,应该是在自然日的处理上有所不同,于是有了下面的代码:
Calendar cal = Calendar.getInstance();
cal.set(2009, 02, 31);
Date testDate = cal.getTime();
System.out.println(testDate);
Calendar cal1 = Calendar.getInstance();
cal1.setTime(testDate);
cal1.add(Calendar.MONTH, 1);
Date testDate1 = cal1.getTime();
System.out.println(testDate1);
输出如下:
Tue Mar 31 11:27:41 CST 2009
Thu Apr 30 11:27:41 CST 2009
OK,结论出来了,add方法会处理自然月的增减来处理日期部分,set方法却只是当成30天来处理。事实证明原来的感觉是对的,希望以后少碰到类似错误!!
发表评论
-
20180222积累
2018-02-22 09:34 4781. mybatis如何通过接口查找对应的mapper. ... -
20180208积累
2018-02-08 10:28 465临时表与永久表相似,但临时表存储在 tempdb 中,当不 ... -
行业应用
2018-01-30 16:30 485git clone的时候用上面那个IP地址,下面栏中的不能 ... -
SQLite 数据库
2018-01-29 22:57 755android: SQLite创建数据 ... -
java里面获取map的key和value的方法
2018-02-01 11:29 2159获取map的key和value的方法分为两种形式: ma ... -
Eclipse中Maven WEB工程tomcat项目添加调试以及项目发布细节记录
2018-02-23 21:11 725一、建立一个maven WEB项目 1、file-&g ... -
错误:HttpServlet was not found on the Java
2018-02-23 21:12 382我们在用Eclipse进行Java web ... -
使用 java8 实现List到Array的转换
2018-02-23 21:13 2988开发中需要调用第三方的库,有些 API 的入参要求是 do ... -
Java8 利用Lambda处理List集合
2018-01-11 09:58 5630Java 8新增的Lambda表达式,我们可以很方便地并行操 ... -
java中string与json互相转化
2018-01-11 09:40 1076在Java中socket传输数据时,数据类型往往比较难选择。 ... -
JSON 数据格式
2018-01-11 09:37 474JSON(JavaScript Object Notatio ... -
java怎么读取json格式的数据
2018-01-11 09:46 1059java可以使用JSONObject和JSONArray来操作 ... -
Java8-如何将List转变为逗号分隔的字符串
2018-01-10 10:13 1988Converting a List to a String ... -
eclipse maven 打war包的两种方式
2018-02-23 21:25 703第一种:利用pom.xml文件打包。 右键pom.xml ... -
Annotation(三)——Spring注解开发
2018-02-28 09:21 428Spring框架的核心功能IoC(Inversion o ... -
Spring自定义注解
2018-02-28 09:32 594java注解:附在代码中的一些元信息,用于在编译、运行时起 ... -
Java项目
2018-01-08 10:56 0这两种解决办法已经能完全解决问题,不过值得注意的一点是,我 ... -
解决Eclipse建立Maven项目后无法建立src/main/java资源文件夹的办法
2018-03-22 10:41 1130在Eclipse中建立好一个Maven项目后,如果Java ... -
Java @override报错的解决方法
2018-01-07 12:56 0有时候Java的Eclipse工程换一台电脑后编译总是@ove ... -
Java 8 配置Maven-javadoc-plugin
2018-01-07 09:07 1040在升级JDK至1.8之后,使用Maven-javadoc- ...
相关推荐
calendar.setStartDate(new Date(2022, 1, 1)); // 设置开始日期为2022年2月1日 calendar.setEndDate(new Date(2022, 12, 31)); // 设置结束日期为2022年12月31日 ``` 回调和事件设置是calendar.js的另一个亮点。...
相反,`setTime(Date date)`方法可以使用`Date`对象设置`Calendar`的时间。 以下是一个简单的`Calendar`使用示例: ```java import java.text.SimpleDateFormat; import java.util.*; public class Test1 { ...
- 使用`set`方法可以设置具体的日期和时间。 ```java calendar.set(Calendar.YEAR, 2023); calendar.set(Calendar.MONTH, 7); // 注意:月份是从0开始的 calendar.set(Calendar.DAY_OF_MONTH, 1); ``` - 设置...
calendar.set(Calendar.MONTH, Calendar.DECEMBER); calendar.set(Calendar.DAY_OF_MONTH, 25); calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 59); ...
在这个项目中,我们将会深入探讨如何使用`Calendar`来获取年、月、日、时、分以及秒等时间信息。 首先,`Calendar`类不是线程安全的,因此在多线程环境中使用时需要额外注意同步问题。在Android中,我们通常会通过`...
如果要获取一年内的某个月的日历,可以使用`set`方法指定年份和月份: ```java calendar.set(Calendar.YEAR, 2022); calendar.set(Calendar.MONTH, Calendar.JANUARY); // 注意月份是从0开始的,所以1月是Calendar....
可以使用Calendar类的set()方法来设置时间。例如,设置时间为2019-02-21 23:59:59: ```java calendar.set(2019, Calendar.FEBRUARY, 21, 23, 59, 59); System.out.println(calendar.getTime()); ``` 或者,分别设置...
- **实例化`SimpleCalendar`**:创建`SimpleCalendar`对象并调用`MyCalendar()`方法输出日历。 ##### 3.2 日历构建方法 ```java public void MyCalendar(){ Calendar calendar = Calendar.getInstance(); // 创建...
`Calendar`类提供了设置具体日期时间的方法,如`set(int field, int value)`,其中`field`表示要设置的字段(如年、月、日等),`value`是具体的数值。例如: ```java Calendar c = Calendar.getInstance(); c.set...
可以使用`get()`和`set()`方法获取或设置这些字段的值。 五、时间跨度转换 `add()`方法可以增加或减少日历字段的值: ```java calendar.add(Calendar.DAY_OF_MONTH, 7); // 加7天 calendar.add(Calendar.WEEK_OF_...
首先通过`clear()`方法清除了24小时制的小时字段,然后使用`set()`方法将12小时制的小时字段设置为3。接下来再次输出修改后的日期和时间信息。 通过以上示例代码的详细解析,我们不仅了解了`Calendar`类的基本用法...
首先,让我们了解`Calendar`类的基本用法。`Calendar`是一个抽象类,我们通常通过`Calendar.getInstance()`静态方法获取其实例。这个实例可以被用来设置或获取年、月、日、小时、分钟等日期时间组件。例如: ```...
本文将详细解释如何使用Java的`Calendar`类来实现这一功能,以满足上述标题和描述的需求。 首先,我们创建一个`Calendar`实例,它代表当前的日期和时间。`Calendar.getInstance()`方法是获取当前日期的静态工厂方法...
首先,我们来看一下`Calendar`的基本用法。创建一个`Calendar`实例通常需要通过`Calendar.getInstance()`静态方法,这会返回一个`Calendar`的子类实例,通常是`GregorianCalendar`,它是符合公历标准的实现。 ```...
可以使用以下方法将 Calendar 对象转化为 Date 对象: ```java Calendar cal = Calendar.getInstance(); Date date = cal.getTime(); ``` 也可以将 Date 对象转化为 Calendar 对象: ```java Date date = new ...
可以使用`before()`, `after()`, 或 `compareTo()`方法比较两个`Calendar`对象: ```java Calendar anotherCalendar = ...; if (calendar.before(anotherCalendar)) { // ... } ``` 在Android中,除了`java.util...
对于非系统应用,你可能需要使用反射来调用这个方法,但这种方法不推荐,因为它可能在未来的Android版本中停止工作。 在上述代码中,我们首先创建了一个`Calendar`对象,并设置了所需的年、月、日、时、分、秒和...
设置时间推荐使用`java.util.Calendar`类,因为`Date`类的一些方法已过时。`Calendar`提供了更灵活的接口来修改日期和时间。首先,创建一个`Calendar`实例,并根据需要设置各项时间组件: ```java Calendar ...
在Java编程语言中,`Calendar`类是用于处理日期和时间的核心类,它是一个抽象类,提供了各种日期和时间操作的方法。在这个“日历calendar详细代码”中,我们很可能会看到如何使用`Calendar`类来创建、修改和查询日期...