[Java]Java日期及时间库插件 -- Joda Time.
来到新公司工作也有一个多月了, 陆陆续续做了一些简单的项目. 今天做一个新东西的时候发现了 Joda Time的这个东西, 因为以前用的都是JDK原生的时间处理API, 大家都知道Java原生的时间处理的API一直都是不太好用, 所以这个有必要去学习下, 去总结下.
来到新公司学到的东西挺多的, 比如我们用了Guava, ElasticSearch, kafka/mns/ons, GuavaCache/Ehcache/Memcahe .... 等很多东西都是我以前没有接触过的. 所以待我学习的东西还有很多. 每天都是怀着激动的心情, 去汲取更多的知识. 说了这么多屁话, 开始总结了.
一: 使用示例
因为双十一就快到了, 所以接触了一个秒杀的活动, 其中有这么一块代码:
/**
* 检查抽奖时间
*
* @return true 可以抽奖 false 不能抽奖
*/
private boolean checkDrawTime() {
return DateTime.parse("2016-11-11 11:11:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")).isBeforeNow();
}
这个方法很简单, 就是检查现在的时间是不是2016/11/11 11:11:00 之前. 当然这里的DateTime是Jode Time里的类.
查看源码可以知道, DateTime.parse就是将输入的时间转换为后面的格式, 转换的结果为:
然后再用isBeforeNow方法来比较, 下面看下这个方法具体的做法:
public boolean isBeforeNow() {
return this.isBefore(DateTimeUtils.currentTimeMillis());
}
public boolean isBefore(long var1) {
return this.getMillis() < var1;
}
这样看过来是不是很清楚了, 当然Java 自带的JDK也是可以完成的, 但是Joda Time都给我封装好了, 用起来就更加简单了.
接下来看看更多的例子:
1、创建任意时间对象
1 //jdk
2 Calendar calendar=Calendar.getInstance();
3 calendar.set(2012, Calendar.NOVEMBER, 15, 18, 23,55);
4
5 //Joda-time
6 DateTime dateTime=new DateTime(2012, 12, 15, 18, 23,55);
2、计算两日期相差的天数
1 //jdk
2 Calendar start = Calendar.getInstance();
3 start.set(2012, Calendar.NOVEMBER, 14);
4
5 Calendar end = Calendar.getInstance();
6 end.set(2012, Calendar.NOVEMBER, 15);
7
8 long startTim = start.getTimeInMillis();
9 long endTim = end.getTimeInMillis();
10 long diff = endTim-startTim;
11 int days=(int) (diff/1000 / 3600 / 24);
12
13
14 //joda-time
15 LocalDate start=new LocalDate(2012, 12,14);
16 LocalDate end=new LocalDate(2012, 12, 15);
17 int days = Days.daysBetween(start, end).getDays();
3、获取18天之后的某天在下个月的当前周的第一天日期
1 //jdk
2 Calendar current = Calendar.getInstance();
3 current.add(Calendar.DAY_OF_MONTH, 18);
4 current.add(Calendar.MONTH, 1);
5 ......
6 DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
7 Date date = current.getTime();
8 String dateStr = dateFormat.format(date);
9 System.out.println(dateStr);
10
11 //joda-time
12 String dateStr = new DateTime().plusDays(18).plusMonths(1)
13 .dayOfWeek().withMinimumValue().toString("yyyy-MM-dd HH:mm:ss");
14 System.out.println(dateStr);
4、时间格式化
1 DateTimeFormatter format = DateTimeFormat .forPattern("yyyy-MM-dd HH:mm:ss");
2
3 //时间解析
4 DateTime dateTime = DateTime.parse("2012-12-21 23:22:45", format);
5
6 //时间格式化,输出==> 2012/12/21 23:22:45 Fri
7 String string_u = dateTime.toString("yyyy/MM/dd HH:mm:ss EE");
8 System.out.println(string_u);
9
10 //格式化带Locale,输出==> 2012年12月21日 23:22:45 星期五
11 String string_c = dateTime.toString("yyyy年MM月dd日 HH:mm:ss EE",Locale.CHINESE);
12 System.out.println(string_c);
5、与JDK互操作
1 //通过jdk时间对象构造
2 Date date = new Date();
3 DateTime dateTime = new DateTime(date);
4
5 Calendar calendar = Calendar.getInstance();
6 dateTime = new DateTime(calendar);
7
8 // Joda-time 各种操作.....
9 dateTime = dateTime.plusDays(1) // 增加天
10 .plusYears(1)// 增加年
11 .plusMonths(1)// 增加月
12 .plusWeeks(1)// 增加星期
13 .minusMillis(1)// 减分钟
14 .minusHours(1)// 减小时
15 .minusSeconds(1);// 减秒数
16
17 // 计算完转换成jdk 对象
18 Date date2 = dateTime.toDate();
19 Calendar calendar2 = dateTime.toCalendar(Locale.CHINA)
二: api简介
Maven项目组中引入Joda Time坐标地址:
<!-- joda -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.3</version>
</dependency>
1, 日期和时间:
Joda-time里面的时间全都是不可变的,也就是不可变性。
DateTime :类似于JDK中的Calendar,提供了更多的方法。
DateMidnight :这个概念稍微复杂,封装某个时区(通常为默认时区)在特定年/月/日的午夜时分的时刻。它基本上类似于
DateTime,不同之处在于时间部分总是为与该对象关联的特定
DateTimeZone 时区的午夜时分。
LocalDate :无时间的类,只包含年月日。(不包含时区)
LocalTime :无日期的类,只包含时间。(不包含时区)
LocalDateTime :包含日期和时间。(不包含时区)
下面举一些简单的例子说明Joda-time的强大之处:
//获取当前月份:
DateTime dt = new DateTime();
int month = dt.getMonthOfYear();
//设定2000年/获取当前小时+2的小时:
DateTime dt = new DateTime();
DateTime year2000 = dt.withYear(2000);
DateTime twoHoursLater = dt.plusHours(2);
System.out.println(year2000.getYear());
System.out.println(twoHoursLater.getHourOfDay());
//以及下面的一些操作:
String monthName = dt.monthOfYear().getAsText();
String frenchShortName = dt.monthOfYear().getAsShortText(Locale.FRENCH);
boolean isLeapYear = dt.year().isLeap();
DateTime rounded = dt.dayOfMonth().roundFloorCopy();
System.out.println(monthName); // 本地月份名称
System.out.println(frenchShortName); // 法语月份简称
System.out.println(isLeapYear); // 是否闰年
System.out.println(rounded); // 获取当天0:0:0的DateTime对象
2, 日历系统及时区
Joda-time支持多种年表(即日历系统)及所有时区。主要的两个类如下:
Chronology :年表,Joda-time支持很多年表。就像JDK有Calendar,也有GregorianCalendar。
DateTimeZone :时区。
示例如下,一般系统都没有这个需求。
Chronology coptic = CopticChronology.getInstance();
System.out.println(coptic); // CopticChronology[Asia/Shanghai] DateTimeZone zone = DateTimeZone.forID("Asia/Tokyo");
Chronology gregorianJuian = GJChronology.getInstance(zone);
System.out.println(gregorianJuian); // GJChronology[Asia/Tokyo]
3, 时间跨度
Joda-time支持的时间跨度有三个,分别如下:
Interval :根据开始、结束时间表示一个特定的时间跨度。其为半开区间,即包括起始时刻,不包含结束时刻。
Period :Period设定了一些特定的时间跨度,比如小时、天、月。
Duration :表示绝对的精准跨度,以毫秒为单位。
使用示例如下:
DateTime beginDateTime = new DateTime(2010, 1, 1, 0, 0, 0);
DateTime endDateTime = new DateTime(2015, 1, 1, 0, 0, 0);
Interval interval = new Interval(beginDateTime, endDateTime);
System.out.println(interval.containsNow()); // 是否包含当前时间
System.out.println(interval.toDurationMillis()); // 时间间隔毫秒数 DateTime dt = new DateTime(2005, 3, 26, 12, 0, 0, 0);
DateTime plusPeriod = dt.plus(Period.days(1));
System.out.println(plusPeriod); // Period的方式+1天
DateTime plusDuration = dt.plus(new Duration(24L * 60L * 60L * 1000L));
System.out.println(plusDuration); // Duration的方式+1天
三: Joda-time使用的理念
不可变性(Immutability)
瞬间性(Instant)
局部性(Partial)
年表(Chronology)
时区(Time zone)
不可变
Joda-time的类具有不可变性,因此它们的实例无法被修改。(不可变类的一个优点就是它们是线程 安全 的)。用于处理日期计算的 API 方法全部返回一个对应 Joda-time 类的新实例,同时保持原始实例不变。当我们通过一个 API 方法操作 Joda 类时,我们必须捕捉该方法的返回值,因为我们正在处理的实例不能被修改。你可能对这种模式很熟悉,这正是 java.lang.String 的各种操作方法的工作 方式。
瞬间性
Instant 表示时间上的某个精确的时刻,使用从 epoch 开始计算的毫秒表示。这一定义与 JDK 相同,这就是为什么任何 Joda Instant 子类都可以与 JDK Date 和 Calendar 类兼容的原因。
更通用一点的定义是:一个瞬间 就是指时间线上只出现一次且唯一的一个时间点,并且这种日期结构只能以一种有意义的方式出现一次。
局部性
一个局部时间,正如我将在本文中将其称为局部时间片段一样,它指的是时间的一部分片段。瞬间性指定了与 epoch 相对的时间上的一个精确时刻,与此相反,局部时间片段指的是在时间上可以来回 “移动” 的一个时刻,这样它便可以应用于多个实例。比如,6 月 2 日 可以应用于任意一年的 6 月份(使用 Gregorian 日历)的第二天的任意瞬间。同样,11:06 p.m. 可以应用于任意一年的任意一天,并且每天只能使用一次。即使它们没有指定一个时间上的精确时刻,局部时间片段仍然是有用的。
我喜欢将局部时间片段看作一个重复周期中的一点,这样的话,如果我正在考虑的日期构建可以以一种有意义的方式出现多次(即重复的),那么它就是一个局部时间。
年表
Joda 本质——以及其设计核心——的关键就是年表(它的含义由一个同名抽象类捕捉)。从根本上讲,年表是一种日历系统——种计算时间的特殊方式——并且是一种在其中执行日历 算法 的框架。受 Joda 支持的年表的例子包括:ISO(默认)、Coptic、Julian、Islamic等。
时区
时区是值一个相对于英国格林威治的地理位置,用于计算时间。要了解事件发生的精确时间,还必须知道发生此事件的位置。任何严格的时间计算都必须涉及时区(或相对于 GMT),除非在同一个时区内发生了相对时间计算(即时这样时区也很重要,如果事件对于位于另一个时区的各方存在利益关系的话)。
DateTimeZone 是 Joda 库用于封装位置概念的类。许多日期和时间计算都可以在不涉及时区的情况下完成,但是仍然需要了解 DateTimeZone 如何影响 Joda 的操作。默认时间,即从运行代码的机器的系统时钟检索到的时间,在大部分情况下被使用。
好了, 我所了解的就是这么多, 我主要还是从如何使用的角度去学习这个东西, 最后总结了它的几个特性, 当然Joda-Time的强大之处远不止这些, 大家在以后的工作中可以尝试着去使用它.
[Java]Java日期及时间库插件 -- Joda Time.的更多相关文章
- Java 8 – 日期和时间实用技巧
当你开始使用Java操作日期和时间的时候,会有一些棘手.你也许会通过System.currentTimeMillis() 来返回1970年1月1日到今天的毫秒数.或者使用Date类来操作日期:当遇到加 ...
- Java 格式化日期、时间
有三种方法可以格式化日期.时间. 1.使用DateFormat类 获取DateFormat实例: DateFormat.getDateInstance() 只能格式化日期 2019年5 ...
- JAVA中日期和时间的格式化选项
一.使用printf方法 import java.util.Date; import java.util.Scanner; public class Test { public static void ...
- (原创)c++11中的日期和时间库
c++11提供了日期时间相关的库chrono,通过chrono相关的库我们可以很方便的处理日期和时间.c++11还提供了字符串的宽窄转换功能,也提供了字符串和数字的相互转换的库.有了这些库提供的便利的 ...
- c++11之日期和时间库
本文主要介绍 std::chrono日期和时间用法. 演示环境: vs2017 0.头文件 1 #include <chrono> 2 #include <thread>// ...
- Joda Time - 强大易用的日期和时间库
Joda-Time提供了一组Java类包用于处理包括ISO8601标准在内的date和time.可以利用它把JDK Date和Calendar类完全替换掉,而且仍然能够提供很好的集成. Joda-Ti ...
- 强大易用的日期和时间库 Joda Time
Joda-Time提供了一组Java类包用于处理包括ISO8601标准在内的date和time.可以利用它把JDK Date和Calendar类完全替换掉,而且仍然能够提供很好的集成,并且它是线程安全 ...
- Java中日期和时间的相关问题
1.java.lang.System类 System类提供的public static long currentTimeMillis()用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位 ...
- Java的日期与时间 java.time.Duration (转)
一个Duration对象表示两个Instant间的一段时间,是在Java 8中加入的新功能. 一个Duration实例是不可变的,当创建出对象后就不能改变它的值了.你只能通过Duration的计算方法 ...
随机推荐
- TypeScript: Angular 2 的秘密武器(译)
本文整理自Dan Wahlin在ng-conf上的talk.原视频地址: https://www.youtube.com/watch?v=e3djIqAGqZo 开场白 开场白主要分为三部分: 感谢了 ...
- ASP.NET Core 中文文档 第四章 MVC(3.8)视图中的依赖注入
原文:Dependency injection into views 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:孟帅洋(书缘) ASP.NET Core 支持在视图中使用 依赖 ...
- TDD在Unity3D游戏项目开发中的实践
0x00 前言 关于TDD测试驱动开发的文章已经有很多了,但是在游戏开发尤其是使用Unity3D开发游戏时,却听不到特别多关于TDD的声音.那么本文就来简单聊一聊TDD如何在U3D项目中使用以及如何使 ...
- gulp详细入门教程
本文链接:http://www.ydcss.com/archives/18 gulp详细入门教程 简介: gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器:她不仅能对网站资源进行优 ...
- 快速搭建springmvc+spring data jpa工程
一.前言 这里简单讲述一下如何快速使用springmvc和spring data jpa搭建后台开发工程,并提供了一个简单的demo作为参考. 二.创建maven工程 http://www.cnblo ...
- 算法与数据结构(十六) 快速排序(Swift 3.0版)
上篇博客我们主要聊了比较高效的归并排序算法,本篇博客我们就来介绍另一种高效的排序算法:快速排序.快速排序的思想与归并排序类似,都是采用分而治之的方式进行排序的.快速排序的思想主要是取出无序序列中第一个 ...
- Angular2开发笔记
Problem 使用依赖注入应该注意些什么 服务一般用来做什么 指令一般用来做什么 angular2如何提取公共组件 angular2为什么不需要提公共组件 父组件与子组件之间如何通讯 什么时候应该使 ...
- potrace源码分析一
1 简介 potrace是由Dalhousie University的Peter Selinger开发一款位图轮廓矢量化软件,该软件源码是可以公开下载的,详细见项目主页:http://potrace. ...
- Autofac - 方法注入
方法注入, 其实就是在注册类的时候, 把这个方法也注册进去. 那么在生成实例的时候, 会自动调用这个方法. 其实现的方法, 有两种. 准备工作: public interface IAnimal { ...
- MongoDB学习笔记~对集合属性的操作
回到目录 $unset清除元素 请注意在单个数组元素上使用$unset的结果可能与你设想的不一样.其结果只是将元素的值设置为null,而非删除整个元素.要想彻底删除某个数组元素,可以用$pull 和$ ...