歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

使用apache.lang包安全簡潔地操作Java時間

引言

最近偶遇apache開發的工作java工具包,一使用,就發現自己愛上它了。不多說了,下面介紹org.apache.commons.lang3.time包中處理java程序員為之頭疼的時間的類。

附上官網jar包下載地址:http://commons.apache.org/proper/commons-lang/download_lang.cgi

在這之前還是先簡單說一下java本身的時間處理類。

Date

Date的絕大部分 API 都deprecated(過時)了,以下是目前可以使用的     Date()                    代表執行到這句構造函數時的當前時間   Date(long d)              用一個相對於1970 年 1 月 1 日 00:00:00 以來的走過的毫秒數創建時間對象。                           如:new Date()  等價於   new Date(System.currentTimeMillis())   boolean before(Date when)  當前時間對象是否早於 when boolean after(Date when)  當前時間對象是否晚於 when toString() hashCode() equals()    

Calender

Calendar 類是一個抽象類,它為特定瞬間與一組諸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日歷字段之間的轉換提供了一些方法,並為操作日歷字段(例如獲得下星期的日期)提供了一些方法。瞬間可用毫秒值來表示,它是距歷元(即格林威治標准時間 1970 年 1 月 1 日的 00:00:00.000,格裡高利歷)的偏移量。

該類還為實現包范圍外的具體日歷系統提供了其他字段和方法。這些字段和方法被定義為 protected。

具體可見API手冊。

SimpleDateFromat

SimpleDateFromat不是線程安全的,這是因為它繼承了DateFormat中的一個Calendar成員,每次在執行format操作時,都會改成成員calendar的狀態。這就是不安全的根源。

多線程下,很可能對Calendar的寫 和 讀 操作不同步(不是被同一個線程執行的),就會發生意外。

class DateFromat
{
  
protected Calendar calendar;
//... } SimpleDateFromat extends DateFromat {   private StringBuffer format(Date date, StringBuffer toAppendTo,FieldDelegate delegate)   { // Convert input date to time field list calendar.setTime(date);     //.... //....   }
}

下面開始介紹文章的主角類。

DateUtils

提供了對時間對象的運算操作,就像和操作 int 一樣。

工具類,不允許創建實例

//-------------------靜態字段-------------------
public static final long    MILLIS_PER_DAY    =    86400000L  一天的毫秒數
public static final long    MILLIS_PER_HOUR    =    3600000L    一個小時的毫秒數
public static final long    MILLIS_PER_MINUTE  =    60000L      一分鐘的毫秒數
public static final long    MILLIS_PER_SECOND  =    1000L      一秒鐘的毫秒數



//-------------------靜態方法------------------

Date的運算和修改


static Date    addDays(Date date, int amount)          返回一個date 時間對象 添加 amount 天 後的新的Date 對象
static Date    addHours(Date date, int amount)        返回一個date 時間對象 添加 amount h 後的新的Date 對象
static Date    addMilliseconds(Date date, int amount)  返回一個date 時間對象 添加 amount 毫秒 後的新的Date 對象
static Date    addMinutes(Date date, int amount)      返回一個date 時間對象 添加 amount 分鐘 後的新的Date 對象
static Date    addMonths(Date date, int amount)      返回一個date 時間對象 添加 amount 月 後的新的Date 對象
static Date    addSeconds(Date date, int amount)      返回一個date 時間對象 添加 amount 秒 後的新的Date 對象
static Date    addWeeks(Date date, int amount)        返回一個date 時間對象 添加 amount 周 後的新的Date 對象
static Date    addYears(Date date, int amount)        返回一個date 時間對象 添加 amount 年 後的新的Date 對象

