一文搞懂Java中的日期类
一、日期类
在程序的开发中我们经常会遇到日期类型的操作,Java对日期类型的操作提供了很好的支持。在最初的版本下,java.lang包中的System.currentTimeMillis();可以获取当前时间与协调时间(UTC)1970年1月1日午夜之间的时间差(以毫秒为单位测量)。我们往往通过调用该方法计算某段代码的耗时。
public class TestTime { public static void main(String[] args) { long start=System.currentTimeMillis(); long sum=0; for (int i = 0; i < 1000000; i++) { sum+=i; } System.out.println("sum="+sum); long end=System.currentTimeMillis(); System.out.println("耗时:"+(end-start)+"ms"); } }
1.1 第一代日期类
第一代日期时间API主要有java.util.Date和日期时间格式化有关的java.text.DateFormat及其子类。
1.1.1 Date类
JDK1.0就在java.util包下面提供了Date类用于表示特定的瞬间,可以精确到毫秒。
通过API或源码,可以看出Date类的大部分方法已经过时,已被第二代日期类Calendar代替,剩下的Date类常见方法如下所示。
序号 | 方法定义 | 描述 |
---|---|---|
1 | Date() | 返回一个代表当前系统时间的Date对象,精确到毫秒 |
2 | Date(long date) | 返回一个距离UTC时间date毫秒的新日期对象,精确到毫秒 |
3 | int compareTo(Date anotherDate) | 比较两个日期的大小 |
4 | long getTime() | 返回自1970年1月1日00:00:00 GMT以来此Date对象表示的毫秒数 |
5 | String toString() | 把此Date对象转换为以下形式的String:dow mon dd hh:mm:ss zzz yyyy其中:dow是一周中的某一天(Sun,Mon,Tue,Wed,Thu,Fri,Sat) |
import java.util.Date; public class DateTest { public static void main(String[] args) { Date date = new Date(); System.out.println("现在的系统时间是:"+date); long time=date.getTime(); System.out.println("当前时间距离UTC时间的毫秒数:"+time); } }
1.1.2 SimpleDateFormat类
Date类显示的格式没有考虑国际化问题,如该格式不符合中国人查看时间的格式习惯,因此需要对其进行格式化操作。java.text.SimpleDateFormat类可以实现格式化操作,它是java.text.DateFormat的子类。
创建SimpleDateFormat类的对象非常简单,可以使用如下构造器:
- SimpleDateFormat():用默认的模式和默认的语言环境的日期格式符号构造SimpleDateFormat。
- SimpleDateFormat(String pattern):用给定的模式和默认语言环境的日期格式符号构造SimpleDateFormat。
- SimpleDateFormat(String pattern,Locale locale):用给定的模式和给定语言环境的日期格式符号构造。
常见的日期格式化模板如下:
SimpleDataFormat类主要用于将Date日期转换为字符串,或者将某个字符串转换为Date对象,其常见方法如下所示:
方法定义 | 描述 |
---|---|
format | 将一个Date格式转化为日期/时间字符串,此方法继承的父类DateFormat的方法 |
parse | 从给定字符串的开始解析文本,以生成一个日期,此方法为继承的父类DateFormat的方法 |
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDateFormatTest { public static void main(String[] args) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH小时mm分钟ss秒S毫秒"); System.out.println("使用指定格式的日期字符串:"+sdf.format(new Date())); String str="2021年1月15日 06小时44分钟05秒 123毫秒"; Date date = sdf.parse(str); System.out.println("日期对象:"+date); } }
1.2 第二代日期类Calendar
Date类用于返回日期对象,不适合获取日历字段。设置和获取日历字段的方法,被JDK1.1推出的Calendar代替。
java.util.Calendar类是一个抽象类,它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(如获得下星期的日期)提供了一些方法。
序号 | 方法定义 | 描述 |
---|---|---|
1 | static getInstance() | 使用默认时区和语言环境获得一个日历,也可以通过getInstance(TimeZone time,Locale loc)或指定时区和语言环境的日历 |
2 | get(int field) | 获取指定的日历字段 |
3 | set(int year,int month,int date,int hourOfDay,int minute,int second) | 设置字段YEAR、MONTH、DAY_OF_MONTH、HOUR、MINUTE和SECOND的值 |
public class CalendarTest { public static void main(String[] args) { Calendar c = Calendar.getInstance(TimeZone.getTimeZone("Asia/Shanghai"), Locale.CHINA); System.out.println("年:"+c.get(Calendar.YEAR)); System.out.println("月:"+(c.get(Calendar.MONTH)+1));//1月从0开始 System.out.println("日:"+c.get(Calendar.DAY_OF_MONTH)); System.out.println("小时:"+c.get(Calendar.HOUR)); System.out.println("分钟:"+c.get(Calendar.MINUTE)); System.out.println("秒:"+c.get(Calendar.SECOND)); } }
上述代码中的TimeZone表示时区,Locale表示语言环境。例如TimeZone.getTimeZone("Asia/Shanghai")表示“亚洲/上海”时区,Locale.CHINA表示中国语言环境。
1.3 第三代日期类
java8中引入的java.time纠正了过去的缺陷,这就是第三代日期API。
java8吸收了Joda-Time的精华,以一个新的开始为Java创建优秀的API。新的java.time中包含了所有关于本地日期(LocalDate)、本地时间(LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime)和持续时间(Duration)的类。历史悠久的Date类也新增了toInstant()方法,用于把Date类转换成新的表示形式。
接下来只介绍商用的几个类型。
1.3.1 LocalDate、LocalTime、LocalDateTime类
这三个类都代表日期对象,只是包含的日历字段不同,相当于Calendar类的代替。
java.time.LocalDate类:代表一个只包含年、月、日的日期对象,如2007-12-03。LocalDate类常见方法如下所示。
序号 | 方法定义 | 描述 |
---|---|---|
1 | static LocalDate now() | 返回默认时区下的当前日期对象 |
2 | int getYear() | 返回年份,从-999999999-01-01~+999999999-12-31 |
3 | int getMonth() | 返回月份,1-12 |
4 | int getDayOfMonth() | 返回日期,1-31 |
5 | LocalDate parse(CharSequence text) | 按默认格式解析字符串为LocalDate的日期对象 |
6 | LocalDate parse(CharSequence text,DateTimeFormatter formatter) | 按指定格式解析字符串为LocalDate的日期对象 |
java.time.LocalTime类:代表一个只包含小时、分钟、秒的日期对象,如13:45.30.123456789。LocalTime常见方法如下:
序号 | 方法定义 | 描述 |
---|---|---|
1 | static LocalTime now() | 返回默认时区下的当前时间对象 |
2 | int getHour() | 返回小时,0-23 |
3 | int getMinute() | 返回分钟,0-59 |
4 | int getSecond() | 返回秒,0-59 |
5 | LocalTime parse(CharSequence text) | 按默认格式解析字符串为LocalTime的日期对象 |
6 | LocalTime parse(CharSequence text,DateTimeFormatter formatter) | 按指定格式解析字符串为LocalTime的日期对象 |
java.time.LocalDateTime类:代表一个包含年、月、日、小时、分钟、秒的日期对象,如2007-12-03T10:15:30。LocalDateTime常见方法如下:
序号 | 方法定义 | 描述 |
---|---|---|
1 | static LocalDateTime now() | 返回默认时区下的当前日期对象 |
2 | int getYear() | 返回年份,从-999999999-01-01~+999999999-12-31 |
3 | int getMonth() | 返回月份,1-12 |
4 | int getDayOfMonth() | 返回日期:1-31 |
5 | int getHour() | 返回小时:0-23 |
6 | int getMinute() | 返回分钟:0-59 |
7 | int getSecond() | 返回秒:0-59 |
8 | LocalDateTime parse(CharSequence text) | 按默认格式解析字符串为LocalDateTime的日期对象 |
9 | LocalDateTime parse(CharSequence text,DateTimeFormatter formatter) | 按指定格式解析字符串为LocalDateTime的日期对象 |
import java.time.LocalDateTime; public class LocalDateTimeTest { public static void main(String[] args) { //1、创建一个日期对象 LocalDateTime now = LocalDateTime.now(); //2、获取日历字段 System.out.println("年:"+now.getYear()); System.out.println("月:"+now.getMonthValue()); System.out.println("月:"+now.getMonth()); System.out.println("日:"+now.getDayOfMonth()); System.out.println("小时:"+now.getHour()); System.out.println("分钟:"+now.getMinute()); System.out.println("秒:"+now.getSecond()); } }
1.3.2 Instant类
在处理时间和日期时,我们通常会想到年、月、日、时、分、秒。然而,这只是时间的一个模型,是面向人类的。第二种通用模型是面向计算机的,在此模型中,时间线中的一个点表示一个整数,这有利于计算机处理。在UNIX中这个数从1970年开始,以秒为单位;同样在Java中也是从1970年开始的,但以毫秒为单位。
java.time包通过值类型Instant提供机器视图,不提供人类意义上的时间单位。Instant类表示时间线商的一点,不需要要任何上下文信息。例如,时区。从概念上讲,它只是简单地表示自1970年1月1日0时0分0秒(UTC)开始地秒数。因为java.time包是基于纳秒计算的,所以Instant类的精度可以达到纳秒级。
Instant类的常见方法如下:
序号 | 方法定义 | 描述 |
---|---|---|
1 | static Instant now() | 静态方法,返回默认UTC时区的Instant类的对象 |
2 | static Instant ofEpochMillo(long epochMilli) | 静态方法,返回在1970-01-01 00:00:00基础上加上指定毫秒数之后的Instant类的对象 |
3 | static OffsetDateTime atOffset(ZoneOffset offset) | 结合即时的便宜来创建一个OffsetDateTime |
4 | long toEpochMilli() | 返回1970-01-01 00:00:00到当前时间的毫秒数,即时间戳 |
Instant类和第一代日期类Date的相互转换:
import java.time.Instant; import java.util.Date; public class InstantTest { public static void main(String[] args) { //1、创建一个Instant对象 Instant now = Instant.now(); System.out.println("now="+now); //2、转换方法 //[1]Instant->Date Date d = Date.from(now); System.out.println("d="+d); //[2]Date->Instant Instant instant = d.toInstant(); System.out.println("instant="+instant); } }
1.3.3 DateTimeFormatter类
java.time.format.DateTimeFormatter类提供了格式化日期的方法,这个类和第一代日期的SimpleDateFormatter类似,但SimpleDateFormat只能格式化Date类,对Calendar类无效。DateTimeFormatter可以格式化LocalDate、LocalTime、LocalDateTime及Instant类。
DateTimeFormatter类常见方法如下:
序号 | 方法定义 | 描述 |
---|---|---|
1 | static DateTimeFormatter ofPattern(String pattern) | 静态方法,返回一个DateTimeFormatter对象 |
2 | String format(TemporalAccessor t) | 格式化一个日期、时间,返回字符串 |
3 | TemporalAccessor parse(CharSequence text) | 将指定格式的字符序列解析为一个日期、时间 |
TemporalAccessor 是java.time.temporal包下的接口,LocalDate、LocalTime、LocalDateTime、Instant都实现了该接口。
下面以LocalDateTime日期的格式为例,进行代码演示。
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class DateTimeFormatterTest { public static void main(String[] args) { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd a hh小时mm分钟ss秒"); //格式化日期(日期->文本) String format = dtf.format(now); System.out.println(format); //解析字符串为日期(文本->日期) String s="2018-08-08 下午 05小时06分钟43秒"; LocalDateTime parse = LocalDateTime.parse(s, dtf); System.out.println(parse); } }
以上就是一文搞懂Java中的日期类的详细内容,更多关于Java日期类的资料请关注脚本之家其它相关文章!
最新评论