Instant及LocalDateTime等使用方法

/ ARC / 没有评论 / 20浏览
欢迎关注微信公众号:程序员小圈圈
原文首发于:www.zhangruibin.com
本文出自于:RebornChang的博客
转载请标明出处^_^

Instant

在看阿里开发规范手册时,看到了这点:

【强制】SimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为static,必须加锁,或者使用DateUtils工具类。 正例:注意线程安全,使用DateUtils。亦推荐如下处理: private static final ThreadLocal df = new ThreadLocal() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); } }; 说明:如果是JDK8的应用,可以使用Instant代替Date,LocalDateTime代替Calendar,DateTimeFormatter代替Simpledateformatter,官方给出的解释:simple beautiful strong immutable thread-safe。

上面提到了两个知识点,Instant和LocalDateTime以及DateTimeFormatter。 细想之下之前对这个小知识还真的忽略了,所以来说下各个的用法。

Instant

通过查看源码我们可以看到,Instant implements Temporal, TemporalAdjuster, Comparable, Serializable 注释上写着:This class is immutable and thread-safe.也就是线程安全。 简单的来说, Instant 类代表的是某个时间(有点像 java.util.Date),它是精确到纳秒的(而不是象旧版本的Date精确到毫秒)。如果使用纳秒去表示一个时间则原来使用一位Long类型是不够的,需要占用更多一点的存储空间,实际上其内部是由两个Long字段组成,第一个部分保存的是自标准Java计算时代(就是1970年1月1日开始)到现在的秒数,第二部分保存的是纳秒数(永远不会超过999,999,999)。

那么怎么使用呢? 看下面:

Instant instantNow = Instant.now();
System.out.println("now:"+instantNow);

上面我们可以看到,直接now出来的时间和我们现在的北京时间也就是东八区时间有出入,看下源码注释,调用这个now()会查询一个system UTC clock,也就是:

Clock clock = Clock.systemUTC();

也就是说,如果你在中国的话,得到的不是中国(东八区)时间,那怎么才是中国时间呢?加八个小时就是北京时间:

Instant now = Instant.now().plusMillis(TimeUnit.HOURS.toMillis(8));

那怎么获得1970-01-01T00:00:00Z.到现在的秒数及毫秒数呢?

System.out.println("秒数:"+now.getEpochSecond()); 
System.out.println("毫秒数:"+now.toEpochMilli());

LocalDateTime

如果说上面的instant是需要手动增加时间来确定自己的时区时间,那么LocalDateTime就不需要增加时间,使用方法与instant是有相似之处的:

LocalDateTime localDateTime = LocalDateTime.now();

而且还可以进行比较,转化等操作,如下:

LocalDateTime localDateTime = LocalDateTime.now();
//当前时间
System.out.println("localDateTime:"+localDateTime);
//format时间
System.out.println("localDateTimeFormat:"+localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH🇲🇲ss")));


//定义localDateTime LocalDateTime localDateTime = LocalDateTime.now();
LocalDate now1 = LocalDate.now();
LocalTime now2 = LocalTime.now();
System.out.println("localDateTime:"+localDateTime);
System.out.println("now1:"+now1);
System.out.println("now2:"+now2);
System.out.println("localDateTimeFormat:"+localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH🇲🇲ss")));

//定义localDateTime2 LocalDateTime localDateTime2 = localDateTime.minus(23, ChronoUnit.MONTHS);
localDateTime.atZone(ZoneId.systemDefault());
localDateTime2 = localDateTime2.withHour(3);
localDateTime2 = localDateTime2.withYear(2019);
localDateTime2 = localDateTime2.with(ChronoField.MONTH_OF_YEAR,3);
System.out.println("localDateTime2:"+localDateTime2);

//比较两个时间 Duration duration = Duration.between(localDateTime,localDateTime2);
System.out.println("比较日:"+duration.toDays());
System.out.println("比较时:"+duration.toHours());
System.out.println("比较分:"+duration.toMinutes());

Period period = Period.between(localDateTime.toLocalDate(),localDateTime2.toLocalDate());
System.out.println("比较年:"+period.getYears());
System.out.println("比较月:"+period.getMonths());
System.out.println("比较日:"+period.getDays());
//互相转化 Date date = Date.from(localDateTime2.atZone(ZoneId.systemDefault()).toInstant());
LocalDateTime dateTime = LocalDateTime.ofInstant(date.toInstant(),ZoneId.systemDefault());

localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH🇲🇲ss"));

稍微提下LocalDate及LocalTime,这两个欠着是不带具体的时分秒只有年月日,后者是不带具体的年月日只有时分秒。

DateTimeFormatter

强力的时间类型模式化工具,有多强呢? 看看下面:

//定义新的时间 LocalDateTime newTime = LocalDateTime.now();
//定义多种格式化类型 DateTimeFormatter[] formatters = new DateTimeFormatter[]{
        // 直接使用常量创建DateTimeFormatter格式器
 //第1种  DateTimeFormatter.ISO_LOCAL_DATE,
        //第2种
  DateTimeFormatter.ISO_LOCAL_TIME,
        //第3种
  DateTimeFormatter.ISO_LOCAL_DATE_TIME,
        //第4种
 // 使用本地化的不同风格来创建DateTimeFormatter格式器  DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM),
        //第5种
  DateTimeFormatter.ofLocalizedTime(FormatStyle.LONG),
        //第6种
 // 根据模式字符串来创建DateTimeFormatter格式器  DateTimeFormatter.ofPattern("Gyyyy%%MMM%%dd HH🇲🇲ss")
};
// 依次使用不同的格式器对LocalDateTime进行格式化 System.out.println("开始使用DateTimeFormatter进行格式化");
for(int i = 0 ; i < formatters.length ; i++){
    // 下面两行代码的作用相同
  System.out.println(newTime.format(formatters[i]));
    System.out.println(formatters[i].format(newTime));
}

控制台输出:

开始使用DateTimeFormatter进行格式化
2019-09-23
2019-09-23
15:42:47.06
15:42:47.06
2019-09-23T15:42:47.06
2019-09-23T15:42:47.06
2019年9月23日 星期一 15:42:47
2019年9月23日 星期一 15:42:47
下午03时42分47秒
下午03时42分47秒
公元2019%%九月%%23 15:42:47
公元2019%%九月%%23 15:42:47

OK,对于这几点的简单介绍到这里就差不多了,有兴趣的小伙伴可以自行深入研究~~ ,博主的微信公众号
程序员小圈圈’开始持续更新了哟~~
识别二维码或者直接搜索名字 ‘程序员小圈圈’ 即可关注本公众号哟~~
不只是有技术哟~~ 还有很多的学习娱乐资源免费下载哦~~ 还可以学下教育知识以及消遣娱乐哟~~ 求关注哟~~ '