Java中LocalDate、LocalTime、LocalDateTime三个时间⼯具
类。。。
Java中 LocalDate、LocalTime、LocalDateTime三个时间⼯具类的使⽤介绍
⼀、背景:
之前在做项⽬的过程中,对⽇期时间类没有⼀个系统的了解,总是在⽤的时候去搜索⼀下,解决问题即完事,久⽽久之,导致对这个概念特别模糊。直到近期,做项⽬的过程中使⽤了mybatis-plus框架,这个框架⾃动⽣成映射⽂件的⼯具会将MySQL中的datetime类型转化成Java中的LocalDateTime类型,由于⼏次都出现了转化错误、转化繁琐的问题,因此,就打算详细的了解⼀下Java中的时间类的相关知识,希望下次再使⽤能够做到⼼中有底。经过了⼏天的了解,对这个时间概念算是有了⼀个⼤致的了解,记录下来供以后参考。看来解决问题还得要抓住问题的本质,了解技术的来龙去脉,不能浮于表⾯。(更好的阅读体验,请移步我的)
⼆、介绍:
在JDK8发布的时候,推出了LocalDate、LocalTime、LocalDateTime这个三个时间处理类,以此来弥补之前的⽇期时间类的不⾜,简化⽇期时间的操作。在Java8之前,处理⽇期时间的类是Date、Calen
dar,这两个在使⽤起来总是让⼈感觉不是很舒服,在设计上⾯有⼀些缺陷,并且还不是线程安全的。
想要详细的了解这⼏个类,我们得要了解⼀点关于时间、时区划分的⼀些知识。1884 年, 国际经度会议将地球表⾯按经线等分为24区,称为时区。即以本初⼦午线为基准, 东西经度各7.5 度的范围作为零时区, 然后每隔15度为⼀时区,每个时区相差⼀⼩时。北京时区为东⼋区,要⽐零时区早8个⼩时。如果现在零时区的时间是10点的话,那北京时间就是18点。
我们平时在程序⾥⾯所见到的UTC时间,就是零时区的时间,它的全称是Coordinated Universal Time ,即世界协调时间。另⼀个常见的缩写是GMT,即格林威治标准时间,格林威治位于 零时区,因此,我们平时说的UTC时间和GMT时间在数值上⾯都是⼀样的。
可能会有⼀些疑问,同样是在地球上啊,不同的地区时间怎么还不⼀样了?难道我现在从北京乘个飞机飞到格林威治,还可以来个时光倒流?如果这样,岂不很神奇?哈哈,当然事情的真相并不是这样的。时间的流逝、细胞的衰⽼对于整个地球来说都是⼀样的,因此,不管你在地球的哪⾥,这⼀秒过去了,就是过去了,它最为公平,不会多你⼀分,也不会少你⼀秒。那怎么记录这流逝的分分秒秒呢?有⼀个名词,叫做时间戳,它是指格林威治(地球零时区)时间1970年01⽉01⽇00时00分00秒(北京时间1970年01⽉01⽇08时00分00秒)起⾄现在的总秒数,这个时间戳,在地球的各个地⽅都是⼀致的。在1970年以前,有其他的计时⽅式,由于没有统⼀,还造成了⼀些软件的运⾏在时间上的错乱,
险些酿成了的⾏业灾难(具体的事件可以⽹上搜索)。如果单纯指望这个时间戳作为⼈们的计时标准,那也是不现实的,因为这对⼈类的⽣产⽣活来说没有任何的意义。举个例⼦:每天早上⼋点上课(上班)符合我们的习惯,如果是***秒到了上课时间就有违⼈的正常脑回路了。这时候,根据地球上的不同经纬度、地球⾃转的特点,就划分了时区,时间戳根据不同的时区转化成当地的时间,以此作为作息标准,从⽽⽅便⼈们的⽣产⽣活。北京时间的8点我们可以见到太阳的升起,伦敦时间的⼋点他们也能见到太阳的升起。
就这样,可以知道,时间戳对地球上的任何⼀个地⽅都是⼀样的,如果我们想要把时间戳转化成当地的时间,就需要根据所在地区的时区进⾏转化。不同时区之间进⾏时间转化也是⼀样的道理,我们需要根据时区的差异来转化当地的时间。
三、使⽤⽅法:
3.1 Java8 以前的时间处理:
1,Date类的使⽤:
SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class TestTime {
public static void main(String[] args) {
try {
//获取Date对象,存放的是时间戳
Date date = new Date();
//获取时间戳(毫秒)
long seconds = Time();
System.out.println("当前时间戳: " + seconds);
//当前GMT(格林威治)时间、当前计算机系统所在时区的时间
SimpleDateFormat beijingFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("本地(东⼋区)时间: " + beijingFormat.format(date) +"; GMT时间: " + GMTString());
//东⼋区时间转换成东九区(东京)时间,⽐北京早⼀个⼩时
SimpleDateFormat tokyoFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
tokyoFormat.TimeZone("Asia/Tokyo"));
System.out.println("东京(东九区)时间: "+tokyoFormat.format(date));
//时间戳转化成Date
SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String fotmatString = timestampFormat.format(seconds);
Date parseDate = timestampFormat.parse(fotmatString);
System.out.println("时间戳转化成Date之后的时间: "+parseDate + ";格式化之后的: "+ fotmatString);
} catch (Exception e) {
e.printStackTrace();
string转date的方法}
}
}
输出结果如下:
Date的⽆参构造函数如下图:
我们可以看到,Date中存放的是时间戳,因此,我们在世界各地调⽤这个⽅法,获取到的值都是⼀样的。只是在不同的地⽅,这个值会根据时区转化成当地的时间⽽已。
3.2 Java8 之后的时间处理:
从Java8开始,推出了LocalDate、LocalTime、LocalDateTime这三个⼯具类,实现了更好地时间处理,我们先看如何使⽤,然后,再进⾏⽐较。
1,⼯具类的获取与使⽤:
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public class TestLocalTime {
public static void main(String[] args) {
//获取当前时区的⽇期
LocalDate localDate = w();
System.out.println("localDate: " + localDate);
//时间
LocalTime localTime = w();
System.out.println("localTime: " + localTime);
/
/根据上⾯两个对象,获取⽇期时间
LocalDateTime localDateTime = LocalDateTime.of(localDate,localTime);
System.out.println("localDateTime: " + localDateTime);
//使⽤静态⽅法⽣成此对象
LocalDateTime localDateTime2 = w();
System.out.println("localDateTime2: " + localDateTime2);
//格式化时间
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss");
System.out.println("格式化之后的时间: " + localDateTime2.format(formatter));
//转化为时间戳(秒)
long epochSecond = EpochSecond(ZoneOffset.of("+8"));
/
/转化为毫秒
long epochMilli = localDateTime2.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli();
System.out.println("时间戳为:(秒) " + epochSecond + "; (毫秒): " + epochMilli);
//时间戳(毫秒)转化成LocalDateTime
Instant instant = Instant.ofEpochMilli(epochMilli);
LocalDateTime localDateTime3 = LocalDateTime.ofInstant(instant, ZoneOffset.systemDefault());
System.out.println("时间戳(毫秒)转化成LocalDateTime: " + localDateTime3.format(formatter));
//时间戳(秒)转化成LocalDateTime
Instant instant2 = Instant.ofEpochSecond(epochSecond);
LocalDateTime localDateTime4 = LocalDateTime.ofInstant(instant2, ZoneOffset.systemDefault());
System.out.println("时间戳(秒)转化成LocalDateTime: " + localDateTime4.format(formatter));
}
}
上述程序运⾏结果如下图所⽰:
新推出来的这三个类,与MySQL中的⽇期时间类型正好对应,如果我们使⽤MySQL数据库的话,在插⼊相应字段的时候,都不需要再进⾏任何的转化了。对应关系如下:
LocalTime 对应 time
LocalDate 对应 date
LocalDateTime 对应 datetime(timestamp)
2,增加、减去时间:
看看上图,是不是⾮常的简单⽅便呢。
3,LocalDateTime 与 Date 的相互转化
// Date 转化成 LocalDateTime
public static LocalDateTime dateToLocalDate(Date date) {
Instant instant = Instant();
ZoneId zoneId = ZoneId.systemDefault();
return instant.atZone(zoneId).toLocalDateTime();
}
// LocalDateTime 转化成 Date
public static Date localDateTimeToDate(LocalDateTime localDateTime) {
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = localDateTime.atZone(zoneId);
return Date.Instant());
}
由于 LocalDate、LocalTime 或者只含有⽇期,或者只含有时间,因此,不能和Date直接进⾏转化。
四、总结:
了解好时区,时间戳等这⼏个概念,对于我们了解程序语⾔中时间类的构造⾮常有帮助。Java8 新推出来的这三个类,不仅让我们在⽇常编程中更为⾼效⽅便,⽽且,在与数据库时间类型的对应上更为友好。
最后总结:
1,时间戳: 是指格林威治(地球零时区)时间1970年01⽉01⽇00时00分00秒起⾄现在的总秒数,这个时间戳,在地球的各个地⽅都是⼀致的;
2,时区:由于地球的⾃转,根据接收太阳光照的顺序将地球划分成24个区,从⽽⽅便当地⼈的⽣产⽣活,每个时区相差⼀⼩时,可以根据时间戳和时区计算当地的时间。格林威治处于零时区,北京处于东⼋区,因此,北京时间⽐格林威治时间早8个⼩时。
3,LocalDateTime ⽐ Date使⽤起来更为⽅便,两者可以相互进⾏转化。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论