java日期
来源:互联网 发布:淘宝的微淘怎么弄2016 编辑:程序博客网 时间:2024/06/11 06:20
参考:http://www.joda.org/joda-time/index.html
简介一下Joda-Time
这个是作为替代JDK的事件库而存在的。因为JDK的时间API有点不太好用。下面介绍一下:
获取属性
get方法
DateTime有一大波get方法,getDayOfYear,getDayOfWeek,getWeekOfWeekyear等等等等,终于,月份是从1开始了~~这些方法并不是DateTime实现的,而是父类AbstractDateTime实现的,仔细看源代码,具体实现的也不是AbstractDateTime类,而是Chronology(历法)类,这个类的职责,类似于日历,他的具体子类定义了不同种类的日历。细思极恐,居然可以把日历抽象到这种地步!!!
另外,补充一下year和yearOfEra的区别:
DateTime dt = new DateTime(-100,1,1,0,0);
System.out.println(dt.getYearOfEra());
System.out.println(dt.getYear());
yearOfEra是带有公元/公元前的标志的,类似于我们说的6:00PM一样,year和yearOfEra在公元中是一样的,公元前则是不同的。year用负数表示公元前,yearOfEra则用正数,并且,绝对值差1。
输出:
101
-100
为啥捏?!
因为并没有公元0年这个概念,所以,不适用公元标志的时候,0是表示公元前1年,100表示公元前101年。
property属性
DateTime还有一个内置静态类,Property。也是获取年月日等属性,功能更加丰富:
dt = new DateTime(2004,2,15,0,0);
DateTime.Property year = dt.year();
DateTime.Property month = dt.monthOfYear();
DateTime.Property day = dt.dayOfMonth();
System.out.println(year.isLeap());
System.out.println(month.getAsShortText());
System.out.println(day.getMaximumValue());
//获取当月最后一天的日期
System.out.println(day.setCopy(day.getMaximumValue()));
输出:
true
二月
29
2004-02-29T00:00:00.000+08:00
这些功能可以判断闰年,可以获取最大值等等。最后一个例子演示了如何求一个月的最后一天。setCopy可以返回当前属性修改后的DateTime对象。
日期计算
DateTime提供了大量易用的加减方法,用于日期的计算,作用类似于Calendar的Set方法,却比Set方法简单易用:
//三周后的星期日
DateTime dt = DateTime.now();
System.out.println(dt
.plusWeeks(3)
.withDayOfWeek(DateTimeConstants.SUNDAY)
.toString("yyyy-MM-dd HH:mm:ss.SSS EEEE"));
可以看到,DateTime用的都是比较直观的方式命名,plusWeeks,withDayOfWeek,其他的还有,plus从Years到Millis,with从Years到Millis,其实还有minus。这些命名方式,一看就明白。而且,支持链式操作(就是可以一直“点”下去),非常方便。要实现链式操作其实非常简单,每次返回一个DateTime对象就可以,不过这里不是为了支持链式操作才这么做的,而是因为他是不可变的,
那么什么是不可变
就是创建了的对象,什么属性,你都改不了。比如上面的plusWeeks,其实也没有改变本身,而是返回了一个加了3周后的对象,原来的对象,根本没有改变。
为什么要设计成不可变的
- 设计使用简单:既然是不可变的,设计使用就简单得多,反正也不让你改,这样出错的可能也就少了。比如拷贝这个问题,DateTime这个类,根本就没实现拷贝接口!因为不需要,反正你不能改,直接拿去用。
- 线程安全:反正你也不能改,当然可以自由的共享,也就是说,他是线程安全的~
withDayOfWeek 这个命名也是有讲究的,为什么是with而不是set,也是因为不可变的原因。
性能问题
jdk中也有许多不可变类,比如string,字符串拼接就有很大的性能问题,所以string还有个StringBuilder这种可变类。同理,DateTime也有可变的版本MutableDateTime。
时间间隔与时间段
时间间隔
Joda-Time使用Interval表示时间间隔。它含有两个属性,开始和结束。这是个半闭包结构,包括开始,不包括结束。
DateTime dt2018 = new DateTime(2018,1,1,0,0);
DateTime dt2017 = new DateTime(2017,1,1,0,0);
DateTime dt2016 = new DateTime(2016,1,1,0,0);
DateTime dt2015 = new DateTime(2015,1,1,0,0);
Interval t0506 = new Interval(dt2015, dt2016);
Interval t0507 = new Interval(dt2015, dt2017);
Interval t0708 = new Interval(dt2017, dt2018);
//判断是否相交
System.out.println(t0506.overlaps(t0507));
//判断是否包含
System.out.println(t0506.contains(t0507));
//求相交部分
System.out.println(t0506.overlap(t0507));
//求间距
System.out.println(t0506.gap(t0708));
API中还有很多方法,我没有列出来,输出:
true
false
2015-01-01T00:00:00.000+08:00/2016-01-01T00:00:00.000+08:00
2016-01-01T00:00:00.000+08:00/2017-01-01T00:00:00.000+08:00
时间段
Duration和Period类,都表示时间段,细节上有所差别。英语的本意分别是“持续”和“周期”,Duration表示连续的时间段,毫秒为单位。而Period则表示周期性时间,比如年月日,一年一定是365天么,一个月一定是30天么,一天一定是24小时么,都不一定。而Period表示的就是这种时间。
这两种时间段,都可以和DateTime做时间加减:
//100天
Period days100 = Period.days(100);
//2年
Period years2 = Period.years(2);
//2年3个月
Period years2Months3 = years2.withMonths(3);
DateTime dt = DateTime.now();
System.out.println(dt.plus(days100));
System.out.println(dt.minus(years2));
System.out.println(dt.plus(years2Months3));
Duration dayStandar2 = Duration.standardDays(2);
Duration hourStandar3 = Duration.standardHours(3);
System.out.println(dt.plus(dayStandar2));
System.out.println(dt.minus(hourStandar3));
定义了这两个类,就更加准确的定义了时间段这个东西,有了这个东西,就可以准确的表示1天,到底是1天前还是24小时前这个问题了。再也不用担心沟通产生的歧义了~~
小结
个人感觉,时间段和时间间隔类的定义,一个是明确定义了几种我们常用的场镜,另一个就是简单实现了场镜中的方法。
格式化与解析
joda-time的格式化与解析的字母模板和JDK的是兼容的,所以,没什么好说的:
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMdd");
System.out.println(fmt.print(DateTime.now()));
DateTime dt2000 = fmt.parseDateTime("20000101");
System.out.println(fmt.print(dt2000));
输出:
20170322
20000101
对象类型转换
在API中一堆to的方法就是喽~
0 0
- JAVA & 日期
- JAVA & 日期
- Java日期
- Java日期
- java日期
- Java 日期
- Java日期
- java 日期
- JAVA日期
- java-日期
- java 日期
- Java日期
- java日期
- JAVA日期
- Java日期
- Java日期
- Java 日期
- Java 日期
- Android——多线程(AsyncTask封装)
- asp.net mvc 中对easyui的引用文件使用Bundle的注意事项
- 从C#中的ArrayList和List的区别说起
- python sorted()
- 安卓学习笔记---Android图片加载框架最全解析(一),Glide的基本用法
- java日期
- 数学公式的英文读法
- FreeRTOS学习------信号量(实践)
- 开源|2017 CVPR(Oral Paper):多目标实时体态估测 项目开源
- webservice
- SLua踩坑指南:导出APK/导出AssetsBundle报错
- Apache Flink® 入门介绍以及编程模型
- javasc基础笔记
- UVA-1642-MagicalGCD[区间最大公约数]