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

LocalDateTime和Date的比较与区别

通过本篇文章了解为什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的类】java8新的时间API的使用方式,包括创建、格式化、解析、计算

通过本篇文章了解

             



  • 为什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的类】

  • java8新的时间API的使用方式,包括创建、格式化、解析、计算、修改

 


为什么需要LocalDate、LocalTime、LocalDateTime

Date如果不格式化,打印出的日期可读性差


Tue Sep 10 09:34:04 CST 2019

使用SimpleDateFormat对时间进行格式化,但SimpleDateFormat是线程不安全的 SimpleDateFormat的format方法最终调用代码:



技术分享图片

private StringBuffer format(Date date, StringBuffer toAppendTo,
FieldDelegate delegate) {
// Convert input date to time field list
calendar.setTime(date);
boolean useDateFormatSymbols = useDateFormatSymbols();
for (int i = 0; i int tag = compiledPattern[i] >>> 8;
int count = compiledPattern[i++] & 0xff;
if (count == 255) {
count = compiledPattern[i++] <<16;
count |= compiledPattern[i++];
}
switch (tag) {
case TAG_QUOTE_ASCII_CHAR:
toAppendTo.append((char)count);
break;
case TAG_QUOTE_CHARS:
toAppendTo.append(compiledPattern, i, count);
i += count;
break;
default:
subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols);
break;
}
}
return toAppendTo;
}

技术分享图片



calendar是共享变量,并且这个共享变量没有做线程安全控制。当多个线程同时使用相同的SimpleDateFormat对象【如用static修饰的SimpleDateFormat】调用format方法时,多个线程会同时调用calendar.setTime方法,可能一个线程刚设置好time值另外的一个线程马上把设置的time值给修改了导致返回的格式化时间可能是错误的。

在多并发情况下使用SimpleDateFormat需格外注意
SimpleDateFormat除了format是线程不安全以外,parse方法也是线程不安全的。parse方法实际调用alb.establish(calendar).getTime()方法来解析,alb.establish(calendar)方法里主要完成了



  • 重置日期对象cal的属性值

  • 使用calb中中属性设置cal

  • 返回设置好的cal对象
    但是这三步不是原子操作





多线程并发如何保证线程安全





  • 避免线程之间共享一个SimpleDateFormat对象,每个线程使用时都创建一次SimpleDateFormat对象 => 创建和销毁对象的开销大

  • 对使用format和parse方法的地方进行加锁 => 线程阻塞性能差

  • 使用ThreadLocal保证每个线程最多只创建一次SimpleDateFormat对象 => 较好的方法






Date对时间处理比较麻烦,比如想获取某年、某月、某星期,以及n天以后的时间,如果用Date来处理的话真是太难了,你可能会说Date类不是有getYear、getMonth这些方法吗,获取年月日很Easy,但都被弃用了啊

一起使用java8全新的日期和时间API

 

创建LocalDate 只获取某年某月



技术分享图片

//获取当前年月日
LocalDate localDate = LocalDate.now();
System.out.println("当前的年月日:"+localDate);
//构造指定的年月日
LocalDate localDate1 = LocalDate.of(2019, 9, 10);
System.out.println("指定的年月日:"+localDate1);

 

  当前的年月日:2020-01-13
  指定的年月日:2019-09-10

 

技术分享图片

获取年、月、日、星期几



技术分享图片

LocalDate localDate = LocalDate.now();
int year = localDate.getYear();
int year1 = localDate.get(ChronoField.YEAR);
System.out.println("当前年:"+year);
System.out.println("当前年:"+year1);
Month mOnth= localDate.getMonth();
int month1 = localDate.get(ChronoField.MONTH_OF_YEAR);
System.out.println("当前月:"+month);
System.out.println("当前月:"+month1);
int day = localDate.getDayOfMonth();
int day1 = localDate.get(ChronoField.DAY_OF_MONTH);
System.out.println("当前天:"+day);
System.out.println("当前天:"+day1);
DayOfWeek dayOfWeek = localDate.getDayOfWeek();
int dayOfWeek1 = localDate.get(ChronoField.DAY_OF_WEEK);
System.out.println("当前星期:"+dayOfWeek);
System.out.println("当前星期:"+dayOfWeek1);


当前年:2020
当前年:2020
当前月:JANUARY
当前月:1
当前天:13
当前天:13
当前星期:MONDAY
当前星期:1


技术分享图片

获取时分秒



技术分享图片

  创建LocalTime
