Java常用API(二)
9.4.2 第二代日期時(shí)間(JDK1.1)
1、java.util.TimeZone
通常,使用 getDefault
獲取 TimeZone
,getDefault
基于程序運(yùn)行所在的時(shí)區(qū)創(chuàng)建 TimeZone
。
也可以用 getTimeZone
及時(shí)區(qū) ID 獲取 TimeZone
。例如美國(guó)太平洋時(shí)區(qū)的時(shí)區(qū) 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]);
}
}
}
常見時(shí)區(qū)ID:
Asia/Shanghai
UTC
America/New_York
America/Los_Angeles
2、java.util.Locale
Locale
對(duì)象表示了特定的地理、政治和文化地區(qū)。需要 Locale
來(lái)執(zhí)行其任務(wù)的操作稱為*語(yǔ)言環(huán)境敏感的* 操作,它使用 Locale
為用戶量身定制信息。
語(yǔ)言參數(shù)是一個(gè)有效的 **ISO 語(yǔ)言代碼**。這些代碼是由 ISO-639 定義的小寫兩字母代碼。
國(guó)家/地區(qū)參數(shù)是一個(gè)有效的 **ISO 國(guó)家/地區(qū)代碼**。這些代碼是由 ISO-3166 定義的大寫兩字母代碼。
Locale
類提供了一些方便的常量,可用這些常量為常用的語(yǔ)言環(huán)境創(chuàng)建 Locale
對(duì)象。
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
類是一個(gè)抽象類,它為特定瞬間與一組諸如 YEAR
、MONTH
、DAY_OF_MONTH
、HOUR
等 日歷字段
之間的轉(zhuǎn)換提供了一些方法,并為操作日歷字段(例如獲得下星期的日期)提供了一些方法。瞬間可用毫秒值來(lái)表示,它是距*歷元*(即格林威治標(biāo)準(zhǔn)時(shí)間 1970 年 1 月 1 日的 00:00:00.000,格里高利歷)的偏移量。與其他語(yǔ)言環(huán)境敏感類一樣,Calendar
提供了一個(gè)類方法 getInstance
,以獲得此類型的一個(gè)通用的對(duì)象。
修改和獲取 YEAR
、MONTH
、DAY_OF_MONTH
、HOUR
等 日歷字段
對(duì)應(yīng)的時(shí)間值。
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 第三代日期時(shí)間(JDK1.8)
Java1.0中包含了一個(gè)Date類,但是它的大多數(shù)方法已經(jīng)在Java 1.1引入Calendar類之后被棄用了。而Calendar并不比Date好多少。它們面臨的問題是:
- 可變性:像日期和時(shí)間這樣的類對(duì)象應(yīng)該是不可變的。Calendar類中可以使用三種方法更改日歷字段:set()、add() 和 roll()。
- 偏移性:Date中的年份是從1900開始的,而月份都是從0開始的。
- 格式化:格式化只對(duì)Date有用,Calendar則不行。
- 此外,它們也不是線程安全的,不能處理閏秒等。
可以說,對(duì)日期和時(shí)間的操作一直是Java程序員最痛苦的地方之一。第三次引入的API是成功的,并且java 8中引入的java.time API 已經(jīng)糾正了過去的缺陷,將來(lái)很長(zhǎng)一段時(shí)間內(nèi)它都會(huì)為我們服務(wù)。
Java 8 吸收了 Joda-Time的精華,以一個(gè)新的開始為 Java 創(chuàng)建優(yōu)秀的 API。
- java.time – 包含值對(duì)象的基礎(chǔ)包
- java.time.chrono – 提供對(duì)不同的日歷系統(tǒng)的訪問。
- java.time.format – 格式化和解析時(shí)間和日期
- java.time.temporal – 包括底層框架和擴(kuò)展特性
- java.time.zone – 包含時(shí)區(qū)支持的類
Java 8 吸收了 Joda-Time的精華,以一個(gè)新的開始為 Java 創(chuàng)建優(yōu)秀的 API。新的 java.time 中包含了所有關(guān)于時(shí)鐘(Clock),本地日期(LocalDate)、本地時(shí)間(LocalTime)、本地日期時(shí)間(LocalDateTime)、時(shí)區(qū)(ZonedDateTime)和持續(xù)時(shí)間(Duration)的類。
1、本地日期時(shí)間:LocalDate、LocalTime、LocalDateTime
序號(hào) | 方法 | 描述 |
---|---|---|
1 | now() / now(ZoneId zone) | 靜態(tài)方法,根據(jù)當(dāng)前時(shí)間創(chuàng)建對(duì)象/指定時(shí)區(qū)的對(duì)象 |
2 | of() | 靜態(tài)方法,根據(jù)指定日期/時(shí)間創(chuàng)建對(duì)象 |
3 | getDayOfMonth()/getDayOfYear() | 獲得月份天數(shù)(1-31) /獲得年份天數(shù)(1-366) |
4 | getDayOfWeek() | 獲得星期幾(返回一個(gè) DayOfWeek 枚舉值) |
5 | getMonth() | 獲得月份, 返回一個(gè) Month 枚舉值 |
6 | getMonthValue() / getYear() | 獲得月份(1-12) /獲得年份 |
7 | getHours()/getMinute()/getSecond() | 獲得當(dāng)前對(duì)象對(duì)應(yīng)的小時(shí)、分鐘、秒 |
8 | withDayOfMonth()/withDayOfYear()/withMonth()/withYear() | 將月份天數(shù)、年份天數(shù)、月份、年份修改為指定的值并返回新的對(duì)象 |
9 | with(TemporalAdjuster t) | 將當(dāng)前日期時(shí)間設(shè)置為校對(duì)器指定的日期時(shí)間 |
10 | plusDays(), plusWeeks(), plusMonths(), plusYears(),plusHours() | 向當(dāng)前對(duì)象添加幾天、幾周、幾個(gè)月、幾年、幾小時(shí) |
11 | minusMonths() / minusWeeks()/minusDays()/minusYears()/minusHours() | 從當(dāng)前對(duì)象減去幾月、幾周、幾天、幾年、幾小時(shí) |
12 | plus(TemporalAmount t)/minus(TemporalAmount t) | 添加或減少一個(gè) Duration 或 Period |
13 | isBefore()/isAfter() | 比較兩個(gè) 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、瞬時(shí):Instant、ZondId和ZonedDateTime
常見時(shí)區(qū)ID:
Asia/Shanghai
UTC
America/New_York
America/Los_Angeles
可以通過ZondId獲取所有可用的時(shí)區(qū)ID:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Set;
public class TestZone {
@Test
public void test01() {
//需要知道一些時(shí)區(qū)的id
//Set<String>是一個(gè)集合,容器
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(){
//以中國(guó)時(shí)區(qū)獲取當(dāng)前時(shí)間
ZonedDateTime chinaNow = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
//將中國(guó)時(shí)間轉(zhuǎn)換為美國(guó)紐約時(shí)間
ZonedDateTime newYorkNow = chinaNow.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println("中國(guó)時(shí)區(qū)當(dāng)前時(shí)間:" + chinaNow);
System.out.println("將中國(guó)時(shí)間轉(zhuǎn)換為美國(guó)紐約時(shí)間:"+newYorkNow);
}
}
3、持續(xù)日期/時(shí)間:Period和Duration
Period:用于計(jì)算兩個(gè)“日期”間隔
Duration:用于計(jì)算兩個(gè)“時(shí)間”間隔
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("相差的年數(shù):"+between.getYears());
System.out.println("相差的月數(shù):"+between.getMonths());
System.out.println("相差的天數(shù):"+between.getDays());
System.out.println("相差的總數(shù):"+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("相差的總天數(shù):"+between.toDays());
System.out.println("相差的總小時(shí)數(shù):"+between.toHours());
System.out.println("相差的總分鐘數(shù):"+between.toMinutes());
System.out.println("相差的總秒數(shù):"+between.getSeconds());
System.out.println("相差的總毫秒數(shù):"+between.toMillis());
System.out.println("相差的總納秒數(shù):"+between.toNanos());
System.out.println("不夠一秒的納秒數(shù):"+between.getNano());
}
}
4、日期時(shí)間格式化DateTimeFormatter
該類提供了三種格式化方法:
- 預(yù)定義的標(biāo)準(zhǔn)格式。如:ISO_DATE_TIME;ISO_DATE
- 本地化相關(guān)的格式。如: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時(shí)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點(diǎn)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時(shí)26分43秒";
LocalDateTime t = LocalDateTime.from(dt.parse(str));
System.out.println(t);
}
}
9.4.4 三代日期時(shí)間的轉(zhuǎn)換
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();//本地的日期時(shí)間對(duì)象
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();//本地的日期時(shí)間對(duì)象
ZonedDateTime zonedDateTime = now.atZone(ZoneId.systemDefault());//時(shí)區(qū)的日期時(shí)間對(duì)象
Instant instant = zonedDateTime.toInstant();//瞬時(shí)對(duì)象
Date date = Date.from(instant);//第一代的Date
System.out.println(date);
}
}