static Date    setDays(Date date, int amount)          修改一個Date 對象的 天數 並返回新的Date對象。
static Date    setHours(Date date, int amount)        修改一個Date 對象的 小時字段並返回新的Date 
static Date    setMilliseconds(Date date, int amount)  修改一個Date 對象的 毫秒,並返回新的Date 對象
static Date    setMinutes(Date date, int amount)        修改一個Date 對象的 分鐘
static Date    setMonths(Date date, int amount)        修改月份
static Date    setSeconds(Date date, int amount)        修改秒
static Date    setYears(Date date, int amount)          修改 年



字符串------>Date

從一個字符串str中按照 給定的字符串時間格式(見文章最後的SimpleDateFormat表),解析出一個時間對象。
可以給定多個字符串時間格式,依次嘗試解析,如果都不能正確解析,則拋出java.text.ParseException異常。

DateUtils.parseDate("10-05-2016 12:45",Locale.CHINA, "dd-MM-yyyy HH:mm")


static Date  parseDate(String str, Locale locale, String... parsePatterns)

static Date  parseDate(String str, String... parsePatterns)

static Date  parseDateStrictly(String str, Locale locale, String... parsePatterns)
static Date  parseDateStrictly(String str, String... parsePatterns)






對時間的向上取整,截斷,四捨五入,和 對浮點數的操作機制一樣。
對一個時間對象的某個字段進行向上取整。 filed指定取整的字段,可以取的值為

Calendar.SECOND

Calendar.MINUTE
Calendar.HOUR_OF_DAY
Calendar.DAY_OF_MONTH
Calendar.MONTH
Calendar.YEAR  等...


如時間為:2016-2-12 22:17:48,若對年進行向上取整(ceiling),則看傳入的參數的月份,為2,向上取值為年底,則會變為2017年
2017-1-1 0:00:00

如時間為:2016-2-25 22:17:48,若對月進行截斷取整(truncate),則看傳入的參數的天,為12,直接丟棄,則會變為本月第一天
2016-2-1 0:00:00

static Calendar  ceiling(Calendar date, int field)
static Date      ceiling(Date date, int field)



static Calendar  round(Calendar date, int field)      和ceil同理,round 是四捨五入
static Date     round(Date date, int field)



static Calendar truncate(Calendar date, int field)    對一個時間對象的某個字段進行截斷。
static Date     truncate(Date date, int field)



static int    truncatedCompareTo(Calendar cal1, Calendar cal2, int field)      2個時間對象截斷某個字段後比較,前者小返回-1,相同返回0,否則返回1
static int    truncatedCompareTo(Date date1, Date date2, int field)



static boolean    truncatedEquals(Calendar cal1, Calendar cal2, int field)    2個時間對象截斷某個字段後比較,相同返回true,否則返回false
static boolean    truncatedEquals(Date date1, Date date2, int field)


將Date 轉換為Calendar
static Calendar    toCalendar(Date date) 



時間 對象的 想等/相近 比較
static boolean    isSameDay(Calendar cal1, Calendar cal2)        是否是同一天,而不在乎具體時間,如 2月12 18:00 和 2月12 23:35 都是一天
static boolean    isSameDay(Date date1, Date date2)              是否是同一天,而不在乎具體時間,如 2月12 18:00 和 2月12 23:35 都是一天
static boolean    isSameInstant(Calendar cal1, Calendar cal2)    是否完全代表同一個時刻,相同。
static boolean    isSameInstant(Date date1, Date date2)          是否完全代表同一個時刻,相同。

DateFormatUtils

將時間轉化為字符串的工具類。不可實例化對象。

線程安全。

這個類中的所有重載的format 實質都是調了下面2個函數。而這2個函數中又借用了FastDateFormat的API。

FastDateFormat是apache time util  優於Java  SimpleDateFormat 的核心類。它是線程安全的。

public static String format(final Date date, final String pattern, final TimeZone timeZone, final Locale locale) {
    final FastDateFormat df = FastDateFormat.getInstance(pattern, timeZone, locale);
    return df.format(date);
}

    
    
