目录
一、ZoneId
它是一个时区ID,如Europe/Paris。
ZoneId用来定义在Instant和LocalDateTime之间转换的规则。它有两种不同类型的ID:
1)固定偏移-从UTC/Greenwich开始的偏移,对所有本地日期时间使用相同的偏移
2)地理区域-适用于查找UTC/格林威治偏移量的特定规则集的区域
//获取上海zoneId
ZoneId zoneId = ZoneId.of("Asia/Shanghai");
/*构造方法可传入参数如下:
EST - -05:00
HST - -10:00
MST - -07:00
ACT - Australia/Darwin
AET - Australia/Sydney
AGT - America/Argentina/Buenos_Aires
ART - Africa/Cairo
AST - America/Anchorage
BET - America/Sao_Paulo
BST - Asia/Dhaka
CAT - Africa/Harare
CNT - America/St_Johns
CST - America/Chicago
CTT - Asia/Shanghai
EAT - Africa/Addis_Ababa
ECT - Europe/Paris
IET - America/Indiana/Indianapolis
IST - Asia/Kolkata
JST - Asia/Tokyo
MIT - Pacific/Apia
NET - Asia/Yerevan
NST - Pacific/Auckland
PLT - Asia/Karachi
PNT - America/Phoenix
PRT - America/Puerto_Rico
PST - America/Los_Angeles
SST - Pacific/Guadalcanal
VST - Asia/Ho_Chi_Minh*/
// 获取当前系统默认时区
ZoneId zoneId1 = ZoneId.systemDefault();
ZoneId的抽象方法
public abstract ZoneRules getRules();
有ZoneOffset和ZoneRegion两个实现类。
二、Clock
一种时钟,通过时区提供对当前时刻、日期和时间的访问。此类的实例用于查找当前时刻Instant,可以使用存储的时区time-zone来来查找当前日期和时间。因此,可以使用时钟代替System.currentTimeMillis()和TimeZone.getDefault()。
//获取系统UTC时钟
Clock clock = Clock.systemUTC();
//获取系统默认时区时钟
Clock clock1 = Clock.systemDefaultZone();
//获取系统巴黎时区时钟
Clock ctt = Clock.system(ZoneId.of("Europe/Paris"));
// 获取当前系统默认最近一秒的instant
Clock clock2 = Clock.tickSeconds(ZoneId.systemDefault());
Instant instant = clock2.instant();
// 获取当前系统默认最近一分的instant
Clock clock3 = Clock.tickMinutes(ZoneId.systemDefault());
Instant instant3 = clock3.instant();
// 最近一小时
Clock tick = Clock.tick(Clock.systemDefaultZone(), Duration.ofHours(1));
Instant instant1 = tick.instant();
// instant转换为Clock
Clock fixed = Clock.fixed(Instant.now(), ZoneId.of("Europe/Paris"));
源码中Clock类主要有以下几个方法:
public abstract ZoneId getZone();
public abstract Clock withZone(ZoneId zone);
public long millis() {}
public abstract Instant instant();
调用Clock相应的静态方法生成如下对应SystemClock,TickClock,FixedClock,OffsetClock
的子类,做具体实现。
三、ZonedDateTime
ISO-8601日历系统中带有时区的日期时间,例如2007-12-03T10:15:30+01:00 Europe/Paris。
ZoneDateTime是带有时区的日期时间的不可变表示形式。此类存储所有日期和时间字段(精度为纳秒)和时区,时区偏移用于处理不明确的本地日期时间。例如,值“2nd October 2007 at 13:45.30.123456789 +02:00 in the Europe/Paris time-zone”可以存储在ZonedDateTime中。
//获取系统默认时区ZonedDateTime
ZonedDateTime now = ZonedDateTime.now();
//获取UTC ZonedDateTime
ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC());
//获取巴黎时区ZonedDateTime
ZonedDateTime now2 = ZonedDateTime.now(ZoneId.of("Europe/Paris"));
// 获取年月日时分秒时区
int year = now.getYear();
int monthValue = now.getMonthValue();
int dayOfYear = now.getDayOfYear();
int hour = now.getHour();
int minute = now.getMinute();
int second = now.getSecond();
ZoneId zone = now.getZone();
//与instant转换
Instant instant = now.toInstant();
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
//与LocalDateTime转换
LocalDateTime localDateTime = now.toLocalDateTime();
localDateTime.atZone(ZoneId.systemDefault());
//与LocalDate转换
LocalDate localDate = now.toLocalDate();
localDate.atStartOfDay(ZoneId.systemDefault());
//与LocalTime转换
LocalTime localTime = now.toLocalTime();
四、DateTimeFormatter
jdk8之前日期时间格式化使用SimpleDateFormat对象,因为它是非线程安全的,每次都需要实例化,消耗内存性能。或者使用ThreadLocal线程变量存放为类变量。还有可以使用org.apache.commons.lang3.time.DateFormatUtils工具类进行时间处理。
jdk8提供了DateTimeFormatter,是线程安全的,提供大量api,方便时间格式化和解析。
//格式化LocalDateTime
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String format1 = dateTimeFormatter.format(LocalDateTime.now());
String format3 = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE);
//格式化LocalDate
DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String format = dateTimeFormatter1.format(LocalDate.now());
String format4 = LocalDate.now().format(DateTimeFormatter.ISO_DATE);
//格式化LocalTime
DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofPattern("HH:mm:ss");
String format2 = dateTimeFormatter2.format(LocalTime.now());
String format5 = LocalTime.now().format(DateTimeFormatter.ISO_TIME);
int year = DateTimeFormatter.ISO_DATE.parse("2011-12-03+01:00").get(ChronoField.YEAR);
int minute = DateTimeFormatter.ISO_TIME.parse("10:15:30").get(ChronoField.MINUTE_OF_HOUR);
int month = DateTimeFormatter.ISO_DATE_TIME.parse("2011-12-03T10:15:30+01:00").get(ChronoField.MONTH_OF_YEAR);