概念
时区
不同时区在同一时刻,它们的本地工夫是不同的,寰球一共有 24 个时区,咱们把伦敦所在的时区称为标准时区,其余时区依照货色偏移的小时来辨别,北京所在的时区是东八区(GMT+08:00)。
时区的体现形式如下:
- GMT+08:00
- UTC+08:00
- CST(China Standard Time / Central Standard Time USA)
- Asia/Shanghai
地区
Local 示意一个国家或地区的日期、工夫、数字、货币等格局
- zh_CN: 示意的是中国的 Local,日期用年月日示意 2020-07-05
- en_US: 示意的是美国的 Local,日期用日月年示意 05/07/2020
计算机用 Local 在日期、工夫、货币和字符串之间进行转换
中国用户 | 美国用户 | |
---|---|---|
购买价格: | 12000.0 | 12,000.00 |
购买日期: | 2020-07-05 | 05/07/2020 |
java.time 的 API
java.time 提供了新的日期和工夫 API
- LocalDate/LocalTime/LocalDateTime
- ZonedDateTime/ZoneId
- Instant
- Formatter
- …
新 API 的特点:
- 严格辨别日期、工夫
- 不变类(相似 String)
- Month 范畴 1~12(Jan~Dec)
- Week 范畴 1~7(Mon~Sun)
LocalDateTime
LocalDate d = LocalDate.now(); // 以后日期
LocalTime t = LocalTime.now(); // 以后工夫
LocalDateTime dt = LocalDateTime.now(); // 以后日期工夫
System.out.println(dt); // 严格依照 ISO 8601 格局打印 2020-07-05T16:38:37.356
// 指定日期和工夫
LocalDate d2 = LocalDate.of(2020, 7, 5); // 2020-07-05, 留神 7= 7 月
LocalTime t2 = LocalTime.of(16, 38, 37); // 16:38:37
LocalDateTime dt2 = LocalDateTime.of(2020, 7, 5,16, 38, 37); // 2020-07-05T16:38:37
LocalDateTime dt3 = LocalDateTime.of(d2, t2); // 2020-07-05T16:38:37
// 对日期进行格式化 a
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(dtf.format(LocalDateTime.now())); // 2020-07-05 16:45:08
// 将字符串解析成日期
LocalDateTime parse = LocalDateTime.parse("2020-07-05 16:45:08", dtf);
System.out.println(parse); // 2020-07-05T16:45:08
新的 DateTimeFormatter 是不可变的。默认状况下,LocalDate,LocalTime,LocalDateTime 依照 ISO 规范格式化和解析:
- yyyy-MM-dd
- HH:mm:ss
- HH:mm:ss:SSS
- yyyy-MM-dd’T’HH:mm:ss
- yyyy-MM-dd’T’HH:mm:ss:SSS
重大更新: 对日期和工夫进行加减
- plusDays() 在当初的日期加上具体天数
- minusHous() 在当初的工夫减去具体的小时
- plusWeeks() 在当初的日期工夫加上具体的周数
// +5 天
LocalDate today = LocalDate.now();
LocalDate after5Days = today.plusDays(5);
System.out.println(after5Days); //2020-07-10
// - 2 小时
LocalTime now = LocalTime.now();
LocalTime before2Hours = now.minusHours(2);
System.out.println(before2Hours); // 14:59:22.526
// + 1 月 - 2 周
LocalDate date = today.plusMonths(1).minusWeeks(2);
System.out.println(date); // 2020-07-22
对日期和工夫进行调整:
- withDayOfMonth()
- withMonth()
- withHour()
- …
- with()
// 本月第一天
LocalDate firstDay = LocalDate.now().withDayOfMonth(1);
System.out.println(firstDay); // 2020-07-01
// 把秒和纳秒调整为 0
LocalTime at = LocalTime.now().withSecond(0).withNano(0);
System.out.println(at); // 17:08
// 本月最初一天
LocalDate lastDay = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
System.out.println(lastDay); // 2020-07-31
// 本月第一个周日
LocalDate firstSunday = LocalDate.now().with(TemporalAdjusters.firstInMonth(DayOfWeek.SUNDAY));
System.out.println(firstSunday); //2020-07-05
判断日期和工夫的先后:
- isBefore()
- isAfter()
- equals()
LocalDate d01 = LocalDate.of(2020,7,5);
LocalDate d02 = LocalDate.of(2020,7,4);
System.out.println(d01.isBefore(d02)); // false
System.out.println(d01.isAfter(d02)); // true
计算日期的 Period: 某一天到指定的某一天具体相差多久
- getYears()
- getMonths()
- getDays()
LocalDate d03 = LocalDate.of(2020,7,5);
LocalDate d04 = LocalDate.of(2018,3,28);
// 通过 until() 办法获取 Period 对象,判断两个日期相差?年?月?天
Period period = d03.until(d04);
System.out.println(period); // P-2Y-3M-8D 示意 2020 年 7 月 5 日到 2018 年 3 月 28 日中相差 2 年 3 个月 8 天
// 两个日期一共相差多少天?long day01 = LocalDate.of(2020, 7, 5).toEpochDay();
long day02 = LocalDate.of(2018,3,28).toEpochDay();
System.out.println(day01-day02); // 830
LocalDateTime 无奈与 long 进行转换
- 因为 LocalDateTime 没有时区,无奈确定某一时刻
- ZonedDateTime 有时区,能够与 long 进行转换
ZonedDateTime
ZonedDateTime = LocalDateTime + ZoneId
- ZonedDateTime: 带时区的日期和工夫
- ZoneId:新的时区对象(取代旧的 java.util.TimeZone)
- Instant: 时刻对象(epoch seconds)
ZonedDateTime zbj = ZonedDateTime.now(); // 以后时区的日期和工夫
System.out.println(zbj); // 2020-07-05T17:32:40.415+08:00[Asia/Shanghai]
ZonedDateTime zny = ZonedDateTime.now(ZoneId.of("America/New_York")); // 纽约时区的以后日期和工夫
System.out.println(zny); // 2020-07-05T05:34:29.522-04:00[America/New_York]
ZonedDateTime 能够从 LocalDateTime 转换:atZone()
// 关联到以后默认时区
ZonedDateTime bj = ldt.atZone(ZoneId.systemDefault());
System.out.println(bj); // 2020-07-05T17:36:12+08:00[Asia/Shanghai]
// 关联到纽约时区
ZonedDateTime ny = ldt.atZone(ZoneId.of("America/New_York"));
System.out.println(ny); // 2020-07-05T17:36:12-04:00[America/New_York]
转换时区:withZoneSamleInstant()
LocalDateTime ldt = LocalDateTime.of(2020, 7, 5, 17, 36, 12);
// 关联到以后默认时区
ZonedDateTime bj = ldt.atZone(ZoneId.systemDefault());
System.out.println(bj); // 2020-07-05T17:36:12+08:00[Asia/Shanghai]
// 转换到纽约时区
ZonedDateTime zdt = bj.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println(zdt); // 2020-07-05T17:36:12-04:00[America/New_York]
Instant 对象示意时刻:
- ZonedDateTime.toInstant()
- Instant.getEpochSecond()
Instant ins = Instant.now();
Instant ins2 = ZonedDateTime.now().toInstant();
ZonedDateTime zdt = ins.atZone(ZoneId.of("Z"));
// 留神是秒
long epoch = ins.getEpochSecond();
如果我的项目中须要应用 generatorConfig.xml 配置文件生成 java8 中的日期类型 LocalDate、LocalTime、LocalDateTime 等等,须要在配置文件中的 javaTypeResolver 结点中退出属性 useJSR310Types,当 useJSR310Types 为 true 时,就会 jdbc 对应的日期类型会转成 java8 中的 LocateDateTime 类型,如果 useJSR310Types 为 false,则还是转成 java.util.Date 类型。
<javaTypeResolver>
<property name="useJSR310Types" value="true"/>
</javaTypeResolver>
一旦 mybatis 中应用了 java8 中的日期类型,记得要在我的项目中引入 mybatis-typehandlers-jsr310, 这个次要是解决 java8 中的日期类型。
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-typehandlers-jsr310</artifactId>
<version>1.0.2</version>
</dependency>
留神:用 maven mybatis 插件如果不在 plugin 外面增加依赖包的援用的话,会找不到相干得 jar 包,在 plugin 内部得 jar 包,他不会去找到并执行,所以要把 plugin 运行依赖得 jar 配置都放在外面,pom.xml 配置 mybatis 插件如下:
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
</dependencies>
</plugin>
</plugins>
留神,在连贯 mysql8.0 的时候要指明 timeZone,即 serverTimezone=UTC 这个不能忘