java localdate_Java 基础系列-LocalDate相关

Java8已经出来好久了,然后我们平时工作中也遇到了好多的关于时间转换的问题,基本上就是需要的时间看一看源码,然后拿来直接用,其实真正理解的并不多。今天又遇到了关于String转换的问题,就决定写一篇文章出来。

那么在写具体的LocalDate前,我们先来看下为什么要在Java8中搞一套新的API呢,因为旧的Date类非常的难用,比如,其中的几个构造方法都被标注为@Deprecated,这里我总结了一些Date的一些问题

Date这个类既可以描述年月日,也可以描述时分秒,虽然万花筒用起来是挺好的,但是它既可以表示时间戳还可以表示日期,直观看来是不明确的。

而且作为一个日期类,它是可变的。所以作为返回对象时,返回的都应该是它的clone,而不是对象本身,否则的话可能会改变它的结构 。既然它是可变的,也就不是线程安全的,这是Date类面临的很大的问题之一。

这里请注意,Java8的LocalDate是线程安全的是因为它没有提供set方法,也就意味着一旦创建就不能修改值。而Date方法则提供了set方法

c985032e7885f9cad49d06ef3968ad02.png

在它的内部API中,getMonth返回的是0-11代表的月份,而getYear返回的是基于1900年的,即2018年为118年

下面面是摘自源码的注释

//The value returned is between 0 and 11,

with the value 0 representing January.

上面的注释已经指出了,一月是0,而且这个getMonth()方法明确了是@Deprecated。

/*** Returns a number representing the month that contains or begins

* with the instant in time represented by this Date object.

* The value returned is between 0 and 11,

* with the value 0 representing January.

*

*@returnthe month represented by this date.

*@seejava.util.Calendar

*@deprecatedAs of JDK version 1.1,

* replaced by Calendar.get(Calendar.MONTH).*/@Deprecatedpublic intgetMonth() {return normalize().getMonth() - 1; //adjust 1-based to 0-based

}

Date类为了兼容SQL,有一个java.sql.Date(这个Date仅包含日期),这就给我们日常的使用带来了很多迷惑。下图是sql.Date的方法

095436523b669785772c5f3d5e1b48bd.png

还有一个就是闰秒的问题,闰秒通常会在一个小时内用ntp更新一个好的系统时钟。在引入两个闰秒(至少每六个月一次,实际上每几年一次)的情况下,系统仍在运行的可能性非常小,特别是考虑到您必须不时地重新部署新版本的代码。即使使用动态语言来重新生成类或类似于WAR引擎的东西,也会污染类空间并最终耗尽permgen(这里摘自网络)

而且在我们经常和Date搭配使用的SimpleDateFormat中,parse()中,其中解析的时候,使用了CalendarBuilder calb = new CalendarBuilder();,然后在设置值的时候,是先用

CalendarBuilder的 establish(),establish方法的内容:

//这里是先清空

cal.clear();

...//然后再设置新的值

cal.setWeekDate(field[MAX_FIELD + WEEK_YEAR], weekOfYear, dayOfWeek);

如果在多个线程中,如果一个线程已经进行了clear(),而另一个线程期望这个值进行读取,可以想象造成的后果,所以如果在多线程中,要么不使用它,要么就要使它是安全的,所以可以:

1. 进行synchronization,虽然这是一个不好的做法

2. 在每个线程中进行单独的实例化,这将造成内存上的消耗,但是这是一个笨办法

3. 最后就是使用ThreadLocal,这是3个方法中最快的(3点建议摘自stackoverflow)

上边说了Date的一些问题,然后我们来说下Java8新增的日期API --- Date Time API

首先让我们来看下包结构。

6d849fb5c9c9f734b484bf3d12decfdc.png

我们可以看到常用的LocalDate, LocalDateTime, LocalTime.Instant类,这些类都是不可变,并且是线程安全的,没有提供set方法。

chrono包,这是一个日历相关的包,A calendar system, used to organize and identify dates 代码注释已经说明了

048e53b2c3cbb5e36f53e622d7025429.png

而且这个日历包是包括ISO日历和非ISO日历的(也就是公历和非公历)

