记得在我刚学Java的时候,真是搞不清楚Date和Calendar这两个类,后来我渐渐知道,原来不能全怪我啊,Java日期API之烂是公认的(不妨参见这篇文章,Tiago Fernandez做过一个投票,就是要选举最烂的Java API,结果Java日期API排行第二,仅次于臭名远扬的EJB2,嘿嘿)。
蛋疼的java.sql.Date
只有Date和Calendar搞定一切吗?那还好啊。当然不是!光Date就有java.util.Date和java.sql.Date,而且关系是java.sql.Date extends java.util.Date。为了把前者转成后者,我写了这样的代码:
1
2
|
Date date = new Date();
java.sql.Date d = new java.sql.Date(date.getTime());
|
居然不支持Date参数的构造器,我只好传入long类型的时间。接下去,我尝试把当前小时数取出来:
1
|
System.out.println(d.getHours()); |
悲剧出现了:
1
2
|
Exception in thread "main" java.lang.IllegalArgumentException at java.sql.Date.getHours(Date.java:177)
|
一看源码,坑爹啊:
1
2
3
|
public int getHours() {
throw new java.lang.IllegalArgumentException();
} |
在java.util.Date里面好好的方法怎么变成这个鸟样了?
方法注释给出了说明:
This method is deprecated and should not be used because SQL Date values do not have a time component.
也就是说,java.sql.Date是SQL中的单纯的日期类型,哪会有时分秒啊?我觉得它根本不应该设计成java.util.Date的子类。如果你把java.sql.Date通过JDBC插入数据库,你会发现时分秒都丢失了,因此如果你同时需要日期和时间,你应该使用Timestamp,它也是java.util.Date的子类。
另外还有一个java.util.Date的子类叫Time,java.sql包下面的Date、Time和Timestamp可以放在一起记忆。Date只包含年月日信息、Time只包含时分秒信息,而Timestamp则包含时间戳的完整信息。
现在知道人家抛出IllegalArgumentException的用心良苦了吧……
坑爹的year和month
看看Date类的构造器:
1
|
public Date( int year, int month, int day)
|
长得并不奇葩嘛。
好,现在我要输出2012年的1月1号了:
1
2
|
Date date = new Date( 2012 , 1 , 1 );
System.out.println(date); |
结果,我傻眼了:
1
|
Thu Feb 01 00:00:00 CST 3912 |
等等,这是啥?3192年?
原来实际年份是要在你的年份参数上加上个起始年份1900。
更坑爹的是,月份参数我不是给了1吗?怎么输出二月(Feb)了?
Date里面的月份居然是用0~11表示的,换句话说,一月用0来表示,二月用1来表示。如果不用常量或者枚举,很容易踩到坑里去,对不对?
后来发现Go语言的time.Date方法,对于月份做了个恶心但是不容易坑人的处理(看奇葩的月份参数啊):
1
|
func Date(year int , month Month, day, hour, min, sec, nsec int , loc *Location)
|
我甚至怀疑Google这样处理是在用极端的方法鄙视Java(另,据我所知,JavaScript好像也是这样的,月份从0开始)……
坑爹的事情还没完,前面已经说了,构造函数的时间起始基准是1900年,可是getTime()方法却特立独行,返回的时间是相对于“1970-01-01 00:00:00”的毫秒数差值……
尝试Joda吧
最开始的时候,Date既要承载日期信息,又要做日期之间的转换,还要做不同日期格式的显示,职责较繁杂,从JDK 1.1 开始,这三项职责分开了:
- 使用Calendar类实现日期和时间字段之间转换;
- 使用DateFormat类来格式化和分析日期字符串;
- 而Date只用来承载日期和时间信息。
原有Date中的相应方法已废弃。不过,无论是Date,还是Calendar,都用着太不方便了,这是API没有设计好的地方。
比如Calendar的getInstance方法,并未提供一个指定年月日和时分秒的重载方法,每次要指定特定的日期时间,必须先获取一个表示当前时间的Calendar实例,再去设值,比如:
1
2
3
|
Calendar c = Calendar.getInstance(); c.set( 2012 , 0 , 1 , 11 , 11 , 11 );
System.out.println(c.getTime()); |
注意上面代码中对于年份的传值——是的,和Date不一样的是,Calendar年份的传值不需要减去1900(当然月份的定义和Date还是一样),这种不一致真是让人抓狂!
打印:
1
|
Sun Jan 01 11:11:11 CST 2012 |
有很多开源库都在努力弥补Java的这一问题,比如Joda-Time,获取Calendar对象和设置时间完全可以合成一步完成:
1
|
DateTime dateTime = new DateTime( 2012 , 1 , 1 , 11 , 11 , 11 , 0 );
|
而且,一月份总是可以传1来表示了。
再如,如果要给上述时间增加3天再按格式输出的话,使用Joda更加便捷:
1
|
System. out .println(dateTime.plusDays(3).toString( "E MM/dd/yyyy HH:mm:ss" );
|
有兴趣的话请阅读此文,并下载Joda-Time使用。
JSR-310
众所周知Java的规范就是多、而且啰嗦,这帮老大们(Export Group中除了有Oracle的人,还有IBM、Google和RedHat的人)终于再也无法忍受Java那么烂的日期API了,于是就有了JSR-310(感兴趣的请移步),官方的描述叫做“This JSR will provide a new and improved date and time API for Java.”,目前的阶段还在“Early Draft Review 2”,有得等。
JSR-310将解决许多现有Java日期API的设计问题。比如Date和Calendar目前是可变对象,你可以随意改变对象的日期或者时间,而Joda就将DateTime对象设计成String对象一样地不可变,能够带来线程安全等等的好处,因此这一点也将被JSR-310采纳。
很多JSR规范都是在程序员的诋毁和谩骂声中萌芽的,然后会有开源项目来尝试解决Java的这些弊端,最后就轮到JSR就去抄他们的实现。除了新的日期API,再比如JCache(JSR-107),你知道它抄了多少EhCache的东西么……
相关推荐
本文档是 Java 2 Platform Standard Edition 6.0 的 API 规范。 请参见: 描述 Java 2 Platform 软件包 java.applet 提供创建 applet 所必需的类和 applet 用来与其 applet 上下文通信的类。 java.awt 包含...
java apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava apijava api...
Java API for Mac,简称为Java-API-Mac,是专门为苹果Mac操作系统设计的一套Java开发接口。这个API使得Java开发者能够充分利用Mac平台特有的功能和特性,如Aqua界面、Carbon库集成以及Core Foundation框架等,从而...
5. **日期和时间API**:Java 8改进了日期和时间的处理,引入了`java.time`包,提供了`LocalDate`、`LocalTime`、`LocalDateTime`等类,替代了之前易用性较差的`java.util.Date`和`java.util.Calendar`。 6. **并发...
5. **日期和时间API**: Java 8引入了`java.time`包,提供`LocalDate`、`LocalTime`、`LocalDateTime`等类,替代了原有的`java.util.Date`和`Calendar`,使日期和时间的操作更加直观。 **模块系统(Project Jigsaw)...
Java 8 API 文档是Java开发人员的重要参考资料,它详细阐述了Java 8及更高版本中的各种类库、接口和方法。这个文档包含了Java SE(标准版)8的所有公共API,是理解和使用新特性的关键工具。让我们深入探讨Java 8 API...
Java 8还对日期和时间API进行了重写,引入了`java.time`包。旧的`java.util.Date`和`java.util.Calendar`被更直观、更易用的`LocalDate`、`LocalTime`、`LocalDateTime`等类取代。这些新类提供了更丰富的操作和格式...
5. **日期和时间API**:Java 8彻底改革了日期和时间处理,引入了java.time包,包含LocalDate、LocalTime、LocalDateTime、ZonedDateTime等类,提供更强大、更易用的日期和时间操作。 6. **默认方法**:在接口中添加...
JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI文档中文版,JavaAPI...
5. **日期和时间API**:Java 8用`java.time`包取代了过时的`java.util.Date`和`Calendar`,提供了更直观和易用的日期、时间和时区处理。`LocalDate`, `LocalTime`, `LocalDateTime`, `ZonedDateTime`等类提供了丰富...
- **日期和时间API**:用`java.time`包取代了`java.util.Date`和`java.util.Calendar`,提供了更直观、更强大的日期和时间操作。 - **默认方法**:在接口中可以定义默认实现的方法,使得接口升级时避免破坏现有...
4. **日期与时间API**:Java 8用新的`java.time`包取代了过时的`java.util.Date`和`java.util.Calendar`,提供了更直观、更易用的日期和时间API,如`LocalDate`、`LocalTime`和`LocalDateTime`。 5. **默认方法**:...
Java 8对日期和时间API进行了彻底的改革,引入了`java.time`包,包含`LocalDate`, `LocalTime`, `LocalDateTime`等类,以及`ZonedDateTime`和`Duration`等,提供了更直观和强大的日期时间处理功能。 **8. Nashorn ...
Java API文档是Java开发者不可或缺的参考资料,它详细记录了Java编程语言的标准库,包括类、接口、方法和属性等核心元素。这些文档不仅提供技术规格,还包含使用示例,帮助程序员理解和应用Java的各类功能。 1. **...
open CV2.9.4版本的java ApI
java6 api中文文档java6 api中文文档java6 api中文文档java6 api中文文档java6 api中文文档java6 api中文文档java6 api中文文档
`java.util`包含集合框架、日期时间、随机数生成等;`java.io`则涉及输入/输出流操作。 2. **网络编程**:`java.net`包提供了网络通信的支持,包括Socket和ServerSocket类,用于实现客户端和服务器端的连接。 3. *...
Java JSON API是Java平台上的库,提供了处理JSON的能力,包括解析JSON字符串、生成JSON对象以及进行JSON与Java对象之间的转换。 在Java中,有多种实现JSON API的库,如Jackson、Gson、org.json和json-lib等。本篇...
标题《ElasticSearch Java API 中文文档》表明本篇文档的主要内容是关于ElasticSearch的Java API的中文使用说明和相关知识点介绍。ElasticSearch是一个基于Lucene构建的开源搜索引擎,它提供了一个分布式、多用户...
中文JAVA API。