旧的日期存在的的问题
1.Date和Calendar不是线程安全的,需要编写额外的代码处理线程安全问题
2.需要编写额外的代码去处理时区问题
新的日期API
ZoneId: 时区ID,用来确定Instant和LocalDateTime互相转换的规则
Instant: 用来表示时间线上的一个点
LocalDate: 表示没有时区的日期, LocalDate是不可变并且线程安全的
LocalTime: 表示没有时区的时间, LocalTime是不可变并且线程安全的
LocalDateTime: 表示没有时区的日期时间, LocalDateTime是不可变并且线程安全的
Clock: 用于访问当前时刻、日期、时间,用到时区
Duration: 用秒和纳秒表示时间的数量
LocalDate
获取当前时间:
LocalDate localDate = LocalDate.now();
可以指定日期:通过of 或者parse方法
LocalDate.of(2017, 07, 20);
LocalDate.parse("2017-07-20");
指定时间之后 也可以对指定的时间进行增加减少的操作
为当前时间加N天
LocalDate tomorrow = LocalDate.now().plusDays(1);
//一周后
now.plusWeeks(1)
//两天前
now.minusDays(2)
//增加一个月不会出现2017-02-31 而是会返回该月的最后一个有效日期,即2017-02-28
LocalDate.of(2017, 1, 31).plusMonths(1)
isBefore isAfter比较两个LocalDate,isLeapYear判断是否是闰年。
LocalTime(本地时间)
LocalTime表示一天中的某个时间,例如18:00:00。LocaTime与LocalDate类似,他们也有相似的API。
需要注意的是:LocalTime本身不关心是AM还是PM,而是格式化程序来负责这个事情。
LocalDateTime(本地日期时间)
LocalDateTime表示一个日期和时间,它适合用来存储确定时区的某个时间点。不适合跨时区的问题。
常用的格式化当前时间:(常用的且重要的)
DateTimeFormatter.ISO_LOCAL_DATE.format(LocalDate.now())
格式化之后的值是 2018-09-25
//20170101 此方法也可以用来生成一个时间戳的啦
DateTimeFormatter.BASIC_ISO_DATE.format(LocalDate.of(2017, 1, 1));
//2017-01-01T09:10:00
DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(LocalDateTime.of(2017, 1, 1, 9, 10, 0));
自定义的日期格式化
//2017-02-27 22:48:52
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now())
/**********************************************************************
Instant
它表示一个精确的时间,时间数轴是由无数个时间点组成的。
使用静态方法Instant.now()可以获取当前的时间点
计算某段代码执行时间可以使用下面的方式:
Instant start = Instant.now();
//这个时间是国际时间还需要将其进行偏移处理成中国时间
偏移8小时的那个
doSomething();
Instant end = Instant.now();
Duration timeElapsed = Duration.between(start, end);
long millis = timeElapsed.toMillis();
System.out.println("millis = " + millis);
@Query("select new map(a.loginName,a.mobile,a.email,a.userId) from UserInfo a where a.userId in :userIds")
日期格式化的相关操作
需求一:将一个字符串转化为LocalDateTime格式
public static void main(String[] args) {
String aa="2019-01-02 22:13:10";
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDateTime time = LocalDateTime.parse(aa, dateTimeFormatter);
System.out.println(time);
}
结果:
2019-01-02T22:13:10
需求二:将一个字符串转化为long类型的时间戳
public static void main(String[] args) {
String aa="2019-01-02 22:13:10";
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime time = LocalDateTime.parse(aa, dateTimeFormatter);
long l = time.toEpochSecond(ZoneOffset.of("+8"));
System.out.println(l);
}
结果:1546438390
需求三:将一个LocalDateTime转化为String类型的时间格式
public static void main(String[] args) {
String aa="2019-01-02 22:13:10";
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime time = LocalDateTime.parse(aa, dateTimeFormatter);
String format = time.format(dateTimeFormatter);
System.out.println(format);
}
需求四:给你分开提供年月日 你给格式化成一个时间格式的字符串
public static void main(String[] args) {
//給定一個格式化的格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("+8"));
ZonedDateTime time = ZonedDateTime.parse("2019-03-05" + " 00:00:00",formatter).withHour(12).withMinute(0).withSecond(0);
String format = time.format(formatter);
System.out.println(format);
}
2019-03-05 12:00:00
/**
* Instant取的时间表示0时区的时间和北京时间相差8个时区 需要修正为北京时间 默认使用的是UTC时间
* 精确到了纳秒 末尾有Z
*2019-04-01T02:36:38.610Z
*LocalDateTime是北京时间 不含有时区信息 到毫秒
*2019-04-01T10:36:38.610
* ZonedDateTime包含时区 的完整的时间日期
*/2019-04-01T10:36:38.610+08:00[Asia/Shanghai]
将yyyy-MM-dd HH:mm:ss格式的时间转化为 HH:mm
DateTimeFormatter formatterFull = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("+8"));
DateTimeFormatter formatterHHmm = DateTimeFormatter.ofPattern("HH:mm");
ZonedDateTime time = ZonedDateTime.parse(operateDate +" 00:00:00",formatterFull).withHour(hourTaskDTO.getOperateHour());
dayEnergyPointVM.setSortDate(time.format(formatterHHmm));