public static String format(final Calendar calendar, final String pattern, final TimeZone timeZone, final Locale locale) {
    final FastDateFormat df = FastDateFormat.getInstance(pattern, timeZone, locale);
    return df.format(calendar);
}
   
時間參數  可以是Date 對象  ,Calender 對象  ,或者一個相對於1970年的long整數

pattern ,如:"yyyy-MM-dd HH:mm:ss"    參見文章最後SimpleDateFormat格式表

Locale:地理,政治和文化地區 如Locale.CHINA

TimeZone:時區偏移量.     
   TimeZone.getTimeZone("GMT+:08:00");   北京時間
   TimeZone.getDefault()                 默認



static String     format(Calendar calendar, String pattern)

static String     format(Calendar calendar, String pattern, Locale locale)

static String     format(Calendar calendar, String pattern, TimeZone timeZone)

static String     format(Calendar calendar, String pattern, TimeZone timeZone, Locale locale)

static String     format(Date date, String pattern)

static String     format(Date date, String pattern, Locale locale)

static String     format(Date date, String pattern, TimeZone timeZone)

static String     format(Date date, String pattern, TimeZone timeZone, Locale locale)

static String     format(long millis, String pattern)

static String     format(long millis, String pattern, Locale locale)

static String     format(long millis, String pattern, TimeZone timeZone)

static String     format(long millis, String pattern, TimeZone timeZone, Locale locale)

static String     formatUTC(Date date, String pattern)

static String     formatUTC(Date date, String pattern, Locale locale)

static String     formatUTC(long millis, String pattern)

static String     formatUTC(long millis, String pattern, Locale locale)

DateUtils 在parse時內部利用了java自身的SimpleDateFormat(即便如此,DateUtils的操作都是是線程安全的,因為SimpleDateFromat是作為方法的局部變量使用的),而 DateFormatUtils 利用了apache開發的線程安全的FastDateFromat。因此,DateUtils和DateFormatUtils可以滿足簡單的時間操作了。如果需要更多的定制化操作,就可能需要

下面介紹的FastDateFormat了。

FastDateFormat

 FastDateFormat是一個快速 且 線程安全的時間操作類,它完全可以替代SimpleDateFromat。

 因為是線程安全的,所以你可以把它作為一個類的靜態字段使用

 構造函數為protected,不允許直接構造它的對象,可以通過工廠方法獲取。

FastDateFormat之所以是線程安全的,是因為這個類是無狀態的:內部的成員在構造時就完成了初始化,並在對象存活期,不提供任何API供外界修改他們。

FastDateFormat內部有很重要的2個對象:

  • FastDateParser
  • FastDatePrinter

分別完成解析和format工作。他們也都是線程安全的,都修飾為final。有興趣的可以取讀源代碼。

靜態字段

用於構造時,控制時間或者日期顯示的完整性,FULL最完整,SHORT最次。
static int    FULL      表示完全顯示

static int    LONG     

static int    MEDIUM 

static int    SHORT   

構造

static FastDateFormat    getDateInstance(int style)
static FastDateFormat    getDateInstance(int style, Locale locale)
static FastDateFormat    getDateInstance(int style, TimeZone timeZone)
static FastDateFormat    getDateInstance(int style, TimeZone timeZone, Locale locale)

只控制日期顯示格式

使用style指定的日期顯示的完整性,靜態字段提供
timeZone 指定時區,若不指定,則使用系統默認的
locale  指定 國家區域,若不指定,則使用系統默認的




static FastDateFormat    getInstance()
static FastDateFormat    getInstance(String pattern)
static FastDateFormat    getInstance(String pattern, Locale locale)
static FastDateFormat    getInstance(String pattern, TimeZone timeZone)
static FastDateFormat    getInstance(String pattern, TimeZone timeZone, Locale locale)

通過String類型的pattern自定義顯示格式
String類型的pattern 指定format格式,參見SimpleDateFormat
timeZone 指定時區,若不指定,則使用系統默認的
locale  指定 國家區域,若不指定,則使用系統默認的

