Java常用API(二)
9.4.2 第二代日期時間(JDK1.1)
1、java.util.TimeZone
通常,使用 getDefault 獲取 TimeZone,getDefault 基于程序運行所在的時區創建 TimeZone。
也可以用 getTimeZone 及時區 ID 獲取 TimeZone 。例如美國太平洋時區的時區 ID 是 "America/Los_Angeles"。

package com.atguigu.datetime.two;
import org.junit.Test;
import java.util.TimeZone;
public class TestTimeZone {
@Test
public void test1(){
TimeZone t = TimeZone.getDefault();
System.out.println(t);
}
@Test
public void test2(){
TimeZone t = TimeZone.getTimeZone("UTC");
System.out.println(t);
}
@Test
public void test3(){
TimeZone t = TimeZone.getTimeZone("America/Los_Angeles");
System.out.println(t);
}
@Test
public void test4(){
String[] all = TimeZone.getAvailableIDs();
for (int i = 0; i < all.length; i++) {
System.out.println(all[i]);
}
}
}
常見時區ID:
Asia/Shanghai
UTC
America/New_York
America/Los_Angeles
2、java.util.Locale
Locale 對象表示了特定的地理、政治和文化地區。需要 Locale 來執行其任務的操作稱為*語言環境敏感的* 操作,它使用 Locale 為用戶量身定制信息。
語言參數是一個有效的 **ISO 語言代碼**。這些代碼是由 ISO-639 定義的小寫兩字母代碼。
國家/地區參數是一個有效的 **ISO 國家/地區代碼**。這些代碼是由 ISO-3166 定義的大寫兩字母代碼。
Locale 類提供了一些方便的常量,可用這些常量為常用的語言環境創建 Locale 對象。
import org.junit.Test;
import java.util.Locale;
public class TestLocale {
@Test
public void test01(){
Locale[] all = Locale.getAvailableLocales();
for (int i = 0; i < all.length; i++) {
System.out.println(all[i]);
}
}
@Test
public void test02(){
Locale china = Locale.CHINA;
System.out.println("china = " + china);
}
}
3、java.util.Calendar
Calendar 類是一個抽象類,它為特定瞬間與一組諸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日歷字段之間的轉換提供了一些方法,并為操作日歷字段(例如獲得下星期的日期)提供了一些方法。瞬間可用毫秒值來表示,它是距*歷元*(即格林威治標準時間 1970 年 1 月 1 日的 00:00:00.000,格里高利歷)的偏移量。與其他語言環境敏感類一樣,Calendar 提供了一個類方法 getInstance,以獲得此類型的一個通用的對象。

