Java日期及时间库插件 -- Joda Time.
轉載自? ?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、創建任意時間對象
//jdk Calendar calendar=Calendar.getInstance(); calendar.set(2012, Calendar.NOVEMBER, 15, 18, 23,55);//Joda-time DateTime dateTime=new DateTime(2012, 12, 15, 18, 23,55);2、計算兩日期相差的天數
//jdkCalendar start = Calendar.getInstance(); start.set(2012, Calendar.NOVEMBER, 14);Calendar end = Calendar.getInstance();end.set(2012, Calendar.NOVEMBER, 15);long startTim = start.getTimeInMillis();long endTim = end.getTimeInMillis();long diff = endTim-startTim;int days=(int) (diff/1000 / 3600 / 24);//joda-timeLocalDate start=new LocalDate(2012, 12,14);LocalDate end=new LocalDate(2012, 12, 15);int days = Days.daysBetween(start, end).getDays();3、獲取18天之后的某天在下個月的當前周的第一天日期
//jdk Calendar current = Calendar.getInstance(); current.add(Calendar.DAY_OF_MONTH, 18); current.add(Calendar.MONTH, 1);...... DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = current.getTime(); String dateStr = dateFormat.format(date); System.out.println(dateStr);//joda-time String dateStr = new DateTime().plusDays(18).plusMonths(1).dayOfWeek().withMinimumValue().toString("yyyy-MM-dd HH:mm:ss"); System.out.println(dateStr);4、時間格式化
DateTimeFormatter format = DateTimeFormat .forPattern("yyyy-MM-dd HH:mm:ss");//時間解析 DateTime dateTime = DateTime.parse("2012-12-21 23:22:45", format);//時間格式化,輸出==> 2012/12/21 23:22:45 Fri String string_u = dateTime.toString("yyyy/MM/dd HH:mm:ss EE"); System.out.println(string_u);//格式化帶Locale,輸出==> 2012年12月21日 23:22:45 星期五 String string_c = dateTime.toString("yyyy年MM月dd日 HH:mm:ss EE",Locale.CHINESE); System.out.println(string_c);5、與JDK互操作
//通過jdk時間對象構造 Date date = new Date(); DateTime dateTime = new DateTime(date);Calendar calendar = Calendar.getInstance(); dateTime = new DateTime(calendar);// Joda-time 各種操作..... dateTime = dateTime.plusDays(1) // 增加天.plusYears(1)// 增加年.plusMonths(1)// 增加月.plusWeeks(1)// 增加星期.minusMillis(1)// 減分鐘.minusHours(1)// 減小時.minusSeconds(1);// 減秒數// 計算完轉換成jdk 對象 Date date2 = dateTime.toDate(); 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日期及时间库插件 -- Joda Time.的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用开源 Godot 引擎,《杀戮尖塔》
- 下一篇: 总结Java常见面试题和答案