Java8中时间API

2023-04-28 08:23:02 浏览数 (1)

Java 8新的日期时间API包含:

  • java.time – 包含值对象的基础包
  • java.time.chrono – 提供对不同的日历系统的访问。
  • java.time.format – 格式化和解析时间和日期
  • java.time.temporal – 包括底层框架和扩展特性
  • java.time.zone – 包含时区支持的类

1.本地日期时间:LocalDate、LocalTime、LocalDateTime

方法

描述

now()/ now(ZoneId zone)

静态方法,根据当前时间创建对象/指定时区的对象

of(xx,xx,xx,xx,xx,xxx)

静态方法,根据指定日期/时间创建对象

getDayOfMonth()/getDayOfYear()

获得月份天数(1-31) /获得年份天数(1-366)

getDayOfWeek()

获得星期几(返回一个 DayOfWeek 枚举值)

getMonth()

获得月份, 返回一个 Month 枚举值

getMonthValue() / getYear()

获得月份(1-12) /获得年份

方法

描述

getHours()/getMinute()/getSecond()

获得当前对象对应的小时、分钟、秒

withDayOfMonth()/withDayOfYear()/withMonth()/withYear()

将月份天数、年份天数、月份、年份修改为指定的值并返回新的对象

with(TemporalAdjuster t)

将当前日期时间设置为校对器指定的日期时间

plusDays(), plusWeeks(), plusMonths(), plusYears(),plusHours()

向当前对象添加几天、几周、几个月、几年、几小时

minusMonths() / minusWeeks()/minusDays()/minusYears()/minusHours()

从当前对象减去几月、几周、几天、几年、几小时

plus(TemporalAmount t)/minus(TemporalAmount t)

添加或减少一个 Duration 或 Period

isBefore()/isAfter()

比较两个 LocalDate

isLeapYear()

判断是否是闰年(在LocalDate类中声明)

format(DateTimeFormatter t)

格式化本地日期、时间,返回一个字符串

parse(Charsequence text)

将指定格式的字符串解析为日期、时间

2.瞬时:Instant

Instant:时间线上的一个瞬时点。 这可能被用来记录应用程序中的事件时间戳。

  • 时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。

java.time.Instant表示时间线上的一点,而不需要任何上下文信息,例如,时区。概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC)开始的秒数。

方法

描述

now()

静态方法,返回默认UTC时区的Instant类的对象

ofEpochMilli(long epochMilli)

静态方法,返回在1970-01-01 00:00:00基础上加上指定毫秒数之后的Instant类的对象

atOffset(ZoneOffset offset)

结合即时的偏移来创建一个 OffsetDateTime

toEpochMilli()

返回1970-01-01 00:00:00到当前时间的毫秒数,即为时间戳

中国大陆、中国香港、中国澳门、中国台湾、蒙古国、新加坡、马来西亚、菲律宾、西澳大利亚州的时间与UTC的时差均为 8,也就是UTC 8。

代码语言:javascript复制
instant.atOffset(ZoneOffset.ofHours(8));

3.日期时间格式化:DateTimeFormatter

该类提供了三种格式化方法:

  • 预定义的标准格式。如:ISOLOCALDATETIME、ISOLOCALDATE、ISOLOCAL_TIME
  • 本地化相关的格式。如:ofLocalizedDate(FormatStyle.LONG)
  • 自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)

方 法

描 述

ofPattern(String pattern)

静态方法,返回一个指定字符串格式的DateTimeFormatter

format(TemporalAccessor t)

格式化一个日期、时间,返回字符串

parse(CharSequence text)

将指定格式的字符序列解析为一个日期、时间

代码语言:javascript复制
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;

public class TestDatetimeFormatter {
    @Test
    public void test1(){
        // 方式一:预定义的标准格式。如: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);
        System.out.println(str1);//2022-12-04T21:02:14.808

        // 解析:字符串 -->日期
        TemporalAccessor parse = formatter.parse("2022-12-04T21:02:14.808");
        LocalDateTime dateTime = LocalDateTime.from(parse);
        System.out.println(dateTime);
    }

    @Test
    public void test2(){
        LocalDateTime localDateTime = LocalDateTime.now();
        // 方式二:
        // 本地化相关的格式。如:ofLocalizedDateTime()
        // FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT :适用于LocalDateTime
        DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
        
        // 格式化
        String str2 = formatter1.format(localDateTime);
        System.out.println(str2);// 2022年12月4日 下午09时03分55秒

        // 本地化相关的格式。如:ofLocalizedDate()
        // FormatStyle.FULL / FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT : 适用于LocalDate
        DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
        // 格式化
        String str3 = formatter2.format(LocalDate.now());
        System.out.println(str3);// 2022年12月4日 星期日
    }

    @Test
    public void test3(){
        //方式三:自定义的方式
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        //格式化
        String strDateTime = dateTimeFormatter.format(LocalDateTime.now());
        System.out.println(strDateTime); //2022/12/04 21:05:42
        //解析
        TemporalAccessor accessor = dateTimeFormatter.parse("2022/12/04 21:05:42");
        LocalDateTime localDateTime = LocalDateTime.from(accessor);
        System.out.println(localDateTime); //2022-12-04T21:05:42
    }
}

4.其它API

4.1 指定时区日期时间:ZondId和ZonedDateTime

  • ZoneId:该类中包含了所有的时区信息,一个时区的ID,如 Europe/Paris
  • ZonedDateTime:一个在ISO-8601日历系统时区的日期时间,如 2007-12-03T10:15:30 01:00 Europe/Paris。
    • 其中每个时区都对应着ID,地区ID都为“{区域}/{城市}”的格式,例如:Asia/Shanghai等
  • 常见时区ID:
    • Asia/Shanghai
    • UTC
    • America/New_York
  • 可以通过ZondId获取所有可用的时区ID:
