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);
}
}