热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java前端多个时间段的设置,java8的时间和`Date`的对比

java8的时间和Date的对比java8提供了新的时间接口。相对Date,Calendar,个人感觉最大的好处是对时间操作的学习成本很低,比Calendar低。1.

java8的时间和Date的对比

java8提供了新的时间接口。相对Date,Calendar,个人感觉最大的好处是对时间操作的学习成本很低,比Calendar低。

1. LocalDate,LocalTime,LocalDateTime

LocalDate 代表日期,LocalTime表示时刻,类似11:23这样的时刻。 LocalDateTime就是前面2个的结合,这个可以从java.time.LocalDateTime#toString的代码看出一二:

@Override

public String toString() {

return date.toString() + 'T' + time.toString();

}

date,time 在java.time.LocalDateTime中

/**

* The date part.

*/

private final LocalDate date;

/**

* The time part.

*/

private final LocalTime time;

实际使用中,计算日期就用LocalDate,计算日期加时刻用LocalDateTime,如果只有时刻就是LocalTime(感觉在说废话)

这三个的用法基本上一样,通过方法名就知道用法那种

1.1 获取当前时间的对象

LocalDateTime localDateTime = LocalDateTime.now();

Date date = new Date();

localDateTime相比Date更像是一个工具类,就是为了时间操作使用。其构造方法是私有的。

1.2 从字符串中解析

字符串 2019-01-11 解析成时间对象

String str = "2019-01-11";

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

LocalDate localDate = LocalDate.parse(str, formatter);

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

try {

Date date = simpleDateFormat.parse(str);

} catch (ParseException e) {

e.printStackTrace();

}

DateTimeFormatter的包路径是java.time.format和LocalDate一样在java.time下面,而SimpleDateFormat和Date是不同的。所以当判断引入路径的时候更容易判断。

当解析失败的时候,两个异常的抛出不一样,DateTimeFormatter抛出的是DateTimeParseException,继承自RuntimeException,而ParseException明显继承的是Exception。

个人感觉这个思路是,前者如果抛出异常那就是编程上错误,而后者则是的程序代码的不稳定性。我更倾向于第一种的异常设计,应该加强对入参的检测判断,而不是通过捕获异常去处理入参的错误。(类似NumberFormatException)

1.3 LocalDate比Date更强的初始化时间

Date 设置某个日期,基本上3个方式,时间戳/Calendar/字符串解析。相对的LocalDate就简单了很多

LocalDate.of(2019,1,12);

其他的也一样

7juENj.jpg

1.4 时间戳的转换

在这里时间戳的转换不如Date直接。主要因为LocalDate本身是没有时区的。

时间戳传LocalDateTime

long timestamp = System.currentTimeMillis();

Instant instant = Instant.ofEpochMilli(timestamp);

LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

LocalDateTime转时间戳

LocalDateTime dateTime = LocalDateTime.now();

dateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();

dateTime.toInstant(ZoneOffset.of("+08:00")).toEpochMilli();

dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();

关于时区的计算也很简单,就是相差几个小时就加上多少秒

2IVzAz.jpg

有些时区计算的时候,不妨自己加时间也一样,elasticsearch+logstash设置@timestamp时间是默认UTC Z的时间,和咱们差了8个小时

LocalDateTime.parse(json.getString("@timestamp"), DateTimeFormatter.ISO_DATE_TIME).plusHours(8L)

1.5 和Date互转

import java.time.Instant;

import java.util.Date;

public class Main {

public static void main(String[] args) {

Date dt = new Date();

System.out.println("Date: " + dt);

Instant in = dt.toInstant();

System.out.println("Instant: " + in);

Date dt2 = Date.from(in);

System.out.println("Date: " + dt2);

}

}

Instant 和 LocalDate或LocalDateTime 就不赘述了…

1.6 更好的理解和操作方式