LocalTime localTime = LocalTime.of(13, 51, 10);
LocalTime localTime1 = LocalTime.now();
System.out.println("当前时间:"+localTime);
System.out.println("当前时间:"+localTime1);
//获取时分秒
//获取小时
int hour = localTime.getHour();
int hour1 = localTime.get(ChronoField.HOUR_OF_DAY);
System.out.println("当前小时:"+hour);
System.out.println("当前小时:"+hour1);
//获取分
int minute = localTime.getMinute();
int minute1 = localTime.get(ChronoField.MINUTE_OF_HOUR);
System.out.println("当前分钟:"+minute);
System.out.println("当前分钟:"+minute1);
//获取秒
int secOnd= localTime.getMinute();
int second1 = localTime.get(ChronoField.SECOND_OF_MINUTE);
System.out.println("当前秒:"+second);
System.out.println("当前秒:"+second1);
    当前时间:13:51:10
    当前时间:10:08:13.687
    当前小时:13
    当前小时:13
    当前分钟:51
    当前分钟:51
    当前秒:51
    当前秒:10

技术分享图片


LocalDateTime


获取年月日时分秒,等于LocalDate+LocalTime

创建LocalDateTime


LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime localDateTime1 = LocalDateTime.of(2019, Month.SEPTEMBER, 10, 14, 46, 56);
LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime);
LocalDateTime localDateTime3 = localDate.atTime(localTime);
LocalDateTime localDateTime4 = localTime.atDate(localDate);

 

 

还有一些对时间的操作api 相当于之前的旧API简单了很多,

和SimpleDateFormat相比,DateTimeFormatter是线程安全的





推荐阅读
  • 深入浅出:Java面向对象编程
    本文详细介绍了Java语言的核心特性——面向对象编程。探讨了Java的基本概念、平台无关性、丰富的内置类库及安全性,同时深入解析了类加载器、垃圾回收机制以及基本数据类型和其包装类。 ... [详细]
  • 在现代多线程编程中,Lock接口提供的灵活性和控制力超越了传统的synchronized关键字。Lock接口不仅使锁成为一个独立的对象,还提供了更细粒度的锁定机制,例如读写锁(ReadWriteLock)。本文将探讨如何利用ReentrantReadWriteLock提高并发性能。 ... [详细]
  • 本文深入探讨了Java注解的基本概念及其在现代Java开发中的应用。文章不仅介绍了如何创建和使用自定义注解,还详细讲解了如何利用反射机制解析注解,以及Java内建注解的使用场景。 ... [详细]
  • 本文详细介绍了Android平台上的动态加载技术,包括其定义、分类及具体实现步骤。通过动态加载技术,开发者可以在不更新应用的情况下,向用户推送新的功能或修复bug,从而提升用户体验。 ... [详细]
  • 本文探讨了在Android平台下编写和读取.JSON文件的方法,解决读取文件时遇到的字符间异常空格问题。 ... [详细]
  • Redis 教程01 —— 如何安装 Redis
    本文介绍了 Redis,这是一个由 Salvatore Sanfilippo 开发的键值存储系统。Redis 是一款开源且高性能的数据库,支持多种数据结构存储,并提供了丰富的功能和特性。 ... [详细]
  • 无脚本 JSP 的 Web 页面设计
    探讨了Web页面设计人员是否需要掌握Java技能,以及他们如何快速学习表达式语言(EL)。虽然EL的应用前景尚不明朗,但本文将重点介绍如何通过JSP的include指令有效整合页面元素。 ... [详细]
  • 本文详细介绍了如何手动编写兼容IE的Ajax函数,以及探讨了跨域请求的实现方法和原理,包括JSONP和服务器端设置HTTP头部等技术。 ... [详细]
  • 本文详细介绍了 Java 中 javax.faces.component.UIInput 类的 getParent() 方法的使用场景及其代码实现,通过多个实际案例帮助开发者更好地理解和应用该方法。 ... [详细]
  • 导读上一篇讲了zsh的常用字符串操作,这篇开始讲更为琐碎的转义字符和格式化输出相关内容。包括转义字符、引号、print、printf的使用等等。其中很多内容没有必要记忆,作为手册参 ... [详细]
  • Spring Boot 应用程序实现开机自启的步骤
    本文介绍如何将Spring Boot项目打包成的JAR文件配置为系统启动时自动运行的方法,包括创建批处理文件和设置任务计划等步骤。 ... [详细]
  • 本文介绍了一种利用迭代法解决特定方程问题的方法,特别是当给定函数f(x)在区间[x1, x2]内连续且f(x1)0时,存在一个x~使得f(x~)=0。通过逐步细化搜索范围,可以高效地找到方程的根。 ... [详细]
  • 一个产品数组拼图|集合 2 (O(1)空间) ... [详细]
  • 本文探讨了C#中所有内置数据类型如何通过默认构造函数初始化,并提供了一个示例方法来展示这些类型的默认值。 ... [详细]
  • Java 中SimpleDateFormat 错误用法及改正 ... [详细]
author-avatar
胡鹏锦_289
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有