java常用时间日期类总结

发布时间 2023-11-23 18:03:04作者: legolas-PRC

前置知识:

UTC时间(Coordinated Universal Time):协调世界时,主要的世界时间标准,0时区的时间

UTC+8:东八区时间

Epoch(纪元):1970-01-01 00:00:00 UTC(北京时间1970-01-01 00:08:00 UTC+8)

 

常用类

描述

 

System.currentTimeMillis()

返回Epoch至今的毫秒数

 

java.util.Date

表示一个时刻,记录Epoch到该时刻的UTC时间相差的毫秒数(其中多数方法已废弃)

 

java.util.Calendar

抽象类,提供了以年,月,日,时分秒,星期等为单位操作的方法

 

java.text.SimpleDateFormat

将时间格式化为字符串,将字符串解析为时间

 

java.util.TimeZone

时区

 

java.time.Instant

表示时刻,精确到nanos,提供了计算的方法

jdk8

java.time.LocalDate

没有时区信息的时间/日期/时间日期

并不能表示某个时刻

java.time.LocalTime

java.time.LocalDateTime

java.time.ZonedDateTime

有时区的时间日期

java.time.format.DateTimeFormatter

时间格式化

java.time.Duration

一段时间,基于秒和纳秒,例如:32秒

java.time.Period

一段时间,基于日历单位,精确到天,例如:2年,3天,5个月

java.time.ZoneId/ZoneOffset

时区

image.jpeg

1.JDK8时间API:

基本都是不可变类

image.jpeg

image.jpeg

1.时间表示

Date类:

记录该对象表示的时刻的UTC时间到Epoch的毫秒数

不受时区影响,无论在哪个时区,同一时刻的UTC时间是相同的,保存的毫秒数也相同

关于时区问题

1.同一个Date对象在不同时区格式化输出的时间字符串不同,但是表示的是同一个时刻

public static void main(String[] args) throws ParseException {
        String dataStr = "2023-11-17 11:26:18";
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 同一个Date对象,表示北京时间2023-11-17 11:26:18这个时刻
        Date date1 = dateFormat.parse(dataStr);
        
        // 东八区这个时刻的时间
        System.out.println(date1+"-->"+date1.getTime());
        // Fri Nov 17 11:26:18 CST 2023-->1700191578000

        // 西八区这个时刻的时间
        TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
        System.out.println(date1+"-->"+date1.getTime());
        // Thu Nov 16 19:26:18 PST 2023-->1700191578000
    }

2.同一个时间字符串在在不同的时区表示不同时刻,解析出的Date对象不同,表示的时间不同

public static void main(String[] args) throws ParseException {
        String dataStr = "2023-11-17 11:26:18";
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  
        // 东八区的2023-11-17 11:26:18
        Date date1 = dateFormat.parse(dataStr);
        System.out.println(date1+"-->"+date1.getTime());
        // Fri Nov 17 11:26:18 CST 2023-->1700191578000

        // 西八区的2023-11-17 11:26:18
        dateFormat.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
        Date date2 = dateFormat.parse(dataStr);
        System.out.println(date2+"-->"+date2.getTime());
        // Sat Nov 18 03:26:18 CST 2023-->1700249178000
    }

Instant类:

一个long记录到epoch的秒数,一个int记录纳秒数

其他类是按不同单位存储时间,如LocalDate类中是year,month,day三个字段


2.时间操作

jdk8提供的时间类都有比较完善的时间操作的方法,大概是这几种,不同的类有针对不同单位的一些扩展,以LocalDateTime为例:

说明

方法

举例

静态工厂方法,构建对象

LocalDateTime.now()

LocalDateTime.of()

LocalDateTime.ofxxx()

Instant now=Instant.now();
LocalDateTime datetime = LocalDateTime.now();
LocalDateTime datetime1 = LocalDateTime.of(2023, 10, 21, 11, 6);
LocalDateTime datetime2 = LocalDateTime.ofInstant(now, ZoneId.of("CTT"));
LocalDateTime datetime3 = LocalDateTime.ofEpochSecond(now.getEpochSecond(),now.getNano(), zoneOffset);

时间加减操作

支持不同单位

localDateTime.plus()

localDateTime.plusSecond()

localDateTime.plusxxx()

LocalDateTime datetime7 = datetime.plusSeconds(3);
LocalDateTime datetime8 = datetime.plus(1000, ChronoUnit.MINUTES);