Date、Calendar的操作,例如设置月份,day of week 都有些让人迷惑,例如1月的定义是0,周一是0。1号好像也是0吧(我真没咋用过这东西,现用现百度…

LocalDate感觉好多了。例如DayOfWeek是枚举类型。使用枚举就不会理解错了吧

3ieqAj.jpg

很多日期和时间操作,无非就是加减时间和比较.

使用‘加’的示例:

z2ymEj.jpg

不用再去使用一个不熟悉的Calendar去操作了(Calendar提供的接口都是啥玩意,get,set的)

Calendar cal = Calendar.getInstance();

cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + 1)

2. 线程安全性比较

LocalDate…系列是线程安全的

额..每一个字段都用了final关键字了,都变不了… 所以进行操作后都是返回新的copy对象

7RfIVv.jpg

至于说Date线程不安全,get,set的肯定在多线程的时候容易出现问题,不过set方法已经都@Deprecated废弃了。当然不是因为线程安全问题废弃的,是因为有了更好的替代

Calendar.set(Calendar.DAY_OF_MONTH, int date)

不过感觉还是不如这个更清晰明了

LocalDate.of(2019,1,12);

2.1 SimpleDateFormat的线程安全性

在一定负载情况下,SimpleDateFormat会出问题的。简单测试一下

package open.note;

import java.text.SimpleDateFormat;

import java.time.LocalDateTime;

import java.time.format.DateTimeFormatter;

import java.util.Date;

import java.util.concurrent.CountDownLatch;

import java.util.function.Consumer;

