Java 8新的日期时间API包含:
java.time
– 包含值对象的基础包java.time.chrono
– 提供对不同的日历系统的访问。java.time.format
– 格式化和解析时间和日期java.time.temporal
– 包括底层框架和扩展特性java.time.zone
– 包含时区支持的类
1.本地日期时间:LocalDate、LocalTime、LocalDateTime
方法 | 描述 |
now()/ now(ZoneId zone) | 静态方法,根据当前时间创建对象/指定时区的对象 |
of(xx,xx,xx,xx,xx,xxx) | 静态方法,根据指定日期/时间创建对象 |
getDayOfMonth()/getDayOfYear() | 获得月份天数(1-31) /获得年份天数(1-366) |
getDayOfWeek() | 获得星期几(返回一个 DayOfWeek 枚举值) |
getMonth() | 获得月份, 返回一个 Month 枚举值 |
getMonthValue() / getYear() | 获得月份(1-12) /获得年份 |
方法 | 描述 |
getHours()/getMinute()/getSecond() | 获得当前对象对应的小时、分钟、秒 |
withDayOfMonth()/withDayOfYear()/withMonth()/withYear() | 将月份天数、年份天数、月份、年份修改为指定的值并返回新的对象 |
with(TemporalAdjuster t) | 将当前日期时间设置为校对器指定的日期时间 |
plusDays(), plusWeeks(), plusMonths(), plusYears(),plusHours() | 向当前对象添加几天、几周、几个月、几年、几小时 |
minusMonths() / minusWeeks()/minusDays()/minusYears()/minusHours() | 从当前对象减去几月、几周、几天、几年、几小时 |
plus(TemporalAmount t)/minus(TemporalAmount t) | 添加或减少一个 Duration 或 Period |
isBefore()/isAfter() | 比较两个 LocalDate |
isLeapYear() | 判断是否是闰年(在LocalDate类中声明) |
format(DateTimeFormatter t) | 格式化本地日期、时间,返回一个字符串 |
parse(Charsequence text) | 将指定格式的字符串解析为日期、时间 |
2.瞬时:Instant
Instant:时间线上的一个瞬时点。 这可能被用来记录应用程序中的事件时间戳。
- 时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。
java.time.Instant
表示时间线上的一点,而不需要任何上下文信息,例如,时区。概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC)开始的秒数。
方法 | 描述 |
now() | 静态方法,返回默认UTC时区的Instant类的对象 |
ofEpochMilli(long epochMilli) | 静态方法,返回在1970-01-01 00:00:00基础上加上指定毫秒数之后的Instant类的对象 |
atOffset(ZoneOffset offset) | 结合即时的偏移来创建一个 OffsetDateTime |
toEpochMilli() | 返回1970-01-01 00:00:00到当前时间的毫秒数,即为时间戳 |
中国大陆、中国香港、中国澳门、中国台湾、蒙古国、新加坡、马来西亚、菲律宾、西澳大利亚州的时间与UTC的时差均为+8,也就是UTC+8。
instant.atOffset(ZoneOffset.ofHours(8));
3.日期时间格式化:DateTimeFormatter
该类提供了三种格式化方法:
- 预定义的标准格式。如:ISOLOCALDATETIME、ISOLOCALDATE、ISOLOCAL_TIME
- 本地化相关的格式。如:ofLocalizedDate(FormatStyle.LONG)
- 自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
方 法 | 描 述 |
ofPattern(String pattern) | 静态方法,返回一个指定字符串格式的DateTimeFormatter |
format(TemporalAccessor t) | 格式化一个日期、时间,返回字符串 |
parse(CharSequence text) | 将指定格式的字符序列解析为一个日期、时间 |
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(){ // 方式一:预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; // 格式化:日期-->字符串 LocalDateTime localDateTime = LocalDateTime.now(); String str1 = formatter.format(localDateTime); System.out.println(localDateTime); System.out.println(str1);//2022-12-04T21:02:14.808 // 解析:字符串 -->日期 TemporalAccessor parse = formatter.parse("2022-12-04T21:02:14.808"); LocalDateTime dateTime = LocalDateTime.from(parse); System.out.println(dateTime); } @Test public void test2(){ LocalDateTime localDateTime = LocalDateTime.now(); // 方式二: // 本地化相关的格式。如:ofLocalizedDateTime() // FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT :适用于LocalDateTime DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG); // 格式化 String str2 = formatter1.format(localDateTime); System.out.println(str2);// 2022年12月4日 下午09时03分55秒 // 本地化相关的格式。如:ofLocalizedDate() // FormatStyle.FULL / FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT : 适用于LocalDate DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL); // 格式化 String str3 = formatter2.format(LocalDate.now()); System.out.println(str3);// 2022年12月4日 星期日 } @Test public void test3(){ //方式三:自定义的方式 DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); //格式化 String strDateTime = dateTimeFormatter.format(LocalDateTime.now()); System.out.println(strDateTime); //2022/12/04 21:05:42 //解析 TemporalAccessor accessor = dateTimeFormatter.parse("2022/12/04 21:05:42"); LocalDateTime localDateTime = LocalDateTime.from(accessor); System.out.println(localDateTime); //2022-12-04T21:05:42 } }
4.其它API
4.1 指定时区日期时间:ZondId和ZonedDateTime
- ZoneId:该类中包含了所有的时区信息,一个时区的ID,如 Europe/Paris
- ZonedDateTime:一个在ISO-8601日历系统时区的日期时间,如 2007-12-03T10:15:30+01:00 Europe/Paris。
- 其中每个时区都对应着ID,地区ID都为“{区域}/{城市}”的格式,例如:Asia/Shanghai等
- 常见时区ID:
- Asia/Shanghai
- UTC
- America/New_York
- 可以通过ZondId获取所有可用的时区ID:
@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); }
4.2 持续日期/时间:Period和Duration
- 持续时间:Duration,用于计算两个“时间”间隔
- 日期间隔: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()); } @Test public void test03(){ //Duration:用于计算两个“时间”间隔,以秒和纳秒为基准 LocalTime localTime = LocalTime.now(); LocalTime localTime1 = LocalTime.of(15, 23, 32); //between():静态方法,返回Duration对象,表示两个时间的间隔 Duration duration = Duration.between(localTime1, localTime); System.out.println(duration); System.out.println(duration.getSeconds()); System.out.println(duration.getNano()); LocalDateTime localDateTime = LocalDateTime.of(2016, 6, 12, 15, 23, 32); LocalDateTime localDateTime1 = LocalDateTime.of(2017, 6, 12, 15, 23, 32); Duration duration1 = Duration.between(localDateTime1, localDateTime); System.out.println(duration1.toDays()); } @Test public void test4(){ //Period:用于计算两个“日期”间隔,以年、月、日衡量 LocalDate localDate = LocalDate.now(); LocalDate localDate1 = LocalDate.of(2028, 3, 18); Period period = Period.between(localDate, localDate1); System.out.println(period); System.out.println(period.getYears()); System.out.println(period.getMonths()); System.out.println(period.getDays()); Period period1 = period.withYears(2); System.out.println(period1); } }
4.3 Clock:使用时区提供对当前即时、日期和时间的访问的时钟。
4.4 TemporalAdjuster
TemporalAdjuster
: 时间校正器。有时我们可能需要获取例如:将日期调整到“下一个工作日”等操作。 TemporalAdjusters : 该类通过静态方法(firstDayOfXxx()/lastDayOfXxx()/nextXxx())提供了大量的常用 TemporalAdjuster 的实现。
@Test public void test1(){ // TemporalAdjuster:时间校正器 // 获取当前日期的下一个周日是哪天? TemporalAdjuster temporalAdjuster = TemporalAdjusters.next(DayOfWeek.SUNDAY); LocalDateTime localDateTime = LocalDateTime.now().with(temporalAdjuster); System.out.println(localDateTime); // 获取下一个工作日是哪天? LocalDate localDate = LocalDate.now().with(new TemporalAdjuster() { @Override public Temporal adjustInto(Temporal temporal) { LocalDate date = (LocalDate) temporal; if (date.getDayOfWeek().equals(DayOfWeek.FRIDAY)) { return date.plusDays(3); } else if (date.getDayOfWeek().equals(DayOfWeek.SATURDAY)) { return date.plusDays(2); } else { return date.plusDays(1); } } }); System.out.println("下一个工作日是:" + localDate); }
5.与传统日期处理的转换
类 | To 遗留类 | From 遗留类 |
java.time.Instant与java.util.Date | Date.from(instant) | date.toInstant() |
java.time.Instant与java.sql.Timestamp | Timestamp.from(instant) | timestamp.toInstant() |
java.time.ZonedDateTime与java.util.GregorianCalendar | GregorianCalendar.from(zonedDateTime) | cal.toZonedDateTime() |
类 | To 遗留类 | From 遗留类 |
java.util.GregorianCalendar | ||
java.time.LocalDate与java.sql.Time | Date.valueOf(localDate) | date.toLocalDate() |
java.time.LocalTime与java.sql.Time | Date.valueOf(localDate) | date.toLocalTime() |
java.time.LocalDateTime与java.sql.Timestamp | Timestamp.valueOf(localDateTime) | timestamp.toLocalDateTime() |
java.time.ZoneId与java.util.TimeZone | Timezone.getTimeZone(id) | timeZone.toZoneId() |
java.time.format.DateTimeFormatter与java.text.DateFormat | formatter.toFormat() | 无 |