java8 时间加一秒_都9012了,Java8中的日期时间API你还没有掌握?
工作这么久了,对于Java中时间日期的操作一直很蛋疼,一会用Date,一会用Calendar一会用LocalDateTime,始终没有认真总结过它们的联系与区别。迷迷糊糊用了好几年了,今天终于搞清楚了!
一,Java8日期时间API产生的前因后果
1.1 为什么要重新定义一套日期时间API
操作不方便:java中最初的Date不能直接对指定字段进行加减操作也不支持国际化,后来新增了Calendar,但是Calendar又不支持格式化操作,需要转换成Date再进行格式化,总之一直在填坑,使用起来一点都不够优雅。
线程不安全:Date,Caleandar,SimpleDateFormat都是可变的,线程不安全的,所以你需要编写额外的代码处理线程安全问题。
1.2 Java8重新定义
对时间日期相关操作进行细分:时间,日期,日期&时间,时间戳,时间段,日期段,格式化等
所有类都是不可变的,线程安全
兼容旧的日期时间
1.3Java8兼容就版本的Date,同时也规范了日期时间的转换流程。
一,给人读的( LocalDateTime & LocalDate & LocalTime)
java8中将时间和日期进行的区分,用LocalDateTime表示日期和时间,LocalDate用来表示日期而LocalTime表示时间。内部实现也非常好理解,LocalDateTime = LocalDate + LocalTime,并且他们的内部api也一致,所以笔者就结合工作中的经验,介绍他们最常见的用法。
1.1 获取当前时间
LocalDateTime localDateTime = LocalDateTime.now();
// 打印结果: 2019-12-02T22:09:20.503
1.2 获取指定时间
// 获取 2019年12月02号 23 : 59 : 59
LocalDateTime localDateTime2 = LocalDateTime.of(2019, 12, 2, 23, 59, 59);
// 打印结果: 2019-12-02T13:20:20
1.3 日期/时间加减操作
// localDateTime2的基础上加1天零1s
LocalDateTime localDateTime3 = localDateTime2.plusDays(1).plusSeconds(1);
// 打印结果:2019-12-04T00:00
1.4 获取指定的字段(年月日时分秒,纳秒,不支持毫秒)
System.out.println("现在是: " + localDateTime.getYear() + " 年中的第 " + localDateTime.getDayOfYear() +" 天");
// 打印结果:现在是: 2019 年中的第 336 天
// 画外音: 快过年了呀,感觉这一年又没啥收获
二,给计算机读的(Instant)
小知识:地球上不同地区经度不同会划分时区,以零度经线上为准(格林尼治天文台旧址,UTC时区)为准,将地球上各个部分分为了24个时区。向西走,每过一个时区,就要把表拨慢1个小时;同理每向东走一个时区,就要把表拨快1个小时。最后,中国处于东8区。
2.1 获取UTC时间(格林尼治时间)
Instant instant = Instant.now();
// 打印结果: 2019-12-02T14:31:41.661Z
2.2 获取北京时间(东8区)
// OffsetTime表示有时差的时间,除了UTC时间,都是OffsetTime
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
// 打印结果: 2019-12-02T22:31:41.661+08:00
2.3 获取毫秒数(1970-01-01T00:00:00Z开始计算)
long epochMilli = instant.toEpochMilli()
// 打印结果:1575297101661
2.4 定义时间戳
Instant instant1 = Instant.ofEpochSecond(59);
// 打印结果: 1970-01-01T00:00:59Z
instant2 = instant1.plusSeconds(99)
// 打印结果:2019-12-02T14:43:00.402Z
三, 时间间隔(Duration)
3.1 计算日期间隔(参数位置影响结果哦)
Instant instant1 = Instant.now();
Instant instant2 = instant1.plusSeconds(99);
Duration duration1 = Duration.between(instant1, instant2);
Duration duration2 = Duration.between(instant2, instant1);
// 打印结果 duration1:PT1M39S
// 打印结果 duration2:PT-1M-39S
long duration1Seconds = duration1.getSeconds();
long duration2Seconds = duration1.getSeconds();
// 打印结果 duration1Seconds: 90
// 打印结果 duration2Seconds: -90
3.2 操作时间间隔
Duration duration3 = duration1.plusDays(1);
// 打印结果:PT24H1M39S
注意 : 仅支持时间操作(Instant, LocalTime,LocalDateTime),不支持日期(LocalDate)
四,日期间隔(Period)
LocalDate localDate1 = LocalDate.now();
LocalDate localDate2 = localDate1.plusDays(1);
Period period = Period.between(localDate1, localDate2);
long days = period.getDays();
// 打印结果 peroid: P1D
// 打印结果 days: 1
五,日期/时间校正器(TemporalAdjuster)
5.1 获取指定日期或时间
LocalDateTime localDateTime1 = LocalDateTime.now();
LocalDateTime localDateTime2 = localDateTime.withDayOfMonth(20);
// 打印结果 localDateTime1:2019-12-02T22:57:47.674
// 打印结果 localDateTime2:2019-12-20T22:57:47.674
5.2 获取下一个固定日期(下一个星期天)
LocalDateTime localDateTime3 = localDateTime.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
// 打印结果 localDateTime33:2019-12-08T23:00:43.101
5.3 自定义矫正器
// 获取下一个工作日
LocalDateTime localDateTime4 = localDateTime.with((tempDateTime) -> {
LocalDateTime localDateTime5 = (LocalDateTime) tempDateTime;
DayOfWeek dayOfWeek = localDateTime5.getDayOfWeek();
if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
return localDateTime5.plusDays(3);
} else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
return localDateTime5.plusDays(2);
} else {
return localDateTime5.plusDays(1);
}
});
// 打印结果 localDateTime4:2019-12-03T23:00:43.101
六,日期时间格式化
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime localDateTime = LocalDateTime.now();
String dateStr =dateTimeFormatter.format(localDateTime);
// 打印结果: 2019-12-02 23:08:55
LocalDateTime localDateTime2 = LocalDateTime.parse(dateStr, dateTimeFormatter);
// 打印结果: 2019-12-02T23:08:55
LocalDate localDate = LocalDate.parse(dateStr, dateTimeFormatter);
// 打印结果: 2019-12-02
七,基于Instant进行转换
java8api对于时间戳,日期时间以及老版本的Date对象之间的转换也进行了兼容和适配,所有的转换操作都可以基于Instant对象进行。由于LocalDate,LocalTime和LocalDateTime三个类的操作完全一样,所以下文仍使用LocalDateTime演示。
7.1 时间戳转LocalDate,LocalDate,LocalDateTime
long timestamp = Instant.now().toEpochMilli();
LocalDateTime localDateTime = Instant.ofEpochMilli(timestamp).atOffset(ZoneOffset.ofHours(8)).toLocalDateTime();
// 打印结果:2019-12-02T23:20:25.791
7.2 LocalDate,LocalDate,LocalDateTime转时间戳
LocalDateTime localDateTime = LocalDateTime.now();
long timestamp = localDateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
// 打印结果:1575300368099
7.3 兼容就版本Date
LocalDateTime localDateTime3 = LocalDateTime.now();Date date =
Date.from(localDateTime.atZone(ZoneOffset.ofHours(8)).toInstant());LocalDateTime localDateTime4 =
localDateTime3.atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
// 打印结果 date:Mon Dec 02 23:32:53 CST 2019
// 打印结果 lcoalDateTime4:2019-12-02T23:32:53.188
八, Q&A
上一篇问题:在java中通常使用synchronized来实现方法同步,AQS中通过CAS保证了修改同步状态的一致性问题,那么对比synchronized,cas有什么优势不同与优势呢?你还知道其他无锁并发的策略吗?
8.1 Answer
Java中的无锁并发策略可以分为三种:
基于乐观锁的CAS操作
Copy On Write:写时复制是指:在并发访问的情景下,当需要修改JAVA中Containers的元素时,不直接修改该容器,而是先复制一份副本,在副本上进行修改。修改完成之后,将指向原来容器的引用指向新的容器(副本容器)
ThreadLocal:线程本地存储,就是为每一个线程创建一个变量,只有本线程可以在该变量中查看和修改值。
8.2 Question
这是一道送分题:正如上文提到的,Java8之前的日期时间以及格式化类是线程不安全的,你知道怎么编写测试代码吗?
如果优雅得获取昨天0点整的毫秒值?
学习Java过程中可能遇到问题和困惑,关注我vx公众号 “cruder” ,后台留言,笔者帮你一起解决!(需要学习资料的请关注后后台留言,主要都是java相关,java基础,并发,mysql,redis,es,mq等都都有!)
java8 时间加一秒_都9012了,Java8中的日期时间API你还没有掌握?相关推荐
- java8 时间加一秒_年货买瓜子有讲究!这些加了“料”的瓜子不安全!
还有不到一个月的时间 就是春节假期 不少人都开始置办年货了 过年一家老小围坐在一起 边嗑瓜子边唠嗑 是不少家庭的日常动作 瓜子可以说是最常见 最受欢迎的年货之一了 它不但含有丰富的不饱和脂肪酸 及维生 ...
- mysql 日期循环_如何在mysql存储过程中循环日期时间
即时通讯使用mysql存储过程,如何制作一个循环,每1小时变量strathour将有1小时的间隔然后返回查询的总数.当starthour小于11月的日期时,它将具有1小时的间隔并执行查询. 这是我的代 ...
- 深入JavaScript与.NET Framework中的日期时间(1):基本概念与概述
日期时间是开发过程中最尝使用的数据类型之一,但是很多开发人员在使用过程中忽视了时间日期的一些特性.现在的应用越来越讲究"国际化"和"本地化",它们的重要特征之一 ...
- python时间函数纳秒_在Python中以秒和纳秒获取POSIX / Unix时间?
我一直在努力找到一种方法来获取自1970-01-01 00:00:00 UTC以来的时间,以秒为单位,在python中以纳秒为单位,我找不到能给我正确精度的任何东西. 我尝试过使用时间模块,但是精度只 ...
- qt mysql 系统时间_使用QT和参数在SQLite数据库中插入日期时间
我想从C++/QT应用程序执行插入到SQLite数据库. 我想要插入数据的表格中的一列是datetime(yyyy-mm-dd hh:mm:ss).使用QT和参数在SQLite数据库中插入日期时间 我 ...
- MySQL中常用日期时间函数及获得
MySQL中常用日期时间函数: 下面的查询选择了所有记录,其date_col的值是在最后30天以内: mysql> SELECT something FROM table WHERE TO_DA ...
- SQL Server中的日期时间类型
一. 数据类型 SQL Server008在上一个版本的基础上把日期时间类的数据类型增加到了六个.除了SQL Server2005的datetime和smalltime之外,加了date,dateti ...
- mysql 时间字符串 1_Mysql 中的日期时间字符串查询
一.将数据库中的Date格式的数据,或者指定日期的字符串格式化为想要的样式 DATE_FORMAT (date, format)能根据格式串format 格式化日期或日期和时间值date,返回结果字符 ...
- mysql中所有时间类型_MySQL 中的日期时间类型
INSERT INTO todo (title,created_on) VALUES ('blah','2019-09-31'); ERROR 1292 (22007): Incorrect date ...
- mysql根据时间回退_MySQL 中的日期时间类型
日期时间类型中包含以下几种数据类型: 各类型都有具体的取值范围,超出或非法的其他值时,MySQL 会回退到 0.TIMESTAMP 类型是个例外,给它设置一个超出范围的值时,将保存上该类型允许的最大值 ...
最新文章
- 可持久化Trie+堆优化 OR Trie树上求XOR第K大 ---- P5283 [十二省联考2019]异或粽子
- java 按顺序取出json_java取json 的方法
- 在线富文本编辑器 UMeditor
- python ip动态代理_Python 爬虫设置动态代理
- 1001:Hello,World!
- Xamarin中国技术社区及BXUG官网上线啦
- 接口自动化- 基于 Python
- linux jobs
- Makefile:Makefile中的调试打印方法
- 59. DNS 服务器
- Linux下调用wps的Tables接口,WPS二次开发简单示例
- Windows 11彻底禁用IE浏览器后,银行网银系统完全解决方案!
- mediawiki修改用mysql数据库_MediaWiki定制化改动
- MAK VR-Forces 3.7
- HDUOJ 1069 Monkey and Banana
- Latex 表格的模版笔记
- 基于FPGA的视频图像拼接融合(附源码)。
- 线阵ccd模块LCAMV8-S11639-01/S11638高灵敏线阵图像传感器模组、驱动板
- 一文带您读懂FCC、CE、CCC认证的区别
- 多个Serial.print拼成一条Serial.print省时间吗?