時間相關java
DateFormatUtils – 提供格式化日期和時間的功能及相關常量;api
DateUtils – 在Calendar和Date的基礎上提供更方便的訪問;安全
DurationFormatUtils – 提供格式化時間跨度的功能及相關常量;app
FastDateFormat – 爲java.text.SimpleDateFormat提供一個的線程安全的替代類;函數
FormatCache -ui
StopWatch – 是一個方便的計時器。this
常見名詞spa
UTC:協調世界時(標準時間)操作系統
GMT:格林尼治標準時(世界時)線程
CST:美國/中國中央 (打印Date能看見),屬於時區三字母id,被廢了
DST夏日節約時間,北京時間等特殊時間
時間戳:1970年1月1日(08:00:00 GMT)至當前時間的總秒數,unix發行時間,也被稱爲 Unix 時間戳
通常咱們用的是北京時間=UTC+8=GMT+8
引用:
import java.text.ParseException; // 解析時出現意外錯誤。 import java.text.ParsePosition; //Format 及其子類所使用的簡單類 import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Iterator; //迭代器 import java.util.NoSuchElementException;//枚舉中沒有更多的元素
能夠看到是對Date的封裝,首先要簡單的瞭解Date/Calendar/SimpleDateFormat
java.util.Date
api描述:
在 JDK 1.1 以前,類 Date
有兩個其餘的函數。它容許把日期解釋爲年、月、日、小時、分鐘和秒值。它也容許格式化和解析日期字符串。不過,這些函數的 API 不易於實現國際化。從 JDK 1.1 開始,應該使用 Calendar
類實現日期和時間字段之間轉換,使用 DateFormat
類來格式化和解析日期字符串。Date
中的相應方法已廢棄。
儘管 Date
類打算反映協調世界時 (UTC),但沒法作到如此準確,這取決於 Java 虛擬機的主機環境。當前幾乎全部操做系統都假定 1 天 = 24 × 60 × 60 = 86400 秒。但對於 UTC,大約每一兩年出現一次額外的一秒,稱爲「閏秒」。閏秒始終做爲當天的最後一秒增長,而且始終在 12 月 31 日或 6 月 30 日增長。例如,1995 年的最後一分鐘是 61 秒,由於增長了閏秒。大多數計算機時鐘不是特別的準確,所以不能反映閏秒的差異。
補充:廢除的差很少了,一般也就new Date()一下
java.util.Calendar
api描述:
Calendar
類是一個抽象類,它爲特定瞬間與一組諸如 YEAR
、MONTH
、DAY_OF_MONTH
、HOUR
等 日曆字段之間的轉換提供了一些方法,併爲操做日曆字段(例如得到下星期的日期)提供了一些方法。瞬間可用毫秒值來表示,它是距曆元(即格林威治標準時間 1970 年 1 月 1 日的 00:00:00.000,格里高利曆)的偏移量。
補充:代替Date,改變時間也很方便,經常使用set/add
打印以下,能夠看到徹底的與樣式分離(date有默認樣式)
java.util.GregorianCalendar[time=1388458208688,areFieldsSet=true,areAllFieldsSet=true,lenient=true,
zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,
transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2013,
MONTH=11,WEEK_OF_YEAR=1,WEEK_OF_MONTH=5,DAY_OF_MONTH=31,DAY_OF_YEAR=365,
DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=5,AM_PM=0,HOUR=10,HOUR_OF_DAY=10,MINUTE=50,
SECOND=8,MILLISECOND=688,ZONE_OFFSET=28800000,DST_OFFSET=0]
----------------------時間樣式
java.text.DateFormat
api描述:
DateFormat 是日期/時間格式化子類的抽象類,它以與語言無關的方式格式化並解析日期或時間。日期/時間格式化子類(如 SimpleDateFormat)容許進行格式化(也就是日期 -> 文本)、解析(文本-> 日期)和標準化。將日期表示爲 Date
對象,或者表示爲從 GMT(格林尼治標準時間)1970 年 1 月 1 日 00:00:00 這一刻開始的毫秒數。
java.text.SimpleDateFormat
api描述:
SimpleDateFormat
是一個以與語言環境有關的方式來格式化和解析日期的具體類。它容許進行格式化(日期 -> 文本)、解析(文本 -> 日期)和規範化。
大多數狀況下仍是選擇用SimpleDateFormat
,初始化話格式後new SimpleDateFormat("yyyyMMdd");在format(渲染/格式話)一下就完成了
DateUtils提供方法
1.判斷
isSameDay:判斷2時間是否爲同一天
isSameInstant:判斷是否爲同一瞬間(比較時間戳)
isSameLocalTime:判斷是否爲本地時間(分別比較,且要求同一實現類)
public static boolean isSameDay(Calendar cal1, Calendar cal2) { if (cal1 == null || cal2 == null) { throw new IllegalArgumentException("The date must not be null"); } return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) && //公元先後 cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&//年 cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));//第幾天 }
public static boolean isSameInstant(Calendar cal1, Calendar cal2) { if (cal1 == null || cal2 == null) { throw new IllegalArgumentException("The date must not be null"); } return cal1.getTime().getTime() == cal2.getTime().getTime(); //cal1.getTime()-》Date,比較的是時間戳 }
public static boolean isSameLocalTime(Calendar cal1, Calendar cal2) { if (cal1 == null || cal2 == null) { throw new IllegalArgumentException("The date must not be null"); } return (cal1.get(Calendar.MILLISECOND) == cal2.get(Calendar.MILLISECOND) && cal1.get(Calendar.SECOND) == cal2.get(Calendar.SECOND) && cal1.get(Calendar.MINUTE) == cal2.get(Calendar.MINUTE) && cal1.get(Calendar.HOUR_OF_DAY) == cal2.get(Calendar.HOUR_OF_DAY) && cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR) && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) && cal1.getClass() == cal2.getClass()); //同一實現類 }
2.解析 date->>text
parseDate(String str, String... parsePatterns)
parseDateStrictly(String str, String... parsePatterns)
將格式如parsePatterns的str解析爲Date,其中Strictly表明嚴格
String[] pattern = new String[] {"yyyy-MM-dd"}; DateUtils.parseDate("2011-1-32", pattern); //Tue Feb 01 00:00:00 CST 2011 DateUtils.parseDateStrictly("2011-1-32", pattern);// throws ParseException
private static Date parseDateWithLeniency( String str, String[] parsePatterns, boolean lenient) throws ParseException { if (str == null || parsePatterns == null) { throw new IllegalArgumentException("Date and Patterns must not be null"); } SimpleDateFormat parser = new SimpleDateFormat(); parser.setLenient(lenient); //是否嚴格 ParsePosition pos = new ParsePosition(0); for (String parsePattern : parsePatterns) { //循環全部樣式 String pattern = parsePattern; // LANG-530 - need to make sure 'ZZ' output doesn't get passed to SimpleDateFormat if (parsePattern.endsWith("ZZ")) { pattern = pattern.substring(0, pattern.length() - 1); } parser.applyPattern(pattern); pos.setIndex(0); String str2 = str; // LANG-530 - need to make sure 'ZZ' output doesn't hit SimpleDateFormat as it will ParseException if (parsePattern.endsWith("ZZ")) { str2 = str.replaceAll("([-+][0-9][0-9]):([0-9][0-9])$", "$1$2"); } Date date = parser.parse(str2, pos); if (date != null && pos.getIndex() == str2.length()) { return date; } } throw new ParseException("Unable to parse the date: " + str, -1); }
3.add系列/set系列
private static Date add(Date date, int calendarField, int amount) { if (date == null) { throw new IllegalArgumentException("The date must not be null"); } Calendar c = Calendar.getInstance(); c.setTime(date); c.add(calendarField, amount); return c.getTime(); }
private static Date set(Date date, int calendarField, int amount) { if (date == null) { throw new IllegalArgumentException("The date must not be null"); } // getInstance() returns a new object, so this method is thread safe. Calendar c = Calendar.getInstance(); c.setLenient(false);//寬鬆型 c.setTime(date); c.set(calendarField, amount); return c.getTime(); }
4.toCalendar:另外一種建立方法
public static Calendar toCalendar(Date date) { Calendar c = Calendar.getInstance(); c.setTime(date); return c; }
5.
round(Date date, int field) :四捨五入,field爲字段(泛型),精確到的值,使用了clone,線程安全
truncate(Date date, int field):全舍
ceiling(Date date, int field):全入
... if (MODIFY_TRUNCATE == modType || millisecs < 500) {//若是爲truncate,就減去500毫秒在四捨五入 time = time - millisecs; } if (field == Calendar.SECOND) { done = true; } // truncate seconds int seconds = val.get(Calendar.SECOND); if (!done && (MODIFY_TRUNCATE == modType || seconds < 30)) { time = time - (seconds * 1000L); } if (field == Calendar.MINUTE) { done = true; } // truncate minutes int minutes = val.get(Calendar.MINUTE); if (!done && (MODIFY_TRUNCATE == modType || minutes < 30)) { time = time - (minutes * 60000L); } ...
6.
iterator(Date focus, int rangeStyle):根據rangeStyle返回Calendar集合範圍(求一週/月等)
RANGE_MONTH_SUNDAY和RANGE_MONTH_MONDAY都是取focus所在月份一個月的天數,RANGE_MONTH_SUNDAY每個月從SUNDAY開始,RANGE_MONTH_MONDAY每個月從MONDAY開始RANGE_WEEK_SUNDAY都是取1周(7天)的天數,RANGE_WEEK_RELATIVE從focus開始取7天,RANGE_WEEK_CENTER從focus所在星期的星期一開始取7天。