java8 日期、时间处理类

发布时间 2023-07-04 14:35:26作者: EPIHPANY

一、LocalDate类

  1. 创建LocalDate
方法 说明
static LocalDate now() 获取默认时区的当前日期,默认返回格式yyyy-MM-dd
static LocalDate now(Clock clock) 从指定时钟获取当前日期
static LocalDate now(ZoneId zone) 获取指定时区的当前日期
static LocalDate of(int year, int month, int dayOfMonth) 根据指定的年、月、日获取LocalDate 实例
static LocalDate of(int year, Month month, int dayOfMonth) 根据指定的年、月、日获取LocalDate 实例(与上一个方法的第二个参数有区别)
static LocalDate ofYearDay(int year,int dayOfYear) 根据指定的年(year),获取年中的第dayOfYear天LocalDate实例
static LocalDate ofEpochDay(long epochDay) 获取从1970-01-01开始往后epochDay天数的LocalDate实例
static LocalDate parse(CharSequence text) 将字符串转换为LocalDate,字符串的格式必须为yyyy-MM-dd,否则会报错
static LocalDate parse(CharSequence text, DateTimeFormatter formatter) 根据指定的日期字符串text、指定的日期字符串格式formatter获取LocalDate实例,text格式要与formatter指定的格式一致,LocalDate实例的日期格式还是yyyy-MM-dd
  • 时区

    全球一共有24个时区,英国格林尼治是0时区,北京是东八区,也就是说格林尼治凌晨1点,北京是早上9点。0时区的时间也称为GMT+0时间,GMT是格林尼治标准时间,北京的时间就是GMT+8:00。

  • 时刻和纪元时

    所有计算机系统内部都用一个整数表示时刻,这个整数是距离格林尼治标准时间1970年1月1日0时0分0秒的毫秒数。格林尼治标准时间1970年1月1日0时0分0秒也被称为EpochTime(纪元时)。这个整数表示的是一个时刻,与时区无关,世界各地都是同一个时刻,但对这个时刻的解读(如年月日时分秒)可能是不一样的。对于1970年以前的时间,使用负数表示。

  • UTC、GMT、CST

    UTC(Coordinated Universal Time):协调世界时间,又称世界统一时间、世界标准时间。UTC是现在全球通用的时间标准。由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。
    GMT(Greenwich Mean Time):格林威治时间。它规定太阳每天经过位于英国伦敦郊区的皇家格林威治天文台子午仪中心的一条经线的时间为中午12点。
    CST:即China Standard Time,表示中国标准时间(或者说北京时间)。GMT是前世界标准时,UTC是现世界标准时。UTC 比 GMT更精准,以原子时计时,适应现代社会的精确计时。
    GMT是前世界标准时,UTC是现世界标准时。UTC 比 GMT更精准,以原子时计时,适应现代社会的精确计时。但在不需要精确到秒的情况下(一般每年UTC和GMT时间相差不会超过1秒),二者可以视为等同。

package com.link.test;

import java.time.Clock;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

public class DateTest {
    public static void main(String[] args) {

        print(LocalDate.now()); // 输出 2023-05-18

        print(LocalDate.now(Clock.systemDefaultZone())); // 输出 2023-05-18

        // 北京时间
        print(LocalDate.now(ZoneId.of(ZoneId.SHORT_IDS.get("CTT")))); // 输出 2023-05-18

        print(LocalDate.now(ZoneId.of("UTC")));

        print(LocalDate.now(ZoneId.of("UTC+15")));

        print(LocalDate.of(2023,5,17)); // 2023-05-17

        print(LocalDate.ofEpochDay(1)); // 1970-01-02

        print(LocalDate.ofYearDay(2023,1)); // 2023-01-01

        print(LocalDate.parse("2023-05-17")); // 2023-05-17 月份必须为MM格式

        print(LocalDate.parse("20230517", DateTimeFormatter.ofPattern("yyyyMMdd"))); // 2023-05-17

        print(LocalDate.parse("2023-05-17", DateTimeFormatter.ofPattern("yyyy-MM-dd"))); // 2023-05-17

    }

    private static void print(Object o) {
        System.out.println(o);
    }
    
}

  1. LocalDate日期计算
