靜以修心

          關于date4j,簡約的日期處理庫(Java's Date Classes Must Die.)

                在熟悉公司業務代碼的時候經常看見有日期處理(date),由于項目轉手次數較多,在這方面沒合理封裝處理好,于是就想自己封裝一個date類。然而輾轉了幾天卻發覺已經有date4j的存在,于是在這里簡單地介紹一下這個日期類庫。以下包括自己的代碼、網上流傳資料、以及date4j官網例子。

          -------------------------------------------------------------------------------------------------------------------------------------------------------------

          java日期處理相關類:

          java.util.Date 
          java.sql.Date 
          java.sql.Time 
          java.sql.Timestamp 
          java.util.Calendar 
          java.util.TimeZone

               比較常用的是java.util.date,將java.util.Date轉為java.sql.Date的時候,日期時分秒會被去掉,失去精度。而且如果現在翻開api看看就發覺這兩個類好多方法已經過時,幾近淪為廢物。

               Timestamp能和java.util.date無損轉換,但是在一些預定義sql中會常常出問題。

          (以上出自 click me

          --------------------------------------------------------------------------------------------------------------------------------------------------------------

          Java本身的日期類在JDK1.0版本之后就再也沒有更新過,同時還存在著一些眾所周知的問題(例如1月從0開始,導致了很多月份差一的漏洞)。一份新的Java規范請求(JSR,Java Specification Request)已經被提交,目的就是要解決上述問題,此版本的類庫仍處在Alpha版本。在其穩定之前,很多開發者還是會使用Joda Time類庫,該類庫與JSR-310的參考實現類似(但不完全相同)。 Date4j為在Java中處理日期提供了一套新的解決方案,但與Joda Time所關注的范圍完全不同。對比如下:

          Joda TimeDate4j
          擁有的類的數量: 140+ 擁有的類的數量< 10
          包含可變和不可變類 僅包含不可變類
          強調速度和功能 強調簡單和有效
          支持格里高里歷(Gregorian)、 科普特語日歷(Coptic)、 伊斯蘭教歷(Islamic)、佛歷(Buddhist)等等 只提供對格里高里歷的支持
          可以完全取代JDK日期類 和JDK日期類配合使用
          精確到毫秒級操作 支持到納秒(十億分之一秒)級操作
          修復了天“溢出”的問題 天“溢出”的問題可配置
          針對的是通常意義的日期維護 適用于通過數據庫來維護的日期
          采用Apache 2.0授權許可 采用BSD授權許可

          雖然乍一看Date4j只具備了Joda中一部分的特性,但它有兩個主要的特點是Joda所不具備的。

          首先,Date4j的開發者宣稱類庫不應莫名其妙地將日期截斷。Joda只支持毫秒級的精度而且在將來可能也不會改善。一些數據庫也已經有了更好的解決方案。比如流行的PostgreSQL數據庫對時間戳精度就已經支持到微秒級(百萬分之一秒)。Date4j可在處理日期時對精度毫無損傷。

          第二個特征是日期“溢出”的問題,例如向某個日期增加一段時間后,日期落在下月的情況。最簡單的例子就是在3月31日增加一個月的計算:

          DateTime dt = new DateTime("2011-03-31"); 
          DateTime result = dt.plusMonths(1); (最新版本此方法應該已經被刪除,只有plus(...)與plusDay())
          System.out.println(result.toString());

          當使用Joda Time時,會輸出4月30日,但這也許并不是你想要的結果。

          鑒于這種不確定性,Date4j為您提供了4種選擇

          1. 第一天
          2. 最后一天(與Joda Time相同)
          3. 日期順延
          4. 拋出異常

          以上轉自 click me
          -----------------------------------------------------------------------------------------------------------------------------------------------------------

          date4j官網&&實例:


          import hirondelle.date4j.DateTime;
          import hirondelle.date4j.DateTime.DayOverflow;

          import java.util.TimeZone;

          public class Date4jExamples {

              public static void main(String[] args) {
                  Date4jExamples examples = new Date4jExamples();
                  examples.currentDateTime();
                  examples.ageIfBornOnCertainDate();
                  examples.daysTillChristmas();
                  examples.whenIs90DaysFromToday();
                  examples.dateDifference();
                  examples.whenIs3Months5DaysFromToday();
                  examples.hoursDifferenceBetweenParisAndPerth();
                  examples.weeksSinceStart();
                  examples.timeTillMidnight();
                  examples.imitateISOFormat();
                  examples.firstDayOfThisWeek();
                  examples.jdkDatesSuctorial();

              }

              private static void log(Object aMsg) {
                  System.out.println(String.valueOf(aMsg));
              }

              /**   
               * 獲取當前時間 what is the current date-time in the JRE's default time zone
               * ------------------------------------------------------------------------
               * Here are some practical examples of using the above formatting symbols:
               *
               *    Format                                  Output
               *    YYYY-MM-DD hh:mm:ss.fffffffff a     1958-04-09 03:05:06.123456789 AM
               *    YYYY-MM-DD hh:mm:ss.fff a             1958-04-09 03:05:06.123 AM
               *    YYYY-MM-DD                             1958-04-09
               *    hh:mm:ss.fffffffff                     03:05:06.123456789
               *    hh:mm:ss                             03:05:06
               *    YYYY-M-D h:m:s                         1958-4-9 3:5:6
               *    WWWW, MMMM D, YYYY                     Wednesday, April 9, 1958
               *    WWWW, MMMM D, YYYY |at| D a         Wednesday, April 9, 1958 at 3 AM
               *
               *----------------------------------------------------------------------
               * ---
              private void currentDateTime() {
                  DateTime now = DateTime.now(TimeZone.getDefault());
                  String result = now.format("YYYY-MM-DD hh:mm:ss");
                  log("Current date-time in default time zone : " + result);
                  // result Current date-time in default time zone : 2012-04-12 00:55:54
              }

              /**
               * 年齡計算 what's the age of someone born may 16,1995
               
          */
              private void ageIfBornOnCertainDate() {
                  DateTime today = DateTime.today(TimeZone.getDefault());
                  DateTime birthdate = DateTime.forDateOnly(1995, 5, 16);
                  int age = today.getYear() - birthdate.getYear();
                  // getDayOfYear獲取距離年初的總天數
                  if (today.getDayOfYear() < birthdate.getDayOfYear()) {
                      age = age - 1;
                  }
                  log("Age of someone born May 16, 1995 is : " + age);
                  // result Age of someone born May 16, 1995 is : 16
              }

              /**
               * 日期相距 How many days till the next December 25
               
          */
              private void daysTillChristmas() {
                  DateTime today = DateTime.today(TimeZone.getDefault());
                  DateTime christmas = DateTime.forDateOnly(today.getYear(), 12, 25);
                  int result = 0;
                  if (today.isSameDayAs(christmas)) {
                      // do nothing
                  } else if (today.lt(christmas)) {
                      result = today.numDaysFrom(christmas);
                  } else if (today.gt(christmas)) {
                      DateTime christmasNextYear = DateTime.forDateOnly(
                              today.getYear() + 1, 12, 25);
                      result = today.numDaysFrom(christmasNextYear);
                  }
                  log("Number of days till Christmas : " + result);
                  // result Number of days till Christmas : 257
              }

              /**
               * What day is 90 days from today
               
          */
              private void whenIs90DaysFromToday() {
                  DateTime today = DateTime.today(TimeZone.getDefault());
                  log("90 days from today is : "
                          + today.plusDays(90).format("YYYY-MM-DD"));
                  // result 90 days from today is : 2012-07-11
              }

              /**
               * 日期相差
               
          */
              private void dateDifference() {
                  // DayOverflow.Abort result throw Exception
                  
          // DayOverflow.Spillover result 2011-05-01
                  
          // DayOverflow.LastDay result 2011-04-30
                  
          // DayOverflow.FirstDay result 2011-05-01
                  
          // public enum DayOverflow {
                  
          /** Coerce the day to the last day of the month. */
                  
          // LastDay,
                 
           /** Coerce the day to the first day of the next month. */
                  
          // FirstDay,
                  
          /** Spillover the day into the next month. */
                  
          // Spillover,
                 
          /** Throw a RuntimeException. */
                  
          // Abort;
                  
          // }
                  /**
                   * 
          @param aNumYears
                   *            positive, required, in range 09999
                   * 
          @param aNumMonths
                   *            positive, required, in range 09999
                   * 
          @param aNumDays
                   *            positive, required, in range 09999
                   * 
          @param aNumHours
                   *            positive, required, in range 09999
                   * 
          @param aNumMinutes
                   *            positive, required, in range 09999
                   * 
          @param aNumSeconds
                   *            positive, required, in range 09999 method plus(Integer
                   *            aNumYears, Integer aNumMonths, Integer aNumDays, Integer
                   *            aNumHours, Integer aNumMinutes, Integer aNumSeconds,
                   *            DayOverflow aDayOverflow)
                   * 
                   
          */
                  DateTime dt = new DateTime("2011-03-31");
                  DateTime result = dt.plus(0, 1, 0, 0, 0, 0, DayOverflow.Spillover);
                  log("date difference : " + result.toString());
                  // result date difference : 2011-05-01 00:00:00
              }

              /** What day is 3 months and 5 days from today? */
              private void whenIs3Months5DaysFromToday() {
                  DateTime today = DateTime.today(TimeZone.getDefault());
                  DateTime result = today.plus(0, 3, 5, 0, 0, 0,
                          DateTime.DayOverflow.FirstDay);
                  log("3 months and 5 days from today is : "
                          + result.format("YYYY-MM-DD"));
                  // result 3 months and 5 days from today is : 2012-07-17
              }

              /**
               * Current number of hours difference between Paris, France and Perth,
               * Australia.
               
          */
              private void hoursDifferenceBetweenParisAndPerth() {
                  // this assumes the time diff is a whole number of hours; other styles
                  
          // are possible
                  DateTime paris = DateTime.now(TimeZone.getTimeZone("Europe/Paris"));
                  DateTime perth = DateTime.now(TimeZone.getTimeZone("Australia/Perth"));
                  int result = perth.getHour() - paris.getHour();
                  if (result < 0) {
                      result = result + 24;
                  }
                  log("Numbers of hours difference between Paris and Perth : " + result);
                  // result Numbers of hours difference between Paris and Perth : 6
              }

              /** How many weeks is it since Sep 6, 2010? */
              private void weeksSinceStart() {
                  DateTime today = DateTime.today(TimeZone.getDefault());
                  DateTime startOfProject = DateTime.forDateOnly(2010, 9, 6);
                  int result = today.getWeekIndex() - startOfProject.getWeekIndex();
                  log("The number of weeks since Sep 6, 2010 : " + result);
                  // result The number of weeks since Sep 6, 2010 : 83
              }

              /** How much time till midnight? */
              private void timeTillMidnight() {
                  DateTime now = DateTime.now(TimeZone.getDefault());
                  DateTime midnight = now.plusDays(1).getStartOfDay();
                  long result = now.numSecondsFrom(midnight);
                  log("This many seconds till midnight : " + result);
                  // result This many seconds till midnight : 83046
              }

              /** Format using ISO style. */
              private void imitateISOFormat() {
                  DateTime now = DateTime.now(TimeZone.getDefault());
                  log("Output using an ISO format: " + now.format("YYYY-MM-DDThh:mm:ss"));
                  // result Output using an ISO format: 2012-04-12T00:55:54
              }

              private void firstDayOfThisWeek() {
                  DateTime today = DateTime.today(TimeZone.getDefault());
                  DateTime firstDayThisWeek = today; // start value
                  int todaysWeekday = today.getWeekDay();
                  int SUNDAY = 1;
                  if (todaysWeekday > SUNDAY) {
                      int numDaysFromSunday = todaysWeekday - SUNDAY;
                      firstDayThisWeek = today.minusDays(numDaysFromSunday);
                  }
                  log("The first day of this week is : " + firstDayThisWeek);
                  // result The first day of this week is : 2012-04-08
              }

              /** For how many years has the JDK date-time API been suctorial? */
              private void jdkDatesSuctorial() {
                  DateTime today = DateTime.today(TimeZone.getDefault());
                  DateTime jdkFirstPublished = DateTime.forDateOnly(1996, 1, 23);
                  int result = today.getYear() - jdkFirstPublished.getYear();
                  log("The number of years the JDK date-time API has been suctorial : "
                          + result);
                  // result The number of years the JDK date-time API has been suctorial :
                  
          // 16
              }
          }

          posted on 2012-04-12 01:05 kohri 閱讀(2836) 評論(0)  編輯  收藏 所屬分類: JAVA


          只有注冊用戶登錄后才能發表評論。


          網站導航:
          博客園   IT新聞   Chat2DB   C++博客   博問  
           

          導航

          <2012年4月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          統計

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 长兴县| 赞皇县| 肃南| 绍兴市| 辽中县| 叶城县| 杭锦旗| 崇左市| 浪卡子县| 镇赉县| 长泰县| 米易县| 荔波县| 松潘县| 德阳市| 广水市| 红安县| 新巴尔虎左旗| 东莞市| 临沭县| 通辽市| 明光市| 承德县| 霍城县| 彭山县| 昌邑市| 鞍山市| 马山县| 读书| 南充市| 肥乡县| 永新县| 榕江县| 裕民县| 锡林郭勒盟| 普定县| 古浪县| 手游| 浑源县| 抚远县| 尤溪县|