Java学习笔记09(2)-常用类之日期类
一、JDK8之前的日期时间API
JDK8.0之前,日期和时间的API主要有:
java.lang.System类中的public static long currentTimeMillis()方法,用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差(毫秒数),这个毫秒数称为时间戳。java.util.Date和java.sql.Date类。java.sql.Date类是java.util.Date类的子类。java.text.SimpleDateFormatCalendar
1、Date类
Date类有两个,一般使用的是java.util.Date类,java.sql.Date类是数据库中使用的日期类。
java.util.Date类有两个构造器:
Date():创建一个对应当前时间的Date对象。Date(long date):创建指定毫秒数的Date对象。
两个方法(大部分方法都过时了):
toString():显示当前的年、月、日、时、分、秒。默认格式为EEE MMM dd HH:mm:ss zzz yyyy,比如Sat Feb 16 16:35:31 GMT+08:00 2019getTime():获取当前Date对象对应的毫秒数(时间戳)。
java.sql.Date类没有空参的构造器:
Date(long date):创建指定毫秒数的Date对象。Date(int year, int month, int day),已过时。
将java.util.Date对象转换为java.sql.Date对象,具体见代码:
实现代码:
1 | |
2、SimpleDateFormat
java.text.SimpleDateFormat是用来格式化和解析日期的具体类。
格式化:日期—>文本
解析:文本—>日期
格式化:
public SimpleDateFormat():根据默认的模式和语言环境创建对象。public SimpleDateFormat(String pattern):用参数pattern指定的格式创建一个对象。public String format(Date date):SimpleDateFormat类对象调用此方法来格式化Date类对象。
解析:
public Date parse(String source):从给定字符串的开始解析文本,生成一个Date类对象。
代码举例:
1 | |
解析的时候要求字符串必须和格式化时的格式相同(通过构造器参数体现),否则抛异常。
3、Calendar
Date类不能转换时区,除了toGMTString()可以按GMT+0:00输出外,Date总是以当前计算机系统的默认时区为基础进行输出。此外,我们也很难对日期和时间进行加减,计算两个日期相差多少天,计算某个月第一个星期一的日期等。
java.util.Calendar类是一个抽象类,JDK 1.1版本引入,可以用于获取并设置年、月、日、时、分、秒,它和Date比,主要多了一个可以做简单的日期和时间运算的功能。
Calendar类实例化有两种方式:
- a.创建其子类
GregorianCalendar的对象获取实例。 - b.调用其静态方法
getInstance()获取实例。(通过getClass可知,类型还是GregorianCalendar)
Calendar类常用方法:
一个Calendar的实例是系统时间的抽象表示,通过public int get(int field)方法来取得想要的时间信息。参数field是Calendar中的静态变量,比如YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY、MINUTE、SECOND等。
public void set(int field,int value):将给定的字段设置为给定值。public void add(int field,int amount):在给定的字段中添加或减去指定的时间。public final Date getTime():日历类—>Date类public final void setTime(Date date):Date类—>日历类
获取月份时:一月是0,二月是1,以此类推,12月是11
获取星期时:周日是1,周二是2,……周六是7
代码实现:
1 | |
二、JDK8的新日期时间API
1、新日期API
Calendar类和Date类存在的问题:
- 可变性:像日期和时间这样的类应该是不可变的。
- 偏移性:Date中的年份是从1900开始的,而月份都从0开始。
- 格式化:格式化只对Date有用,Calendar则不行。
此外,它们也不是线程安全的;不能处理闰秒等。
JDK 8.0提供了java.time这个API,其包含了所有关于本地日期(LocalDate)、本地时间(LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime)和持续时间(Duration)的类。
JDK 8.0新增了toInstant()方法,用于把Date转换成新的表示形式。这些新增的本地化时间日期API大大简化了日期时间和本地化的管理。
和旧的API相比,新API严格区分了时刻、本地日期、本地时间和带时区的日期时间,并且,对日期和时间进行运算更加方便。
此外,新API修正了旧API不合理的常量设计:
- Month的范围用1~12表示1月到12月;
- Week的范围用1~7表示周一到周日。
最后,新API的类型几乎全部是不变类型(和String类似),可以放心使用不必担心被修改。
新日期API包含:
java.time:包含值对象的基础包。常用java.time.chrono:提供对不同的日历系统的访问。java.time.format:格式化和解析时间和日期。常用java.time.temporal:包括底层框架和扩展特性。java.time.zone:包含时区支持的类。
新日期API和旧日期API的对应关系:
java.util.Date和java.sql.Date对应(类似)InstantSimpleDateFormat对应(类似)DateTimeFormatterCalendar对应(类似)LocalDate、LocalTime、LocalDateTime
2、常用的三个类
其中三个比较重要的类,这三个类的实例是不可变对象:
- LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存储生日、纪念日等日期。
- LocalTime表示一个时间,而不是日期。
- LocalDateTime是用来表示日期和时间的,这是一个最常用的类之一。
这几个类常用的方法如下:
实现代码参考:
1 | |
3、Instant
java.time.Instant用来表示时间戳,它只是简单的表示自1970年1月1日0时0分0秒(UTC)开始的秒数。java.time包是基于纳秒计算的,Instant的精度可以达到纳秒级。
常用方法:
| 方法 | 描述 |
|---|---|
public static Instant now() |
静态方法,返回默认UTC时区的Instant类的对象 |
public static Instant ofEpochMilli(long epochMilli) |
静态方法,返回在1970-01-01 00:00:00基础上加上指定毫秒数之后的Instant类的对象 |
public long toEpochMilli() |
返回1970-01-01 00:00:00到当前时间的毫秒数,即为时间戳 |
public OffsetDateTime atOffset(ZoneOffset offet) |
结合即时的偏移来创建一个OffsetDateTime |
实现代码:
1 | |
4、DateTimeFormatter
使用Date对象时,用SimpleDateFormat进行格式化显示。使用新的LocalDateTime或ZonedLocalDateTime时,使用java.time.format.DateTimeFormatter进行格式化显示。
和SimpleDateFormat不同的是,DateTimeFormatter是不变对象,并且是线程安全的。因为SimpleDateFormat不是线程安全的,使用的时候,只能在方法内部创建新的局部变量。而DateTimeFormatter可以只创建一个实例,到处引用。
DateTimeFormatter类有三种格式化方法:
- 预定义的标准格式。如:
ISO_LOCAL_DATE_TIME、ISO_LOCAL_DATE、ISO_LOCAL_TIME - 本地化相关的格式。如:
ofLocalizedDateTime(FormatStyle.LONG) - 自定义的格式。如:
ofPattern(“yyyy-MM-ddhh:mm:ss”),常用
同样地,DateTimeFormatter类也提供了相应的格式化和解析的函数:
| 方法 | 描述 |
|---|---|
public static DateTimeFormatter ofPattern(String pattern) |
静态方法,返回一个指定字符串格式的DateTimeFormatter |
public String format(Temporal Accessort) |
格式化一个日期、时间,返回字符串 |
public TemporalAccessor parse(CharSequence text) |
将指定格式的字符序列解析为一个日期、时间 |
代码使用:
1 | |
5、其他API
ZoneId:该类中包含了所有的时区信息,一个时区的ID,如Europe/Paris- ZonedDateTime`:一个在ISO-8601日历系统时区的日期时间,如2007-12-03T10:15:30+01:00Europe/Paris。其中每个时区都对应着ID,地区ID都为“{区域}/{城市}”的格式,例如:Asia/Shanghai等
Clock:使用时区提供对当前即时、日期和时间的访问的时钟。- 持续时间:
Duration,用于计算两个“时间”间隔 - 日期间隔:
Period,用于计算两个“日期”间隔 TemporalAdjuster:时间校正器。有时我们可能需要获取例如:将日期调整到“下一个工作日”等操作。TemporalAdjusters:该类通过静态方法(firstDayOfXxx()/lastDayOfXxx()/nextXxx())提供了大量的常用TemporalAdjuster的实现。
6、新旧日期转换
- 本文作者:Kangshitao
- 本文链接:http://kangshitao.github.io/2021/04/04/java-note-0902/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!