JDK 8之前
java.lang.System静态方法
System
类提供的public static long currentTimeMillis()
,用于返回当前时间与1970年1月1日0时0分0秒的时间差,以毫秒为单位。
计算世界时间的主要标准有:
- UTC: Coordinated Universal Time
- GMT: Greenwich Mean Time
- CST: Central Standard Time
java.util.Date类
表示特定的瞬间,精确到毫秒
- 构造器
Date()
获取本地当前时间的Date对象Date(long date)
创建指定毫秒数的Date对象
- 常用方法
long getTime()
返回自1970年1月1日0时0分0秒 GMT 以来此Date对象表示的毫秒数,即时间戳String toString()
把此对象转换为以下形式的String:dow(一周中的某一天) mon dd hh:mm:ss zzz(时间标准) yyyy
注意:很多方法已被废弃,因为不易于国际化
//构造器一:Date():创建一个对应当前时间的Date对象
Date date1 = new Date();
System.out.println(date1.toString()); // Mon Jul 05 12:34:45 CST 2021
System.out.println(date1.getTime()); //1625459685618
//构造器二:创建指定毫秒数的Date对象
Date date2 = new Date(1625459685618L);
System.out.println(date2.toString());
java.util.Calendar类
Calendar
是一个抽象基类,主要用于完成日期字段之间相互操作的功能。
获取Calendar
实例的方法:
- 调用
Calendar.getInstance()
- 调用子类
GregorianCalendar
构造器
一个Calendar
的实例是系统时间的抽象表示,通过get(int field)
方法来取得想要的时间信息,e.g.YEAR/MONTH/DAY_OF_WEEK/HOUR_OF_DAY/MINUTE/SECOND
void set(int field, int value)
void add(int field, int amount)
final Date getTime()
final void setTime(Date date)
注意:
- 获取月份时,范围是0-11
- 获取星期时,以西方为准,即1是周日,7是周六
//1.实例化
//方式一:创建其子类(GregorianCalendar)的对象
//方式二:调用其静态方法getInstance()
Calendar calendar = Calendar.getInstance();
// System.out.println(calendar.getClass());
//2.常用方法
//get()
int days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));
//set()
//calendar可变性
calendar.set(Calendar.DAY_OF_MONTH,22);
days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days); // 22
//add()
calendar.add(Calendar.DAY_OF_MONTH,-3); // 往前数3天
days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days); // 19
//getTime():日历类---> Date
Date date = calendar.getTime();
System.out.println(date);
//setTime():Date ---> 日历类
Date date1 = new Date();
calendar.setTime(date1);
days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
java.text.SimpleDateFormat类
该类是一个不与语言环境有关的方式来格式化和解析日期的具体类。
它允许进行:
-
格式化:Date => String
SimpleDateFormat()
默认的模式和语言环境创建对象SimpleDateFormat(String pattern)
以pattern指定的格式创建对象- 通过
SimpleDateFormat
的实例调用方法String format(Date date)
格式化时间对象date
//实例化SimpleDateFormat:使用默认的构造器 SimpleDateFormat sdf = new SimpleDateFormat(); //格式化:日期 --->字符串 Date date = new Date(); System.out.println(date); String format = sdf.format(date); System.out.println(format); //按照指定的方式格式化:调用带参的构造器 SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); //格式化 String format1 = sdf1.format(date); System.out.println(format1);//2021-07-05 10:33:45
-
解析:String => Date
Date parse(String source)
将给定字符串进行解析,生成一个日期对象
//解析:格式化的逆过程,字符串 ---> 日期 String str = "21-07-05 上午11:43"; Date date1 = sdf.parse(str); System.out.println(date1); //解析:要求字符串必须是符合SimpleDateFormat识别的格式(通过构造器参数体现), //否则,抛异常 Date date2 = sdf1.parse("2021-07-05 10:33:45"); System.out.println(date2);
识别格式
JDK 8中新的API
JDK 8之前的API面临的问题:
- 可变性:时间和日期这种类应该是不可变的
- 偏移性:Date中的年份是从1900开始,而月份都从0开始
- 格式化:只对Date有用,对Calendar无效
- 非线程安全
- 不能处理闰年
在JDK 8中吸收Joda-Time
的精华,引入java.time
系列API纠正了过去的缺陷,包括:
java.time
包含值对象的基础包java.time.chrono
提供对不同的日历系统的访问java.time.format
格式化和解析时间、日期java.time.temporal
包括底层框架和扩展特性java.time.zone
包含时区支持的类
常用的包就是基础包和format包。
常用的类包括:
- 本地日期
LocalDate
- 本地时间
LocalTime
- 本地日期时间
LocalDateTime
- 时区
ZonedDateTime
- 持续时间
Duration
此外,Date
类中新增了toInstant()
方法,用于把Date
转换成新的表示形式。
LocalDate、LocalTime、LocalDateTime
这三个类的实例是不可变的对象,分别表示使用ISO-8601日历系统的日期、时间、日期时间,不包含当前的时间信息,也不包含与时区相关的信息。
ISO-8601日历系统是ISO指定的线代公民的日期和时间的表示法,即公历。
LocalDate
代表ISO格式(yyyy-MM-dd)的日期,可以存储生日、纪念日等日期LocalTime
表示一个时间LocalDateTime
表示日期+时间,最常用
常用方法
/*
LocalDate、LocalTime、LocalDateTime 的使用
说明:
1.LocalDateTime相较于LocalDate、LocalTime,使用频率要高
2.类似于Calendar
*/
@Test
public void test1(){
//now():获取当前的日期、时间、日期+时间
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDate);
System.out.println(localTime);
System.out.println(localDateTime);
//of():设置指定的年、月、日、时、分、秒。没有偏移量
LocalDateTime localDateTime1 = LocalDateTime.of(2021, 7, 6, 13, 23, 43);
System.out.println(localDateTime1);
//getXxx():获取相关的属性
System.out.println(localDateTime.getDayOfMonth());
System.out.println(localDateTime.getDayOfWeek());
System.out.println(localDateTime.getMonth());
System.out.println(localDateTime.getMonthValue());
System.out.println(localDateTime.getMinute());
//体现不可变性,改变属性不改变原有对象,会生成新对象
//withXxx():设置相关的属性
LocalDate localDate1 = localDate.withDayOfMonth(22);
System.out.println(localDate);
System.out.println(localDate1);
LocalDateTime localDateTime2 = localDateTime.withHour(4);
System.out.println(localDateTime);
System.out.println(localDateTime2);
//不可变性
LocalDateTime localDateTime3 = localDateTime.plusMonths(3);
System.out.println(localDateTime);
System.out.println(localDateTime3);
LocalDateTime localDateTime4 = localDateTime.minusDays(6);
System.out.println(localDateTime);
System.out.println(localDateTime4);
}
Instant
时间线上的一个瞬时点,可能被用来记录应用程序中的事件时间戳。
java.time
包通过值类型Instant
提供机器视图,不提供处理人类意义上的时间单位,表示时间线上的一个点,不需要任何上下文信息,精度可以达到纳秒级别。
时间戳是指格林威治时间1970年01月01号0时0分0秒(北京时间1970年01月01号8时0分0秒)起到当前时间的总秒数。(或以毫秒为单位)
1 ns = 10^-9 s
常用方法
/*
Instant的使用
类似于 java.util.Date类
*/
@Test
public void test2(){
//now():获取本初子午线对应的标准时间
Instant instant = Instant.now();
System.out.println("instant = " + instant); // 2021-07-06T06:23:32.658Z
//添加时间的偏移量
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
System.out.println("offsetDateTime = " + offsetDateTime); // 2021-07-06T14:26:39.995+08:00
//toEpochMilli():获取自1970年1月1日0时0分0秒(UTC)开始的毫秒数 ---> Date类的getTime()
long milli = instant.toEpochMilli();
System.out.println("milli = " + milli); // 1625552799995
//ofEpochMilli():通过给定的毫秒数,获取Instant实例 -->Date(long millis)
Instant instant1 = Instant.ofEpochMilli(1625552799995L);
System.out.println("instant1 = " + instant1); // 2021-07-06T06:26:39.995Z
}
DateTimeFormatter
java.time.format.DateTimeFormatter
类提供了3种格式化方法,用于格式化与解析日期或时间:
- 预定义的标准格式:
ISO_LOCAL_DATE_TIME
、ISO_LOCAL_DATE
、ISO_LOCAL_TIME
- 本地化相关的格式:
ofLocalizedDateTime(FormatStyle.LONG)
FormatStyle.FULL / FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT
适用于LocalDateFormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT
适用于LocalDateTime
- 自定义的格式(使用最多):
ofPattern("yyyy-MM-dd HH:mm:ss")
常用方法
/*
DateTimeFormatter:格式化或解析日期、时间
类似于SimpleDateFormat
*/
@Test
public void test3(){
// 方式一:预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
// 格式化:日期-->字符串
LocalDateTime localDateTime = LocalDateTime.now();
String str1 = formatter.format(localDateTime);
System.out.println("localDateTime = " + localDateTime); // 2021-07-06T14:37:18.147
System.out.println("str1 = " + str1); // 2021-07-06T14:37:18.147
// 解析:字符串 -->日期
TemporalAccessor parse = formatter.parse("2021-07-06T14:36:22.294");
System.out.println("parse = " + parse); // {},ISO resolved to 2021-07-06T14:36:22.294
// 方式二:
// 本地化相关的格式。如:ofLocalizedDateTime()
// FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT :适用于LocalDateTime
DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
// 格式化
String str2 = formatter1.format(localDateTime);
// LONG:2021年7月6日 下午02时37分18秒
// MEDIUM:2021-7-6 14:57:05
// SHORT:21-7-6 下午2:57
System.out.println("str2 = " + str2);
// 本地化相关的格式。如:ofLocalizedDate()
// FormatStyle.FULL / FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT : 适用于LocalDate
DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
// 格式化
String str3 = formatter2.format(LocalDate.now());
// FULL:2021年7月6日 星期二
// LONG:2021年7月6日
// MEDIUM:2021-7-6
// SHORT:21-7-6
System.out.println("str3 = " + str3);
// 重点: 方式三:自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 格式化
String str4 = formatter3.format(LocalDateTime.now());
System.out.println("str4 = " + str4); // 2021-07-06 14:37:18
// 解析
TemporalAccessor accessor = formatter3.parse("2021-07-06 14:36:22");
System.out.println("accessor = " + accessor); // {},ISO resolved to 2021-07-06T14:36:22
}
其他类
-
ZoneId
包含了所有的时区信息,一个时区的ID,格式为{区域}/{城市}
,e.g.Asia/Shanghai
ZoneId.getAvailableZoneIds()
获取所有的时区IDZoneId.of("xx/xxx")
获取指定时区的时间
-
ZonedDateTime
一个在ISON-8601日历系统时区的日期时间,e.g.2021-07-06T15:04:30+08:00 Asia/Shanghai
ZonedDateTime.now()
获取本时区的ZonedDateTime
对象ZonedDateTime.now(ZoneId.of("xx/xxx"))
获取指定时区的ZonedDateTime
对象
-
Clock
使用时区提供对当前即时、日期和时间访问的时钟 -
Duration
持续时间,用于计算两个时间的间隔static Duration between(LocalTime1/LocalDateTime1, LocalTime2/LocalDateTime2)
返回一个Duration
对象,表示两个时间的间隔,可以通过getSeconds()/getNano()/toDays()
来获取时间间隔
-
Period
日期间隔,用于计算两个日期的间隔,以年月日衡量static Period between(LocalDate1, LocalDate2)
,返回一个Period
对象,通过getYears()/getMonths()/getDays()
来获取日期间隔
-
TemporalAdjuster
时间校正器// e.g. 获取当前日期的下一个周日是哪一天 TemporalAdjuster ta = TemporalAdjusters.next(DayOfWeek.SUNDAY); LocalDateTime ldt = LocalDateTime.now().with(ta); // e.g. 获取下一个工作日是哪一天 LocalDate ld = LocalDate.now().with(new TemporalAdjuster() { @Override public Temporal adjustInto(Temporal t) { LocalDate date = (LocalDate) t; if (date.getDayOfWeek().equals(DayOfWeek.FRIDAY)) { return date.plusDays(3); } else if (date.getDayOfWeek().equals(DayOfWeek.SATURDAY)) { return date.plusDays(2); } else { return date.plusDays(1); } } });
-
TemporalAdjusters
该类通过静态方法(firstDayOfXXX()/lastDayOfXXX()/nextXXX()
)提供了大量的常用TemporalAdjuster
的实现