static FastDateFormat    getDateTimeInstance(int dateStyle, int timeStyle)
static FastDateFormat    getDateTimeInstance(int dateStyle, int timeStyle, Locale locale)
static FastDateFormat    getDateTimeInstance(int dateStyle, int timeStyle, TimeZone timeZone)
static FastDateFormat    getDateTimeInstance(int dateStyle, int timeStyle, TimeZone timeZone, Locale locale)
同時控制 日期和 時間的顯示格式

使用style指定的日期和時間顯示的完整性,靜態字段提供


StringBuffer    format(Date date, StringBuffer buf)
StringBuffer    format(long millis, StringBuffer buf)
StringBuffer    format(Calendar calendar, StringBuffer buf)
將格式化後的字符串寫入到一個StringBuffer對象中


String    format(long millis)
String    format(Date date)
String    format(Calendar calendar)

Date    parse(String source)
Date    parse(String source, ParsePosition pos)
從字符串解析一個Date,解析的模式是構造時決定的

String    getPattern()  獲取fommat時的pattern

TimeZone  getTimeZone()   

Locale    getLocale()

例子:

import java.util.Date;
import java.util.Locale;

import org.apache.commons.lang3.time.FastDateFormat;


/**
 * 當使用FastDateFormat.getInstance()構造時,需要和SimpleDateFomat一樣,自定義格式化字符串。
 * 當使用FastDateFormat.getDateTimeInstance() 構造時,需要 FastDateFormat的4個靜態字段指定日期 和 時間顯示的具體程度
 * 當使用FastDateFormat.getDateInstance() 構造時,意為著你只想顯示日期,需要 FastDateFormat的4個靜態字段指定日期的顯示的具體程度
 *
 */

public class Test {

    
    public static void showCustom()
    {
        
        String pattern = "yyyy-MM-dd HH:mm:ss";
        
        final FastDateFormat df = FastDateFormat.getInstance(pattern);
        
        System.out.println(df.format(new Date()));
        
    }
    
    public static void showDateAndTime()
    {
        final FastDateFormat df = FastDateFormat.getDateTimeInstance(FastDateFormat.FULL,
                                                                    FastDateFormat.FULL,
                                                                    Locale.CHINA);
        System.out.println(df.format(new Date()));
         
        
    }
    public static void showDate()
    {
        final FastDateFormat df = FastDateFormat.getDateInstance(FastDateFormat.LONG, Locale.CHINA);
        
        System.out.println(df.format(new Date()));
        
    }
    
    
    
    
    public static void main(String[] args) 
    {
        
        showCustom();
        
        showDateAndTime();
        
        showDate();
        
        
        /*Output
         * 
         *  2016-10-15 16:18:49
            2016年10月15日 星期六 下午04時18分49秒 CST
            2016年10月15日

         */
        
    }

}

 SimpleDateFormat的時間字符串表達模式定義表

LetterDate or Time ComponentPresentationExamples G Era designator Text AD y Year Year 199696 Y Week year Year 200909 M Month in year (context sensitive) Month JulyJul07 L Month in year (standalone form) Month JulyJul07 w Week in year Number 27 W Week in month Number 2 D Day in year Number 189 d Day in month Number 10 F Day of week in month Number 2 E Day name in week Text TuesdayTue u Day number of week (1 = Monday, ..., 7 = Sunday) Number 1 a Am/pm marker Text PM H Hour in day (0-23) Number 0 k Hour in day (1-24) Number 24 K Hour in am/pm (0-11) Number 0 h Hour in am/pm (1-12) Number 12 m Minute in hour Number 30 s Second in minute Number 55 S Millisecond Number 978 z Time zone General time zone Pacific Standard TimePSTGMT-08:00 Z Time zone RFC 822 time zone -0800 X Time zone ISO 8601 time zone -08-0800-08:00

Copyright © Linux教程網 All Rights Reserved