方法 说明
LocalDate plus(long amountToAdd, TemporalUnit unit) 通用方法,可以通过unit参数控制增加天、周、月、年
LocalDate plus(TemporalAmount amountToAdd) 根据给定的参数对象amountToAdd增加天、周、月、年,TemporalAmount是一个接口,实现类可用Period、Duration
LocalDate plusDays(long daysToAdd) 返回增加了daysToAdd天的LocalDate副本
LocalDate plusWeeks(long weeksToAdd)
LocalDate plusMonths(long monthsToAdd)
LocalDate plusYears(long yearsToAdd)
LocalDate minus(long amountToSubtract, TemporalUnit unit) 通用方法,可以通过unit参数控制减少天、周、月、年
package com.link.test;

import java.time.LocalDate;
import java.time.Period;
import java.time.temporal.ChronoUnit;

public class DateCalTest {
    public static void main(String[] args) {
        print(LocalDate.now()); // 2023-05-21
        print(LocalDate.now().plus(1, ChronoUnit.DAYS)); // 2023-05-22
        print(LocalDate.now().plus(-1, ChronoUnit.DAYS)); // 2023-05-20
        print(LocalDate.now().minus(Period.of(1,1,1))); // 2022-04-20
        
    }


    private static void print(Object o) {
        System.out.println(o);
    }
}

  1. 获取年、月、日
方法 说明
int getYear() 获取年份
Month getMonth() 获取月份(返回值JANUARY、FEBRUARY、MARCH...见枚举类Month)
int getMonthValue() 获取月份(返回值1-12)
int getDayOfMonth() 获取日期在该月是第几天
DayOfWeek getDayOfWeek() 获取日期是星期几(返回值MONDAY、TUESDAY...见枚举类DayOfWeek,方法getValue可获取数字星期几(1-7))
int lengthOfYear() 返回日期所在年份共有几天
long toEpochDay() 返回当前日期距离1970年1月1日的天数
package com.link.test;

import java.time.LocalDate;
import java.time.temporal.ChronoField;

public class LocalDateFieldTest {
    public static void main(String[] args) {
        LocalDate now = LocalDate.now();
        print(now); // 2023-05-21
        print(now.get(ChronoField.MONTH_OF_YEAR)); // 5
        print(now.get(ChronoField.DAY_OF_MONTH)); // 21
        print(now.toEpochDay()); // 19498
        print(now.getMonth()); // MAY
        print(now.getDayOfMonth()); // 21
        print(now.getDayOfWeek().getValue()); // 7
        print(now.getDayOfYear()); // 141
        print(now.lengthOfYear()); // 365
    }

    private static void print(Object o) {
        System.out.println(o);
    }
}

4.日期间隔计算

package com.link.test;

import java.time.LocalDate;
import java.time.Period;
import java.time.temporal.ChronoUnit;

public class LocalDateBetweenTest {
    public static void main(String[] args) {
        LocalDate nowDate = LocalDate.now();
        LocalDate beforeDate = LocalDate.of(2022, 5, 20);
        // 一、计算两个日期之间的间隔天数
        print(nowDate.toEpochDay() - beforeDate.toEpochDay());

        // 二、计算两个日期之间间隔的天数、月数、年数
        print(ChronoUnit.DAYS.between(beforeDate,nowDate)); // 间隔的天数
        print(ChronoUnit.MONTHS.between(beforeDate,nowDate)); // 间隔的月数
        print(ChronoUnit.YEARS.between(beforeDate,nowDate)); // 间隔的年数
        // between方法中使用的是以下方法
        print(beforeDate.until(nowDate,ChronoUnit.YEARS));
        Period until = beforeDate.until(nowDate);
        print(String.format("两个时间相差:%d年%d月%d日",until.getYears(),until.getMonths(),until.getDays()));

        // 三、计算两个日期之间间隔的天数、月数、年数
        Period between = Period.between(beforeDate, nowDate);
        print(String.format("两个时间相差:%d年%d月%d日",between.getYears(),between.getMonths(),between.getDays()));
    }

    private static void print(Object o) {
        System.out.println(o);
    }
}


二、LocalDateTime类

参考:
Java 日期和时间
java8之LocalDate的使用、LocalDate格式化问题
UTC与GMT的区别