ISO公历:国际标准ISO 8601,是国际标准化组织的日期和时间的表示方法,全称为《数据存储和交换形式·信息交换·日期和时间的表示方法》(https://zh.wikipedia.org/wiki/ISO_8601)

比如年由4位数字组成YYYY,或者带正负号的四或五位数字表示±YYYYY。月、日用两位数字表示:MM、DD。只使用数字为基本格式。使用短横线"-"间隔开年、月、日为扩展格式。

非ISO公历:泰国佛教日历,Hijrah日历,Minguo日历

251b523249b85b1bedc109fff50e666f.png

其中LocalDate就是我们的公历,而ThaiBuddhistDate是泰国的佛教日历

输出结果是

c515ba93f9371db653f9355f9b170079.png

当然有了不同的日历就有了转换,看代码

3d66b1084f51479dac484094f1778f73.png

输出是

5ee2f7c470c6cde006498538afb2ab8c.png

LocalDate和ThaiBuddhistDate都是Temporal的子类

format包,这是一个用于格式化和解析的包,不过我们不会经常用它,LocalDate类本身已经提供了相关操作

temporal包,使用字段和单位以及日期时间调整器访问日期和时间。该软件包扩展了基础软件包,为更强大的用例提供了额外的功能,包括

日期时间单位,例如年,月,日和小时

日期时间字段,例如月份,星期几或小时

日期时间调整功能

周的不同定义

比如像Date Time Package图提到的Month,MonthDay都是Temporal的子类

要查找给定日期之后的第一个星期几,请使用TemporalAdjusters.next(DayOfWeek),例如 date.with(next(MONDAY))

zone包。支持不同时区和规则的包。

接下来我们来看LocalDate

在LocalDate中,有以下常用的方法,

public staticLocalDate now() {returnnow(Clock.systemDefaultZone());

}public staticLocalDate now(ZoneId var0) {returnnow(Clock.system(var0));

}public staticLocalDate now(Clock var0) {

}public static LocalDate of(int var0, Month var1, intvar2) { ...}public static LocalDate of(int var0, int var1, intvar2) {

}public static LocalDate ofYearDay(int var0, intvar1) {

}public staticLocalDate from(TemporalAccessor var0) {

}public staticLocalDate parse(CharSequence var0) {returnparse(var0, DateTimeFormatter.ISO_LOCAL_DATE);

}public staticLocalDate parse(CharSequence var0, DateTimeFormatter var1) {

Objects.requireNonNull(var1,"formatter");return(LocalDate) var1.parse(var0, LocalDate::from);

}

在上面的代码中,其中now()方法,还有parse(),of(),是比较常用的方法,

523a863f4252e66db81f161e786aa339.png

输出是

a1d9d3f698597eaae4e56dd8d38af82c.png

可以看出,使用起来还是很方便的

LocalTime

LocalTime是一个不可变类,其实例表示人类可读格式的时间。它的默认格式是hh:mm:ss.zzz。

0a9e605782e55a12f399ab2dde179f2d.png

输出是

049d1a58503256cc0a342cea1500e76f.png

基本和LocalDate一样,这里不做太多叙述

LocalDateTime

01dc9bfbf8170c735f1b2725a8786502.png

输出是

bdc0cb0207f9884228780d2e5f599cda.png

Instant这是一个时间线上的瞬时点时间,可以理解为格林威治时间

d37d47ae30e591aa911d2b6c711ad3b3.png

我现在的时间是2018年10月9日21点02,输出是

be4b207d7c9a8ff537f16452e3ae64b4.png

接下来是java8 时间API的一些基本应用

1.转Date

55ca3e0b1fdc4d35e860f087d426d162.png

2.转String

now.toString()

3.一般用法

be3dc8404697145e8335c8c7d3bc0c4e.png

4.String转LocalDate

62fe804a3a01b4276334591a74d11d41.png

也可以自己自定义格式

5.取相关的日期

112b7476b442105a7ba106e8578e1048.png

6.取具体时间

3a9fd0301bc1fecad1e6ba31e26c5d91.png

7.时间比较

3a9df2a7c48ffb2ffa2757e766a2f9f0.png

3181c505097c3936dc6c63db9c84c0ce.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值