public class UnSafeTest {

private static String time = "2019-01-11 11:11:11";

private static long timestamp = 1547176271000L;

private static LocalDateTime dateTime = LocalDateTime.of(2019,1,11,11,11,11);

private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

public static void main(String[] args) {

dateFormatTest((obj)->{

try {

Date date = dateFormat.parse(time);

if (date.getTime() != timestamp){

System.out.println(date);

}

} catch (Exception e) {

System.out.println(e.getMessage());

}

});

System.out.println("---------------");

dateFormatTest((obj)->{

try {

LocalDateTime dateTime = LocalDateTime.parse(time,formatter);

if (!dateTime.isEqual(UnSafeTest.dateTime)){

System.out.println(dateTime);

}

} catch (Exception e) {

System.out.println(e.getMessage());

}

});

}

private static void dateFormatTest(Consumer runnable){

CountDownLatch countDownLatch = new CountDownLatch(1000);

for (int i &#61; 0; i <1000; i&#43;&#43;) {

new Thread(()->{

runnable.accept(null);

countDownLatch.countDown();

}).start();

}

try {

countDownLatch.await();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

输出结果

multiple points

multiple points

empty String

Sat Jan 11 11:11:11 CST 111

Fri Jan 04 11:11:11 CST 2019

For input string: ""

Mon Dec 31 11:11:11 CST 2018

Mon Dec 31 11:11:11 CST 2018

For input string: ""

Tue Jan 11 11:11:11 CST 42101

---------------

测试过程中&#xff0c;SimpleDateFormat 1000个线程里&#xff0c;有5次&#xff0c;时间解析错了&#xff0c;5次异常了(时间错了&#xff0c;比抛出异常还可怕)

DateTimeFormatter只是对比参考一下,未出现异常(人家已经声明是线程安全了…)

当然SimpleDateFormat线程不安全应该人尽皆知的&#xff0c;但依然有不安全的使用&#xff0c;但每次使用都new一个实例&#xff0c;当负载大的时候也不好。所以一个线程一个SimpleDateFormat实例应该可以的。

最后

java8 对时间操作的类还有很多 到java.time包下去看看&#xff0c;以后总会用得到的地方。

Instant&#xff1a;时间戳

Duration&#xff1a;持续时间&#xff0c;时间差

LocalDate&#xff1a;只包含日期&#xff0c;比如&#xff1a;2016-10-20

LocalTime&#xff1a;只包含时间&#xff0c;比如&#xff1a;23:12:10

LocalDateTime&#xff1a;包含日期和时间&#xff0c;比如&#xff1a;2016-10-20 23:14:21

Period&#xff1a;时间段

ZoneOffset&#xff1a;时区偏移量&#xff0c;比如&#xff1a;&#43;8:00

ZonedDateTime&#xff1a;带时区的时间

Clock&#xff1a;时钟&#xff0c;比如获取目前美国纽约的时间



推荐阅读
  • Visual Studio 2015 开发 ASP.NET 5 有何变化?
    Visual Studio 2015 开发 ASP.NET 5 有何变化? ... [详细]
  • Spring Cloud笔记Spring Cloud Stream消息驱动(十五)
    1.消息驱动概述1.SpringCloudStream是什么SpringCloudStream是一个构建消息驱动微服务的框架。应用程序通过Inpust和Outputs与Spri ... [详细]
  • 本文讨论了如何使用GStreamer来删除H264格式视频文件中的中间部分,而不需要进行重编码。作者提出了使用gst_element_seek(...)函数来实现这个目标的思路,并提到遇到了一个解决不了的BUG。文章还列举了8个解决方案,希望能够得到更好的思路。 ... [详细]
  • IOSUITableView解析(一)
    UITableView的作用由于Iphone的大小有限,所以UITableView的作用是巨大的。比如QQ,微博等应用都用到了该控件。UITableVi ... [详细]
  • 问题说明最近看到Spring事务,在学习过程中遇到一个很苦恼问题搭建好Spring的启动环境后出现了一点小问题在启动时候却出现[java.lang.NullPointerExcep ... [详细]
  • oracle text db2,从Oracle 到DB2(一)
    在实际的软件项目的开发过程中,特别是在企业的应用系统集成(EAI)项目中广大开发人员经常遇到不同关系型数据库之间的数据移植问题。笔者根据自己在工作中的不同数据库数据移 ... [详细]
  • 本文整理了Java中com.atlassian.scheduler.config.JobConfig类的一些代码示例,展示了JobConfig ... [详细]
  • C#使用System.Net.Mail类实现邮件发送【.Net开发】
    这篇文章介绍了C#使用System.Net.Mail类实现邮件发送的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值, ... [详细]
  • 如何实现Percona Mysql Galera多读写集群的部署
    本篇文章给大家主要讲的是关于如何实现PerconaMysqlGalera多读写集群的部署的内容,感兴趣的话就一起来看看这篇文章吧,相信看完如何实现PerconaMysq ... [详细]
  • 为什么需要有应用层缓冲区?muduo网络库使用IO复用,并且文件描述符使用非阻塞模式,如果使用阻塞模式那么read、write就会阻塞在 ... [详细]
  • 本文整理了Java中java.lang.Iterable.iterator()方法的一些代码示例,展示了Iterable.iterator() ... [详细]
  • 微服务应用性能如何?APM监控工具来告诉你
    当微服务系统越来越庞大,各个服务间的调用关系也变得越来越复杂,需要一个工具来帮忙理清请求调用的服务链路。之前使用的是Sleuth+Zipkin的解决方案,最近发现应 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 本文提供了关于数据库设计的建议和注意事项,包括字段类型选择、命名规则、日期的加入、索引的使用、主键的选择、NULL处理、网络带宽消耗的减少、事务粒度的控制等方面的建议。同时还介绍了使用Window Functions进行数据处理的方法。通过遵循这些建议,可以提高数据库的性能和可维护性。 ... [详细]
  • 本文讨论了在使用Git进行版本控制时,如何提供类似CVS中自动增加版本号的功能。作者介绍了Git中的其他版本表示方式,如git describe命令,并提供了使用这些表示方式来确定文件更新情况的示例。此外,文章还介绍了启用$Id:$功能的方法,并讨论了一些开发者在使用Git时的需求和使用场景。 ... [详细]
author-avatar
小张
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有