Java时间类
日期在开发过程中使用的频率比较高的,使用日期类的API可以更快速更方便的来解决问题。
日期类中分为2类,一类是jdk8以前的类和jdk8后来的类。
jdk8以前的类使用起来有着很多的问题,使用起来也非常的不方便,像那些月份从0开始、需要加上1900等等问题,让人用起来非常的麻烦。所以一般还是不用了,学习的重点也在后面的类上。
jdk8以前:
Date 时间
SimpleDateFormat 格式化时间
Calendar 日历
jdk8以后
Date类
ZoneId 时区
Instant 时间戳
ZoneDateTime 带有时区的时间
格式化类
DateTimeFormatter
日历类
LocalDate 年月日
LocalTime 时分秒
LocalDateTime 年月日时分秒
工具类
Duration 时间间隔(秒、纳秒)
Period 时间间隔(年月日)
ChronoUnit 时间间隔(所有单位)
JDK8以后类的优势:
代码简单
多线程下更加安全,对象都是不可变的
格式化时间的格式见最后附录
用的比较多的是日期类和工具类
Date类
用来描述时间,精确到毫秒值。
date类中有着很多和毫秒、年、月、日、小时等等的方法,其中毫秒是类中所书写的,年月日这样的类CalendarDate这样的帮助类来实现的。
其有着构造方法,get/set来处理
构造方法
毫秒值构造
有参构造:参数为毫秒值。
无参构造:调用系统的System.currentTimeMillis()获取当前值,在用有参构造来赋值。
日期构造
需要注意的是:
可以看到输入的年需要减去1900
输入的月份是从0开始范围是0-11所以说非常不符合人的常识。
get和set方法比较好理解,就是获取值和设置值。
然后重写的tostring格式是像这样的
Tue Jan 01 00:00:00 CST 1900看着也不是很舒服。
也没有什么其他的方便的方法(如对比2个时间的前后),所以一般就不使用date类了。
类的转换
//转Instant
// 底层调用Instant.ofofEpochMilli方法
public Instant toInstant()
// instant转date
public static Date from(Instant instant)
SimpleDateFormat
作用:
格式化:把时间变成我们喜欢的格式输出
解析:把字符串解析成date
构造方法:
空参:使用默认格式
字符串参数:使用指定格式
常用方法:
String format(Date) 日期->String
Date parse(String) String->日期
Calendar
日历类,方便获取和修改年月日等等。
Calendar是一个抽象类,构造方法都被私有化了,不能直接获取对象。
构造方法
public static Calendar getInstance()
可以使用getInstance方法来获取其对象
常用方法
//Date转换
Date getTime();
void setTime(Date);
//设置和获取毫秒值
long getTimeInMillis()
void setTimeInMillis(long)
//字段的设置和获取
int get(int field)
void set(int field,int value)
//某个字段的修改 amount为负数时候减少
void add(int field,int amount)
field的值使用Calendar里面的常量就行。
和Date一样:
年:从1900开始
月份:是从0开始的
星期:从星期日开始 2代表星期一
JDK8以后
ZoneId时区
格式
洲名/城市名
国家名/城市名
注意:
没有北京的,有Asia/Shanghai、Asia/Taibei、Asia/Chongqing
方法:
static Set<String> getAvailableZoneIds()获取java支持的时区
static ZoneId systemDefault() 获取系统默认时区
static ZoneId of(String zone) 获取指定时区
Instant
时间戳的介绍
时间戳:一个能表示一份数据在某个特定时间之前已经存在的、 完整的、 可验证的数据,通常是一个字符序列,唯一地标识某一刻的时间。
作用:
一般啊,在互联网公司都会在项目种使用时间戳,时间戳主要用于清理缓存,大多数用于版本更新;
instant粗略理解
他是处理时间戳相关的,但是不能直接处理年月日
代表的是某个时间(有点像 java.util.Date)
它是精确到纳秒的(而不是象旧版本的Date精确到毫秒)。
如果使用纳秒去表示一个时间则原来使用一位Long类型是不够的
需要占用更多一点的存储空间
实际上其内部是由1个long和1个int组成的
第一个部分保存的是自标准Java计算时代(就是1970年1月1日开始)到现在的秒数
第二部分保存的是纳秒数
秒字段中的纳秒数
稍后沿时间线显示
这始终是正数,并且从不超过999999999
可以对时间进行比较,
方法:
static Instant now()//获取当前时间戳(标准时间)
static Instant ofXXX()//根据(秒/毫秒/纳秒)获取instant Xxx可以是 EpochSecond /EpochMilli毫秒
ZoneDateTime atZone(ZoneId)//指定时区
boolean isXXX(Instant)//判断是否是 Xxx 可以是after/before
Instant minusXxx(long)//减少
Instant plusXxx(long)//加
//Xxx是秒/毫秒/纳秒
类的转换
//转ZonedDateTime
public ZonedDateTime atZone(ZoneId zone)
ZonedDateTime
带时区的时间,包括年月日等等的
其底层包括LocalDateTime、ZoneOffset、ZoneId来记录
所以其是非常强大的一个类,
方法
int getXXX()//如获取小时分钟等等
static ZonedDateTime now()//获取当前时间,带时区的
static ZonedDateTime ofXxx(Xxx)//获取指定
ZonedDateTime withXxx()//修改时间,XX为需要修改的字段
ZonedDateTime minusXxx()//减少时间
ZonedDateTime plusXxx()//添加时间
类的转换
//转LocalDateTime
public LocalDateTime toLocalDateTime()
//转LocalDate
public LocalDate toLocalDate()
//LocalTime
public LocalTime toLocalTime()
DateTimeFormatter
方法
static DateTimeFormatter ofPattern(格式)
String format(对象)
日期类(最好用,也用的最多)
LocalDate
LocalTime
LocalDateTime
方法
static XXX now()//当前的
static XXX of()//获取指定时间的对象
get开头的//获取字段
isBefore/After//判断
with开头的//修改
minus开头的//减少
plus开头的//添加
LocalDateTime还可以通过toLocalDate/LocalTime转换
LocalDate只能对年月日进行操作
LocalTime只能对时分秒纳秒等等操作
LocalDateTime可以对年月日时分秒进行操作
工具类(时间间隔对象,用的较多)
Duration 时分秒
Period 年月日
ChronoUnit 所有单位
ChronoUnit,这个相当于对单位来进行工具,先获取单位的工具类,然后在调用方法
类挺多的,不过方法有很多通用的表达,相对而言都还是能够见名知意
如
between()第二个减去第一个,返回的还是对应时间间隔对象
Duration.between(time1, time2);
ChronoUnit.字段.between
案例:
1.2个日期中的天数
public long daysBetweenDates(String date1, String date2) {
LocalDate p1 = LocalDate.parse(date1);
LocalDate p2 = LocalDate.parse(date2);
return Math.abs(ChronoUnit.DAYS.between(p1,p2));
}
Duration
静态构造
of开头
to获取对应字段的值
get相关,获取对应的值
plus添加时间
minus减少
divied除以
常见类的转换
附录
格式时间
常用 yyyy-MM-dd HH:mm:ss 年-月-日 时-分-秒
G Era 标志符 Text AD
y 年 Year 1996; 96
M 年中的月份 Month July; Jul; 07
w 年中的周数 Number 27
W 月份中的周数 Number 2
D 年中的天数 Number 189
d 月份中的天数 Number 10
F 月份中的星期 Number 2
E 星期中的天数 Text Tuesday; Tue
a Am/pm 标记 Text PM
H 一天中的小时数(0-23) Number 0
k 一天中的小时数(1-24) Number 24
K am/pm 中的小时数(0-11) Number 0
h am/pm 中的小时数(1-12) Number 12
m 小时中的分钟数 Number 30
s 分钟中的秒数 Number 55
S 毫秒数 Number 978
z 时区 General time zone Pacific Standard Time; PST; GMT-08:00
Z 时区 RFC 822 time zone -0800
实例
蓝桥杯–星期一
整个2020 世纪(1901年1月1日至 2000 年12月31日之间)一共有多少个星期一?
import java.util.Scanner;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//在此输入您的代码...
LocalDate l1 = LocalDate.of(1901,1,1);
LocalDate l2 = LocalDate.of(2000,12,31);
long between = ChronoUnit.DAYS.between(l1, l2);
System.out.println(between/7);
sc.close();
}
}