修改和獲取 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日歷字段對應的時間值。
void add(int field,int amount)
int get(int field)
void set(int field, int value)
示例代碼:
package com.atguigu.datetime.two;
import org.junit.Test;
import java.util.Calendar;
import java.util.TimeZone;
public class TestCalendar {
@Test
public void test1(){
Calendar c = Calendar.getInstance();
System.out.println(c);
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+1;
int day = c.get(Calendar.DATE);
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
int second = c.get(Calendar.SECOND);
System.out.println(year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second);
}
@Test
public void test2(){
TimeZone t = TimeZone.getTimeZone("America/Los_Angeles");
Calendar c = Calendar.getInstance(t);
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+1;
int day = c.get(Calendar.DATE);
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
int second = c.get(Calendar.SECOND);
System.out.println(year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second);
}
}
9.4.3 第三代日期時間(JDK1.8)
Java1.0中包含了一個Date類,但是它的大多數方法已經在Java 1.1引入Calendar類之后被棄用了。而Calendar并不比Date好多少。它們面臨的問題是:
- 可變性:像日期和時間這樣的類對象應該是不可變的。Calendar類中可以使用三種方法更改日歷字段:set()、add() 和 roll()。
- 偏移性:Date中的年份是從1900開始的,而月份都是從0開始的。
- 格式化:格式化只對Date有用,Calendar則不行。
- 此外,它們也不是線程安全的,不能處理閏秒等。
可以說,對日期和時間的操作一直是Java程序員最痛苦的地方之一。第三次引入的API是成功的,并且java 8中引入的java.time API 已經糾正了過去的缺陷,將來很長一段時間內它都會為我們服務。
Java 8 吸收了 Joda-Time的精華,以一個新的開始為 Java 創建優秀的 API。
- java.time – 包含值對象的基礎包
- java.time.chrono – 提供對不同的日歷系統的訪問。
- java.time.format – 格式化和解析時間和日期
- java.time.temporal – 包括底層框架和擴展特性
- java.time.zone – 包含時區支持的類
Java 8 吸收了 Joda-Time的精華,以一個新的開始為 Java 創建優秀的 API。新的 java.time 中包含了所有關于時鐘(Clock),本地日期(LocalDate)、本地時間(LocalTime)、本地日期時間(LocalDateTime)、時區(ZonedDateTime)和持續時間(Duration)的類。
1、本地日期時間:LocalDate、LocalTime、LocalDateTime
| 序號 | 方法 | 描述 |
|---|---|---|
| 1 | now() / now(ZoneId zone) | 靜態方法,根據當前時間創建對象/指定時區的對象 |
| 2 | of() | 靜態方法,根據指定日期/時間創建對象 |
| 3 | getDayOfMonth()/getDayOfYear() | 獲得月份天數(1-31) /獲得年份天數(1-366) |
| 4 | getDayOfWeek() | 獲得星期幾(返回一個 DayOfWeek 枚舉值) |
| 5 | getMonth() | 獲得月份, 返回一個 Month 枚舉值 |
| 6 | getMonthValue() / getYear() | 獲得月份(1-12) /獲得年份 |
| 7 | getHours()/getMinute()/getSecond() | 獲得當前對象對應的小時、分鐘、秒 |
| 8 | withDayOfMonth()/withDayOfYear()/withMonth()/withYear() | 將月份天數、年份天數、月份、年份修改為指定的值并返回新的對象 |
| 9 | with(TemporalAdjuster t) | 將當前日期時間設置為校對器指定的日期時間 |
| 10 | plusDays(), plusWeeks(), plusMonths(), plusYears(),plusHours() | 向當前對象添加幾天、幾周、幾個月、幾年、幾小時 |
| 11 | minusMonths() / minusWeeks()/minusDays()/minusYears()/minusHours() | 從當前對象減去幾月、幾周、幾天、幾年、幾小時 |
| 12 | plus(TemporalAmount t)/minus(TemporalAmount t) | 添加或減少一個 Duration 或 Period |
| 13 | isBefore()/isAfter() | 比較兩個 LocalDate |
| 14 | isLeapYear() | 判斷是否是閏年(在LocalDate類中聲明) |
import org.junit.Test;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class TestLocalDateTime {
@Test
public void test7(){
LocalDate now = LocalDate.now();
LocalDate before = now.minusDays(100);
System.out.println(before);//2019-02-26
}
@Test
public void test06(){
LocalDate lai = LocalDate.of(2019, 5, 13);
LocalDate go = lai.plusDays(160);
System.out.println(go);//2019-10-20
}
@Test
public void test05(){
LocalDate lai = LocalDate.of(2019, 5, 13);
System.out.println(lai.getDayOfYear());
}
@Test
public void test04(){
LocalDate lai = LocalDate.of(2019, 5, 13);
System.out.println(lai);
}
@Test
public void test03(){
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
}
@Test
public void test02(){
LocalTime now = LocalTime.now();
System.out.println(now);
}
@Test
public void test01(){
LocalDate now = LocalDate.now();
System.out.println(now);
}
}
2、瞬時:Instant、ZondId和ZonedDateTime
常見時區ID:
Asia/Shanghai
UTC
America/New_York
America/Los_Angeles
可以通過ZondId獲取所有可用的時區ID:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Set;
public class TestZone {
@Test
public void test01() {
//需要知道一些時區的id
//Set<String>是一個集合,容器
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
//快捷模板iter
for (String availableZoneId : availableZoneIds) {
System.out.println(availableZoneId);
}
}
@Test
public void test02(){
ZonedDateTime t1 = ZonedDateTime.now();
System.out.println(t1);
ZonedDateTime t2 = ZonedDateTime.now(ZoneId.of("America/New_York"));
System.out.println(t2);
}
@Test
public void test03(){
Instant t = Instant.now();
System.out.println(t);
}
@Test
public void test4(){
//以中國時區獲取當前時間
ZonedDateTime chinaNow = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
//將中國時間轉換為美國紐約時間
ZonedDateTime newYorkNow = chinaNow.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println("中國時區當前時間:" + chinaNow);
System.out.println("將中國時間轉換為美國紐約時間:"+newYorkNow);
}
}
3、持續日期/時間:Period和Duration
Period:用于計算兩個“日期”間隔
Duration:用于計算兩個“時間”間隔
import org.junit.Test;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
public class TestPeriodDuration {
@Test
public void test01(){
LocalDate t1 = LocalDate.now();
LocalDate t2 = LocalDate.of(2018, 12, 31);
Period between = Period.between(t1, t2);
System.out.println(between);
System.out.println("相差的年數:"+between.getYears());
System.out.println("相差的月數:"+between.getMonths());
System.out.println("相差的天數:"+between.getDays());
System.out.println("相差的總數:"+between.toTotalMonths());
}
@Test
public void test02(){
LocalDateTime t1 = LocalDateTime.now();
LocalDateTime t2 = LocalDateTime.of(2017, 8, 29, 0, 0, 0, 0);
Duration between = Duration.between(t1, t2);
System.out.println(between);
System.out.println("相差的總天數:"+between.toDays());
System.out.println("相差的總小時數:"+between.toHours());
System.out.println("相差的總分鐘數:"+between.toMinutes());
System.out.println("相差的總秒數:"+between.getSeconds());
System.out.println("相差的總毫秒數:"+between.toMillis());
System.out.println("相差的總納秒數:"+between.toNanos());
System.out.println("不夠一秒的納秒數:"+between.getNano());
}
}
4、日期時間格式化DateTimeFormatter
該類提供了三種格式化方法:
- 預定義的標準格式。如:ISO_DATE_TIME;ISO_DATE
- 本地化相關的格式。如:ofLocalizedDate(FormatStyle.MEDIUM)、ofLocalizedTime(FormatStyle.MEDIUM)、ofLocalizedDateTime(FormatStyle.MEDIUM)
- 自定義的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
import org.junit.Test;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
public class TestDatetimeFormatter {
@Test
public void test1(){
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter df = DateTimeFormatter.ISO_DATE_TIME;//2019-06-06T16:38:23.756 String str = df.format(now);
System.out.println(str);
}
@Test
public void test2(){
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter df1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);//2019年6月6日 下午04時40分03秒
DateTimeFormatter df2 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);//2019-6-6 16:40:37
DateTimeFormatter df3 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);//19-6-6 下午4:40
DateTimeFormatter df4 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withZone(ZoneId.systemDefault());//注意
String str1 = df1.format(now);
String str2 = df2.format(now);
String str3 = df3.format(now);
String str4 = df4.format(now);
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
System.out.println(str4);
}
@Test
public void test3(){
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy年MM月dd日 aHH點mm分ss秒SSS毫秒 E 是這一年的D天");
String str = df.format(now);
System.out.println(str);
}
@Test
public void test4(){
//String ==> LocalDateTime
DateTimeFormatter dt = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
String str = "2023年3月27日 下午07時26分43秒";
LocalDateTime t = LocalDateTime.from(dt.parse(str));
System.out.println(t);
}
}
9.4.4 三代日期時間的轉換
1、第一代與第二代
import org.junit.Test;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class TestDateTimeChange1 {
@Test
public void test1(){
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
Date now = calendar.getTime();
System.out.println(now);
}
@Test
public void test2(){
Date d = new Date();
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
c.setTime(d);
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+1;
int day = c.get(Calendar.DATE);
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
int second = c.get(Calendar.SECOND);
System.out.println(year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second);
}
}
2、第一代與第三代
- Date與Instant - Date與LocalDateTime
package com.atguigu.review;
import org.junit.Test;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
public class TestDateTimeChange2 {
@Test
public void test1(){
//Date ==> Instant
Date d = new Date();
Instant instant = d.toInstant();
System.out.println(instant);
}
@Test
public void test2(){
//Instant ==> Date
Instant instant = Instant.now();
Date d = Date.from(instant);
System.out.println(d);
}
@Test
public void test3(){
//Date ==> LocalDateTime
Date d = new Date();
LocalDateTime t = LocalDateTime.ofInstant(d.toInstant(), ZoneId.systemDefault());
System.out.println(t);
}
@Test
public void test4(){
LocalDateTime now = LocalDateTime.now();//本地的日期時間對象
Instant instant = now.toInstant(ZoneOffset.of("+08:00"));
Date date = Date.from(instant);//第一代的Date
System.out.println(date);
}
@Test
public void test5(){
//LocalDateTime ==> Date
LocalDateTime now = LocalDateTime.now();//本地的日期時間對象
ZonedDateTime zonedDateTime = now.atZone(ZoneId.systemDefault());//時區的日期時間對象
Instant instant = zonedDateTime.toInstant();//瞬時對象
Date date = Date.from(instant);//第一代的Date
System.out.println(date);
}
}