获取该时间的某个单位上的值

年份,月份,年的第几天,周几等

localDateTime.getDayOfWeek()

localDateTime.getDayOfxxx()

localDateTime.getMonth()

localDateTime.getxxx()

DayOfWeek dayOfWeek = datetime.getDayOfWeek();
int dayOfMonth = datetime.getDayOfMonth();
int dayOfYear = datetime.getDayOfYear();
Month month = datetime.getMonth();
int monthValue = datetime.getMonthValue();
int year = datetime.getYear();

修改

支持不同单位级别上的修改

 

localDateTime.with()

localDateTime.withNano()

localDateTime.withxxx()

datetime.with(ChronoField.SECOND_OF_DAY,1000);
LocalDateTime datetime4 = datetime.withNano(100);
LocalDateTime datetime5 = datetime.withYear(1990);
LocalDateTime datetime6 = datetime.withDayOfYear(99);

计算到另一个时间的按照某单位的差值

localDateTime.util(Temporal endExclusive, TemporalUnit unit)

 

格式化和解析

localDateTime.format()

LocalDateTime.parse()

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = datetime.format(dateTimeFormatter);
LocalDateTime parsed = LocalDateTime.parse("2019-01-07 23:49:08");

 

Calendar类:

说明

方法

示例

实例化,取当前时间

Calendar.getInstance()

 

赋值

calendar.set(int field,int value)

calendar.setTime(Date date)

calendar.setTimeZone(TimeZone value)

 

获取某个单位上的值

还提供了一些获取某些特殊值的能力,如某单位的最大最小值,某单位的String值等

calendar.get(int field)

calendar.getxxx()

int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1;
int day = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
System.out.println(year + "年" + month + "月" + day + "日" + hour + "时" + minute + "分" + second + "秒");
// 2023年11月23日14时25分20秒

int maxDayOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
System.out.println(maxDayOfMonth);// 30

加减操作

add方法会在高位进位

calendar.add(int field,int amount)

calendar.add(Calendar.MONTH,3);

 

3.时间格式化

SimpleDateFormat

线程不安全

字符串解析过于宽容,容易出错

// 1.预定义的
DateFormat dateTimeInstance = SimpleDateFormat.getDateTimeInstance();
System.out.println(dateTimeInstance.format(new Date()));// 2023-11-22 15:02:00
// 2.自定义格式的
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(dateFormat.format(new Date()));// 2023-11-22 15:02:00

Date parsed = dateFormat.parse("2023-11-22 15:06:01", new ParsePosition(0));

DateTimeFormatter

线程安全

提供了一些预定义的Formtter

// 1.根据格式解析
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 2.DateTimeFormatterBuilder来构造
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .appendValue(ChronoField.YEAR)
                .appendLiteral("/")
                .appendValue(ChronoField.MONTH_OF_YEAR)
                .appendLiteral("/")
                .appendValue(ChronoField.DAY_OF_MONTH)
                .appendLiteral(" ")
                .appendValue(ChronoField.HOUR_OF_DAY)
                .appendLiteral(":")
                .appendValue(ChronoField.MINUTE_OF_HOUR)
                .appendLiteral(":")
                .appendValue(ChronoField.SECOND_OF_MINUTE)
                .appendLiteral(".")
                .appendValue(ChronoField.MILLI_OF_SECOND)
                .toFormatter();
// 3.用预定义的格式
DateTimeFormatter isoLocalDateTime = DateTimeFormatter.ISO_LOCAL_DATE_TIME;// '2011-12-03T10:15:30'
// 4.用本地化的一些风格
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
System.out.println(dateTimeFormatter.format(LocalDateTime.now()));// 2023年11月22日 星期三

TemporalAccessor parse = dateTimeFormatter.parse("2023年11月22日 星期三");
LocalDate ldt = LocalDate.from(parse);
System.out.println(ldt);// 2023-11-22

4.时间段

image.jpeg

Period

通过年月日来对一段时间建模

Duration

通过秒和纳秒来对一段时间建模

5.时间单位

image.jpeg

TemporaUnit

A unit of date-time, such as Days or Hours.

TemporaFeild

A field of date-time, such as month-of-year or hour-of-minute.

两者都提供了枚举实现

6.时区

image.jpeg

ZoneId

一个表示时区的ID

ZoneOffset

表示时区和标准时间的差值