目錄
在java中獲取日期時間相關的Date類和抽象類Calendar 以及格式化時間的類SimpDateFormat。Date類中的大部分方法都已經過時了。在java1.8后又新增了處理時間相關的類(java.time包)且該包下所有的類都是不可變類型且線程安全。
- Instant 瞬時實例
- LocalDate 本地日期,不包含具體時間
- LocalTime 本地時間,不包含日期
- LocalDateTime 日期和時間,不包含時差和時區信息
- ZonedDateTime 完整的日期和時間,包含時區和時差信息
一、Date類(java.util.date)
使用date類獲取時可以使用toString()方法,將 Date 對象轉換為 String: dow mon dd hh:mm:ss zzz yyyy形式 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。
// 時間以1970 年 1 月 1 日 00:00:00 GMT 為基准來計算
Date date = new Date(); //內部調用的是System的currentTimeMillis()方法
Date d = new Date(1432356666666L); //某一時間的毫秒數
System.out.println(date.toString()); // Mon Jul 23 21:56:29 CST 2018
System.out.println(d.toString()); // Sat May 23 12:51:06 CST 2015
System.out.println(System.currentTimeMillis()); // 當前系統時間的毫秒數
System.out.println(date.getTime()); // 當前系統時間的毫秒數
// 日期時間的比較
System.out.println(date.after(d)); //true date在指定時間之后則返回 true
System.out.println(date.before(d));//false date在指定時間之前則返回 true
System.out.println(date.equals(d));//false 比較兩個日期的相等性
System.out.println(date.compareTo(d)); // 1
// 比較當調用此方法的Date對象和指定日期。
// 兩者相等時候返回0。
// 調用對象在指定日期之前則返回負數。
// 調用對象在指定日期之后則返回正數。
System.out.println(date.toInstant()); // 2018-07-23T14:28:17.211Z
二、Calendar類(java.util.Calendar)
Calendar類是一個抽象類,可以方便的設置和獲取日期數據的特定部分。它還有個已知的子類GregorianCalendar。
Calendar中的靜態常量(常用的):
常量 | 描述 |
---|---|
Calendar.AM | 從午夜到中午之前這段時間的 AM_PM 字段值 |
Calendar.PM | 從中午到午夜之前這段時間的 AM_PM 字段值 |
Calendar.YEAR | 年份 |
Calendar.MONTH | 月份 |
Calendar.DATE | 日期 |
Calendar.HOUR | 小時(12小時制) |
Calendar.MINUTE | 分鍾 |
Calendar.SECOND | 秒 |
Calendar.WEEK_OF_YEAR | 年內的某星期 |
Calendar.WEEK_OF_MONTH | 月內的某星期 |
Calendar.DAY_OF_YEAR | 年內的某天 |
Calendar.DAY_OF_MONTH | 月內的某天 |
Calendar.DAY_OF_WEEK | 星期內的某天(從周日開始計算) |
Calendar.HOUR_OF_DAY | 小時(24小時制) |
獲取當前相關日期時間相關的例子:
Calendar c = Calendar.getInstance(); // 獲取當前時間的日歷對象
Calendar c1 = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00")); //獲取東八區的日歷實例對象
System.out.println(c.get(Calendar.YEAR)); // 2018 年份
System.out.println(c.get(Calendar.MONTH)+1);// 7 月份,需要+1
System.out.println(c.get(Calendar.DATE)); // 23 日期
System.out.println(c.get(Calendar.AM_PM)); // 1 AM=0, PM=1
System.out.println(c.get(Calendar.HOUR)); // 10 小時
System.out.println(c.get(Calendar.MINUTE)); // 32 分鍾
System.out.println(c.get(Calendar.SECOND)); // 50 秒
System.out.println(c.get(Calendar.MILLISECOND)); // 570 毫秒
//--------------------------------------------------------------------------
System.out.println(c.toString()); // 返回此日歷的字符串表示形式
System.out.println(c.getTime()); // 返回一個Date類型的時間 Tue Jul 24 22:00:44 CST 2018
System.out.println(c.getTimeInMillis()); // 返回當前時間的毫秒數
System.out.println(c.getTimeZone().getDisplayName()); // 中國標准時間 默認區域的用戶的時區名稱
System.out.println(c.getTimeZone().getID()); // Asia/Shanghai 返回時區ID
System.out.println(c.getMaximum(Calendar.HOUR)); // 11 返回小時中最大的數
實例:
判斷是否為閏年
- 方法一
// 是Calendar具體的子類,提供了一個判斷閏年的方法
GregorianCalendar gc = new GregorianCalendar();
System.out.println(gc.isLeapYear(2018)? " 是閏年":" 是平年");
- 方法二
//滿足條件之一: 1、能被4整除但不能被100整除2、能被400整 除
Scaner s =new Scanner(System.in);
System.out.println("請輸入年份:");
long n = s.nextLong();
if((n%4 ==0 && n%100 !=0) || n%400 ==0 ){
System.out.println("是閏年");
}else {
System.out.println("是平年");
}
三、SimpleDateFormat類(java.text.SimpleDateFormat)
SimpleDateFormat繼承抽象類 DateFormat。 是一個以與語言環境有關的方式來格式化和解析日期的具體類,且非線程安全。它允許進行格式化(日期 -> 文本)、解析(文本 -> 日期)和規范化。使得可以選擇任何用戶定義的日期-時間格式的模式。
日期和時間的格式化編碼:
字母 | 描述 | 表示 | 示例 |
---|---|---|---|
y | 年份 | Year | 2018;18 |
M | 月份 | Month | July; Jul; 07 |
d | 月內的日期 | Number | 10 |
h | 12小時制(1~12) | Number | 12 |
H | 24小時制 (0~23) | Number | 22 |
m | 分鍾數 | Number | 30 |
s | 秒數 | Number | 55 |
S | 毫秒數 | Number | 234 |
E | 星期幾 | Text | Tuesday |
D | 年內的天數 | Number | 180 |
F | 月內的星期 | Number | 2 (second Wed. in July) |
w | 年內的周數 | Number | 40 |
W | 月內的周數 | Number | 1 |
a | AM/PM 標記 | Text | PM |
k | 24小時制(1~24) | Number | 24 |
K | 12小時制(0~11) | Number | 10 |
z | 時區 | General time zone | Eastern Standard Time |
上述的模式字母通常是重復的,其數量確定其精確表示:
- Text:格式化來說,字母數量大於等於4,則使用完全形式;否則,在可用的情況下使用短形式或縮寫形式。解析來說,兩種形式都是可接受的,與字母的數量無關
- Number:格式化來說,字母的數量是最小的數位,如果數位不夠,則用 0 填充以達到此數量。解析來說,字母的數量被忽略,除非必須分開兩個相鄰字段。
- Year:格式器的 Calendar 是格里高利歷,則應用以下規則:
格式化來說,如果字母的數量為 2,則年份截取為 2 位數,否則將年份解釋為 number。
解析來說,如果字母的數量大於 2,則年份照字面意義進行解釋,而不管數位是多少. - Month: 如果字母的數量為 3 或大於 3,則將月份解釋為 text;否則解釋為 number。
- General time zone: 如果時區有名稱,則將它們解釋為 text。
實例:
// 假設不加Locale.ENGLISH,默認則以本系統語言(中文)顯示
Date d = new Date();
// 年份,月份,日,星期,小時,分鍾,秒全顯示(數位不夠,則用 0 填充)。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd a EEEE hh:mm:ss.SSS z ",Locale.ENGLISH);
System.out.println(sdf.format(d)); // 2018/07/08 PM Sunday 01:02:24.562 CST
// 年份只取后兩位,月份為Text且簡寫
SimpleDateFormat sdf1 = new SimpleDateFormat("yy/M/d a E h:m:s.S z ",Locale.ENGLISH);
System.out.println(sdf1.format(d)); // 18/7/8 PM Sun 1:2:24.562 CST
//--------------------------------------------------------------
//使用printf()方法
System.out.printf("%tc%n",d); // 星期六 七月 08 13:02:24 CST 2018
System.out.printf("%tF%n",d); // 2018-07-08
System.out.printf("%tD%n",d); // 07/08/18
System.out.printf("%tT%n",d); // 13:02:24
System.out.printf("%tr%n",d); // 01:02:24 下午
System.out.printf("%tR%n",d); // 13:02
四、java.time包下相關的類
在最開始也講了這幾個日期時間相關的類的含義,從字面的意思也可以看出這幾個類是逐漸的獲取更詳細的信息。
System.out.println(Instant.now()); // 從系統時鍾獲取當前瞬間
System.out.println(LocalDate.now()); // 從默認時區的系統時鍾獲取當前日期
System.out.println(LocalTime.now()); // 從默認時區的系統時鍾獲取當前時間
System.out.println(LocalDateTime.now()); // 從默認時區的系統時鍾獲取當前日期和時間
System.out.println(ZonedDateTime.now());//從默認時區的系統時鍾獲取當前的日期時間時差時區
/*結果:
2018-07-08T08:08:46.701Z
2018-07-08
16:08:46.988
2018-07-08T16:08:46.988
2018-07-08T16:08:46.989+08:00[Asia/Shanghai]
*/
// 源碼是通過((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0)來判斷
System.out.println(LocalDate.now().isLeapYear()); // 判斷系統的年份是否為閏年