代码语言:javascript复制
@Test
public void test01() {
    //需要知道一些时区的id
    //Set<String>是一个集合,容器
    Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
    //快捷模板iter
    for (String availableZoneId : availableZoneIds) {
        System.out.println(availableZoneId);
    }
}

@Test
public void test02(){
    ZonedDateTime t1 = ZonedDateTime.now();
    System.out.println(t1);

    ZonedDateTime t2 = ZonedDateTime.now(ZoneId.of("America/New_York"));
    System.out.println(t2);
}

4.2 持续日期/时间:Period和Duration

  • 持续时间:Duration,用于计算两个“时间”间隔
  • 日期间隔:Period,用于计算两个“日期”间隔
代码语言:javascript复制
public class TestPeriodDuration {
    @Test
    public void test01(){
        LocalDate t1 = LocalDate.now();
        LocalDate t2 = LocalDate.of(2018, 12, 31);
        Period between = Period.between(t1, t2);
        System.out.println(between);

        System.out.println("相差的年数:" between.getYears());
        System.out.println("相差的月数:" between.getMonths());
        System.out.println("相差的天数:" between.getDays());
        System.out.println("相差的总数:" between.toTotalMonths());
    }

    @Test
    public void test02(){
        LocalDateTime t1 = LocalDateTime.now();
        LocalDateTime t2 = LocalDateTime.of(2017, 8, 29, 0, 0, 0, 0);
        Duration between = Duration.between(t1, t2);
        System.out.println(between);

        System.out.println("相差的总天数:" between.toDays());
        System.out.println("相差的总小时数:" between.toHours());
        System.out.println("相差的总分钟数:" between.toMinutes());
        System.out.println("相差的总秒数:" between.getSeconds());
        System.out.println("相差的总毫秒数:" between.toMillis());
        System.out.println("相差的总纳秒数:" between.toNanos());
        System.out.println("不够一秒的纳秒数:" between.getNano());
    }
    @Test
    public void test03(){
        //Duration:用于计算两个“时间”间隔,以秒和纳秒为基准
		LocalTime localTime = LocalTime.now();
		LocalTime localTime1 = LocalTime.of(15, 23, 32);
		//between():静态方法,返回Duration对象,表示两个时间的间隔
		Duration duration = Duration.between(localTime1, localTime);
		System.out.println(duration);

		System.out.println(duration.getSeconds());
		System.out.println(duration.getNano());

		LocalDateTime localDateTime = LocalDateTime.of(2016, 6, 12, 15, 23, 32);
		LocalDateTime localDateTime1 = LocalDateTime.of(2017, 6, 12, 15, 23, 32);

		Duration duration1 = Duration.between(localDateTime1, localDateTime);
		System.out.println(duration1.toDays());
    }
    
    @Test
    public void test4(){
        //Period:用于计算两个“日期”间隔,以年、月、日衡量
		LocalDate localDate = LocalDate.now();
		LocalDate localDate1 = LocalDate.of(2028, 3, 18);

		Period period = Period.between(localDate, localDate1);
		System.out.println(period);

		System.out.println(period.getYears());
		System.out.println(period.getMonths());
		System.out.println(period.getDays());

		Period period1 = period.withYears(2);
		System.out.println(period1);

    }
}

4.3 Clock:使用时区提供对当前即时、日期和时间的访问的时钟。

4.4 TemporalAdjuster

TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下一个工作日”等操作。 TemporalAdjusters : 该类通过静态方法(firstDayOfXxx()/lastDayOfXxx()/nextXxx())提供了大量的常用 TemporalAdjuster 的实现。

代码语言:javascript复制
@Test
public void test1(){
    // TemporalAdjuster:时间校正器
	// 获取当前日期的下一个周日是哪天?
	TemporalAdjuster temporalAdjuster = TemporalAdjusters.next(DayOfWeek.SUNDAY);
	LocalDateTime localDateTime = LocalDateTime.now().with(temporalAdjuster);
	System.out.println(localDateTime);
	// 获取下一个工作日是哪天?
	LocalDate localDate = LocalDate.now().with(new TemporalAdjuster() {
   	 	@Override
   	 	public Temporal adjustInto(Temporal temporal) {
        	LocalDate date = (LocalDate) temporal;
     	  	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);
        	}
    	}
	});
	System.out.println("下一个工作日是:"   localDate);

}

5.与传统日期处理的转换

To 遗留类

From 遗留类

java.time.Instant与java.util.Date

Date.from(instant)

date.toInstant()

java.time.Instant与java.sql.Timestamp

Timestamp.from(instant)

timestamp.toInstant()

java.time.ZonedDateTime与java.util.GregorianCalendar

GregorianCalendar.from(zonedDateTime)

cal.toZonedDateTime()

To 遗留类

From 遗留类

java.util.GregorianCalendar

java.time.LocalDate与java.sql.Time

Date.valueOf(localDate)

date.toLocalDate()

java.time.LocalTime与java.sql.Time

Date.valueOf(localDate)

date.toLocalTime()

java.time.LocalDateTime与java.sql.Timestamp

Timestamp.valueOf(localDateTime)

timestamp.toLocalDateTime()

java.time.ZoneId与java.util.TimeZone

Timezone.getTimeZone(id)

timeZone.toZoneId()

java.time.format.DateTimeFormatter与java.text.DateFormat

formatter.toFormat()

0 人点赞