1. JDK8之前的时间日期API
1.1 java.lang.System类
- public static native long currentTimeMillis();
- 用于返回当前时间与1970年1月1日0:0:0之间以毫秒为单位的时间差
- 时间戳
1.2 java.util.Date类
-
两个构造器
- new Date(); —> 当前时间
- new Date(Long 毫秒数) — > 根据毫秒数创建指定日期
-
两个方法的使用
- toString() 显示当前的年,月,日,时,分,秒
- getTime() 获取当前date对象的对应的毫秒数(时间戳)
-
java.util.Date 和java.sql.Date 互相转换
- Date date = new java.sql.Date()
- java.sql.Date date2 = (java.sql.Date) date;
- java.sql.Date date3 = new java.sql.Date(new Date().getTime());
1.3 java.text.SimpleDateFormat类
- Date类的API不易于国际化,大部分被废弃,SimpleDateFormat类 一个与语言环境有关的方式来格式化和解析时间的具体类
- format() 方法 按照具体的格式格式化时间
- parse() 方法将字符串解析成时间
1.4 java.util.Calendar 日历类
- 获取Calendar的实例
- 使用其子类 (GregorianCalendar)的对象
- 使用Calendar.getInstance()
- 常用方法
- set()
- calendar.set(Calendar.DAY_OF_MONTH,22) —> 将日期设置为这个月的第几天
- get()
- calendar.get(Calendar.DAY_OF_MONTH)----->这个月的第几天,返回值是int
- calendar.get(Calendar.DAY_OF_YEAR) —>这一年的第几天
- add()
- calendar.add(Calendar.DAY_OF_MONTH,3) ----> 在现有的日期上加3天
- getTime()
- calendar.getTime(); —> 返回Date()
- setTime()
- calendar.setTime(new Date()) — > 将日期设置为某日期
- set()
2 JDK8新日期时间的API
- 可变性 : 像日期和时间这样的类应该是不可变的,---->返回一个值,原来的对象不变
- 偏移性 : Date中的年份是从1900开始的,而月份是从0开始的
- 日期表示需要减 new Date(2020-1900,9-1,8) 这样才可以表示2020年9月8日
- 格式化; 格式化日期只对Date有用,Calendar则不行
- 线程不安全的,不能处理闰秒等
- Java8 吸收了Joda-Time精华,开启了新的API,新的java.time包含了如下子类
- 本地日期
LocalDate
- 本地时间
LocalTime
- 本地日期时间
LocalDateTime
- 时区
ZonedDateTime
- 持续时间
Duration
- 本地日期
2.1 JDK8 的新日期的API
- java.time -包含值对象的基础包
- java.time.chrono - 提供不同日历系统的访问
- java.time.format - 格式化和解析时间和日期
- java.time.temporal - 包含底层框架和扩展特性
- java.time.zone - 包含时区支持的类
2.2 LocalDate,LocalTime,LocalDateTime
// LocalDate LocalTime LocalDateTime
// 获取当前时间
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDate);
System.out.println(localTime);
System.out.println(localDateTime);
// LocalDateTime 使用频率较高
// of() 设置指定的年月日时分秒 体现不偏移性
LocalDateTime dateTime = LocalDateTime.of(2019, 04, 10, 23, 03);
System.out.println(dateTime);
// getXxx()
System.out.println(dateTime.getDayOfMonth());
System.out.println(dateTime.getDayOfWeek());
System.out.println(dateTime.getMonth());
System.out.println(dateTime.getMinute());
System.out.println(dateTime.getMonthValue());
// withXxx 体现不可变性
LocalDate localDate1 = localDate.withDayOfMonth(12);
System.out.println(localDate);
System.out.println(localDate1);
// 设置分钟
LocalDateTime localDateTime1 = localDateTime.withMinute(20);
System.out.println(localDateTime);
System.out.println(localDateTime1);
// plusXxx() 当前的时间做加法
LocalDate localDate2 = localDate.plusMonths(1);
System.out.println(localDate);
System.out.println(localDate2);
// 结果
2019-04-10
23:14:42.994
2019-04-10T23:14:42.994
2019-04-10T23:03
10
WEDNESDAY
APRIL
3
4
2019-04-10
2019-04-12
2019-04-10T23:14:42.994
2019-04-10T23:20:42.994
2019-04-10
2019-05-10
2.3 Instant 瞬时
- 时间线上的一个瞬时点,这可能用于记录应用程序的事件时间戳
- Instant的精度可以达到纳秒级
// Instant 和java.util.Date 很像
// 获取本初子午线的标准时间
Instant now = Instant.now();
System.out.println(now); // 2019-04-10T15:19:51.640Z
// 东八区的时间 偏移量
OffsetDateTime offsetDateTime = now.atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime); // 2019-04-10T23:21:47.598+08:00
// 距离1970年1月1日0:0:0(UTC) 开始的毫秒数
long l = now.toEpochMilli();
System.out.println(l);
// 根据偏移量获取时间
Instant instant = Instant.ofEpochMilli(l);
System.out.println(instant);
--------------------结果------------------------
2019-04-10T15:23:52.587Z
2019-04-10T23:23:52.587+08:00
1554909832587
2019-04-10T15:23:52.587Z
2.4 java.time.format.DateTimeFormatter 格式化或者解析时间
-
预定义的标准格式 如:
ISO_LOCAL_DATE
,ISO_LOCAL_DATE_TIME
,ISO_LOCAL_TIME
* -
本地化相关的格式 如:
ofLocalizedDateTime(FormatStyle.LONG)
-
自定义的格式 如:
ofPattern("yyyy-MM-dd HH:mm:ss E")
// 1. 预定义的标准格式 ISO_LOCAL_DATE_TIME,ISO_LOCAL_DATE,ISO_LOCAL_TIME
// 格式化日期 --- > 字符串
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
LocalDateTime now = LocalDateTime.now();
System.out.println(formatter.format(now)); //2019-04-14T11:26:07.555
System.out.println(now); //2019-04-14T11:26:07.555
// 字符串--->时间
TemporalAccessor parse = formatter.parse("2019-04-14T11:26:07.555");
System.out.println(parse);
// 方式二
// 本地化相关格式 ofLocalizedDateTime()
// FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT
DateTimeFormatter dateTime = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
System.out.println(dateTime.format(now)); //2019年4月14日 上午11时30分54秒
// 方式三 自定义格式
// ofPattern("yyyy-MM-dd hh:mm:ss") -->和SimpleDateFormat相似
3. 其他API
- ZoneId :该类包含了所有的时区信息,一个时区的Id,如Europe/Paris
- ZoneDateTime: 一个在ISO-8601日历系统时区的时间
- 其中每个时区都有对应的Id,每个地区Id都有"{区域}/{城市}" 例如
Asia/Shanghai
等
- 其中每个时区都有对应的Id,每个地区Id都有"{区域}/{城市}" 例如
- Clock :使用时区提供的当前及时,日期和时间的访问的时钟
- 持续时间Duration,用于计算两个"时间"的间隔
- 日期间隔: Period ,用于计算两个"日期"的间隔
- TemporalAdjuster : 时间校正器
- TemporalAdjusters: 通过该类的静态方法(firstDayOfXxx()/lastDayOfXxx()/nextXxx()) 提供大量的常用TemporalAdjuster的实现
//ZoneId:类中包含了所有的时区信息
// ZoneId的getAvailableZoneIds():获取所有的ZoneId
Set<String> zoneIds = ZoneId.getAvailableZoneIds();
for (String s : zoneIds) {
System.out.println(s);
}
// ZoneId的of():获取指定时区的时间
LocalDateTime localDateTime = LocalDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println(localDateTime);
//ZonedDateTime:带时区的日期时间
// ZonedDateTime的now():获取本时区的ZonedDateTime对象
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println(zonedDateTime);
// ZonedDateTime的now(ZoneId id):获取指定时区的ZonedDateTime对象
ZonedDateTime zonedDateTime1 = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println(zonedDateTime1);
//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());
//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);
// 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);