概念
时区
?? 不同时区在同一时刻, 它们的本地时间是不同的, 全球一共有 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 类型.
name="useJSR310Types" value="true"/>
?? 一旦 mybatis 中使用了 java8 中的日期类型, 记得要在项目中引入 mybatis-typehandlers-jsr310, 这个主要是处理 java8 中的日期类型.
- org.mybatis
- mybatis-typehandlers-jsr310
- 1.0.2
注意: 用 maven mybatis 插件如果不在 plugin 里面添加依赖包的引用的话, 会找不到相关得 jar 包, 在 plugin 外部得 jar 包, 他不会去找到并执行, 所以要把 plugin 运行依赖得 jar 配置都放在里面, pom.xml 配置 mybatis 插件如下:
- org.mybatis.generator
- mybatis-generator-maven-plugin
- 1.3.7
- org.mybatis
- mybatis
- 3.4.6
- MySQL
- MySQL-connector-java
- 8.0.13
注意, 在连接 mysql8.0 的时候要指明 timeZone, 即 serverTimezone=UTC 这个不能忘
来源: http://www.bubuko.com/infodetail-3625204.html