Java8中时间API

简介: Java8中时间API


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。

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) 将指定格式的字符序列解析为一个日期、时间
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:
@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,用于计算两个“日期”间隔
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 的实现。

@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()
相关文章
|
4天前
|
安全 Java API
Java Stream API详解与使用
Java Stream API是Java 8引入的特性,提供函数式操作处理集合,支持链式操作和并行处理,提升代码可读性和性能。关键点包括:延迟执行的中间操作(如filter, map)和触发计算的终端操作(如collect, forEach)。示例展示了如何从Person列表过滤出年龄大于20的姓名并排序。使用Stream时注意避免中间操作的副作用,终端操作后Stream不能复用,以及并行操作的线程安全性。
12 1
|
1天前
|
安全 Java API
Java进阶-Java Stream API详解与使用
效、更易于维护的代码,同时享受到函数式编程带来的好处。
9 2
|
2天前
|
Java 大数据 API
利用Java Stream API实现高效数据处理
在大数据和云计算时代,数据处理效率成为了软件开发者必须面对的重要挑战。Java 8及以后版本引入的Stream API为开发者提供了一种声明式、函数式的数据处理方式,极大提升了数据处理的效率和可读性。本文将详细介绍Java Stream API的基本概念、使用方法和性能优势,并通过实际案例展示如何在实际项目中应用Stream API实现高效数据处理。
|
2天前
|
自然语言处理 Java API
Java 8的Stream API和Optional类:概念与实战应用
【5月更文挑战第17天】Java 8引入了许多重要的新特性,其中Stream API和Optional类是最引人注目的两个。这些特性不仅简化了集合操作,还提供了更好的方式来处理可能为空的情况,从而提高了代码的健壮性和可读性。
24 7
|
2天前
|
Java API
Java 8新特性之Lambda表达式与Stream API
【5月更文挑战第17天】本文将介绍Java 8中的两个重要特性:Lambda表达式和Stream API。Lambda表达式是一种新的编程语法,它允许我们将函数作为参数传递给其他方法,从而使代码更加简洁。Stream API是一种用于处理集合的新工具,它提供了一种高效且易于使用的方式来处理数据。通过结合使用这两个特性,我们可以编写出更加简洁、高效的Java代码。
7 0
|
4天前
|
Java API
Java 8新特性之Lambda表达式与Stream API实践指南
【5月更文挑战第15天】 随着Java语言的不断发展,Java 8作为一个重要的版本,引入了许多令人兴奋的新特性。其中,Lambda表达式和Stream API是Java 8最受关注的两个特性。本文将深入探讨Lambda表达式的基本概念、语法和使用场景,以及如何结合Stream API实现更加简洁、高效的代码编写。通过实例演示,帮助读者快速掌握这两个新特性,提高Java编程能力。
|
4天前
|
SQL Java API
Java一分钟之-JPA:Java持久化API简介
【5月更文挑战第14天】Java Persistence API (JPA) 是Java的ORM规范,用于简化数据库操作。常见问题包括实体映射、事务管理和性能问题。避免错误的关键在于明确主键策略、妥善使用事务、优化查询及理解实体生命周期。示例展示了如何定义实体和使用`EntityManager`保存数据。JPA通过标准化API让开发者更专注于业务逻辑,提升开发效率和代码维护性。
14 0
|
4天前
|
Java API
Java一分钟之-Java日期与时间API:LocalDate, LocalDateTime
【5月更文挑战第13天】Java 8引入`java.time`包,改进日期时间API。`LocalDate`代表日期,`LocalDateTime`包含日期和时间。本文概述两者的基本用法、常见问题及解决策略。创建日期时间使用`of()`和`parse()`,操作日期时间有`plusDays()`、`minusMonths()`等。注意点包括:设置正确的`DateTimeFormatter`,考虑闰年影响,以及在需要时区信息时使用`ZonedDateTime`。正确使用这些类能提升代码质量。
12 3
|
4天前
|
Java API 数据处理
Java一分钟之-Stream API:数据处理新方式
【5月更文挑战第13天】Java 8的Stream API为集合操作提供了声明式编程,简化数据处理。本文介绍了Stream的基本概念、常见问题和易错点。问题包括并行流与顺序流的区别,状态改变操作的影响,以及忘记调用终止操作和误用`peek()`。理解并合理使用Stream API能提升代码效率和可维护性。实践中不断探索,将发掘更多Stream API的潜力。
12 3
|
4天前
|
Java 程序员 API
Java 8新特性之Lambda表达式与Stream API的深度解析
【5月更文挑战第12天】本文将深入探讨Java 8中的两个重要新特性:Lambda表达式和Stream API。我们将从基本概念入手,逐步深入到实际应用场景,帮助读者更好地理解和掌握这两个新特性,提高Java编程效率。
43 2