深入了解Java8新特性-日期时间API:LocalDateTime类

 

阅读建议

嗨,伙计!刷到这篇文章咱们就是有缘人,在阅读这篇文章前我有一些建议:

  1. 本篇文章大概22000多字,预计阅读时间长需要20分钟以上。
  2. 本篇文章的实战性、理论性较强,是一篇质量分数较高的技术干货文章,建议收藏起来,方便时常学习与回顾,温故而知新。
  3. 创作不易,免费的点赞、关注,请走上一走,算是对博主一些鼓励,让我更有动力输出更多的干货内容。

注意

本文编写的单元测试是基于java11,具体的版本号是:11.0.19

关于LocalDateTime

LocalDateTime 是 Java 8 中引入的一个新的日期时间 API,它表示一个没有时区的日期时间对象,是不可变且线程安全的。LocalDateTime 通常用于需要同时表示日期和时间,但不涉及时区的场景。

LocalDateTime、LocalDate和LocalTime都是Java中用于表示日期和时间的数据类型,但它们在功能和使用上有一些重要的区别。

与LocalDate的区别

功能:

  • LocalDateTime:是一个不可变的日期时间对象,包含日期和时间信息,通常被视为年-月-日-时-分-秒。它也可以访问其他日期和时间字段,例如一年中的某天、一周中的某天和一周中的某周。时间以纳秒精度表示。LocalDateTime是不可变的,提供了各种方法来操作和提取日期和时间值,并且是线程安全的。
  • LocalDate:也是一个不可变的日期时间对象,但只包含日期信息,通常被视为年-月-日。它不包含时间信息。LocalDate提供了方法来操作和提取日期值,但不包括时间信息。同样,它是不可变的,并且是线程安全的。

使用场景:

  • 如果需要同时处理日期和时间信息,LocalDateTime更为适用。
  • 如果只需要操作日期,不需要时间信息,LocalDate可能更合适。

与LocalTime的区别

功能:

  • LocalDateTime表示日期和时间,不包含时区信息。它是一个不可变类,提供了一系列方法来获取、设置和操作年、月、日、时、分、秒等日期和时间的不同部分,以及进行比较、格式化、解析等操作。LocalDateTime是LocalDate和LocalTime的组合,可以用于存储和操作具体的日期和时间。
  • LocalTime表示时间,不包含日期和时区信息。它也是不可变类,提供了一系列方法来获取、设置和操作时、分、秒等时间的不同部分,以及进行比较、格式化等操作。LocalTime可以用于存储和操作每天的固定时间点,如午夜、中午等。

使用场景

  • 如果需要同时处理日期和时间信息,LocalDateTime更为适用。
  • 如果只需要操作时间,不需要日期信息,LocalTime可能更合适。

核心方法

LocalDateTime#now()

LocalDateTime#now() 用于获取当前的日期和时间,不包含时区信息。

   @Test
   public void test() {
        LocalDateTime now = LocalDateTime.now();
        String format = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println(format);//当前日期和时间:2023-11-27 11:23:54
    }

LocalDateTime#of(...)、LocalDateTime#ofInstant(...)、LocalDateTime#ofEpochSecond(...)

  • LocalDateTime#of():这个方法用于创建一个具有特定日期和时间的LocalDateTime对象。它接受年、月、日、时、分、秒作为参数,返回一个对应的LocalDateTime实例。使用场景包括需要创建一个特定的日期和时间对象,例如生日、纪念日等。
  • LocalDateTime#ofInstant():这个方法用于使用Instant和时区ID创建LocalDateTime的实例。它将两个参数传递给方法,一个是Instant类型,表示传递给创建localdatetime的瞬间,另一个是ZoneId类型,代表用于创建偏移量的时区。该方法返回一个对应的LocalDateTime实例。使用场景包括需要将一个瞬时转化为本地日期和时间,例如在处理与时间相关的数据时,需要将UTC时间转换为本地时间。
  • LocalDateTime#ofEpochSecond():这个方法用于根据秒数和纳秒数创建一个LocalDateTime对象。它接受秒数和纳秒数作为参数,返回一个对应的LocalDateTime实例。使用场景包括需要将秒数和纳秒数转化为日期和时间对象,例如在处理时间戳等数据时,需要将秒数和纳秒数转换为日期和时间对象。
   
    @Test
    public void test2() {
        LocalDateTime localDateTime = LocalDateTime.of(2023, 11, 27, 11, 27, 56);
        System.out.println(localDateTime);//输出结果:2023-11-27T11:27:56
        LocalDate localDate = LocalDate.of(2023, 11, 27);
        LocalTime localTime = LocalTime.of(11, 27, 56);
        LocalDateTime localDateTime1 = LocalDateTime.of(localDate, localTime);
        System.out.println(localDateTime1);//输出结果:2023-11-27T11:27:56
        LocalDateTime localDateTime2 = LocalDateTime.ofInstant(Instant.ofEpochSecond(61), ZoneId.systemDefault());
        System.out.println(localDateTime2);//输出结果:1970-01-01T08:01:01
        LocalDateTime localDateTime3 = LocalDateTime.ofEpochSecond(61, 0, ZoneOffset.ofHours(8));
        System.out.println(localDateTime3);//输出结果:1970-01-01T08:01:01
    }

LocalDateTime#from(...)

LocalDateTime#from(...)用于从给定的日期时间对象中创建一个新的LocalDateTime实例。这个方法接受一个Object类型的参数,这个对象需要是以下类型之一:

  • ZonedDateTime
  • OffsetDateTime
  • Instant
  • LocalDate
  • LocalTime
  • YearMonth
  • MonthDay
  • YearWeek
  • Year
  • Month
  • DayOfWeek
  • WeekOfMonth
  • WeekOfYear
  • DayOfYear
  • MonthDayOfYear
  • YearMonthDayOfYear

当给定的日期时间对象为以上所列出的类型之一时,LocalDateTime#from(...)方法会尝试从中提取日期和时间信息,并创建一个新的LocalDateTime实例。如果给定的对象无法转换为LocalDateTime,那么这个方法会抛出一个DateTimeException异常。

这个方法的使用场景通常是在需要将一个日期时间对象转换为LocalDateTime,以便进行后续的日期和时间运算或处理。例如,你可能从数据库中获取了一个日期时间戳,然后你需要将这个日期时间戳转换为LocalDateTime,以便进行进一步的计算或处理。或者,你可能需要从一个具有特定时区的日期时间对象中创建一个没有时区的LocalDateTime。

     @Test
    public void test3() {
        LocalDateTime localDateTime = LocalDateTime.parse("2023-11-2711:36:56", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime from = LocalDateTime.from(localDateTime);
        System.out.println(from);//输出结果:2023-11-2711:36:56
    }  

LocalDateTime#parse(...)

LocalDateTime#parse(...) 用于将字符串解析为 LocalDateTime 对象的函数。该方法使用一个字符串作为输入,并根据该字符串的内容创建一个新的 LocalDateTime 对象。

在使用该方法时,该字符串必须符合 ISO 8601 格式,例如 "2019-01-01T12:00:00",另外还需要注意时区的问题。如果字符串中没有指定时区信息,那么解析出来的 LocalDateTime 对象将是本地时区的时间。如果需要指定时区,可以使用 ZoneId 类的 of 方法来创建时区对象,然后使用 LocalDateTime.atZone 方法将 LocalDateTime 对象转换为 ZonedDateTime 对象,最后再使用 ZonedDateTime.toLocalDateTime 方法将其转换为指定时区的 LocalDateTime 对象。

     @Test
    public void test4() {
        LocalDateTime localDateTime = LocalDateTime.parse("2023-11-2711:36:56", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println(localDateTime);//输出结果:2023-11-2711:36:56
    }

LocalDateTime#isSupported(...)

LocalDateTime#isSupported() 用于检查是否支持特定的单位或字段。该方法接受一个参数,可以是 TemporalUnit 或 TemporalField 对象,用于指定要检查的单位或字段。如果支持,方法将返回 true;如果不支持,方法将返回 false。

使用场景:

  • 需要对日期时间进行特定单位或字段的操作时:如果需要在代码中使用 LocalDateTime 对象进行日期时间操作,并需要确保所使用的字段或单位是受支持的,可以使用 LocalDateTime#isSupported() 方法进行检查。例如,在执行加减运算之前,可以使用该方法检查是否支持特定的时间单位。
  • 需要进行日期时间格式验证时:在使用 LocalDateTime 对象处理日期时间数据时,可能需要对输入数据进行格式验证。通过调用 LocalDateTime#isSupported() 方法并传递相应的单位或字段参数,可以验证输入数据是否符合要求。例如,可以检查日期时间字符串是否包含不合法的字段或单位。
@Test
public void test5() {
        LocalDateTime now = LocalDateTime.now();
        boolean supported = now.isSupported(ChronoUnit.YEARS);
        boolean supported1 = now.isSupported(ChronoField.DAY_OF_YEAR);
        System.out.println(supported);//输出结果:true
        System.out.println(supported1);//输出结果:true
    }

LocalDateTime#range(...)

LocalDateTime#range(...) 用于获取LocalDateTime对象指定字段的有效值范围,返回值是一个ValueRange对象,range对象表示字段的最小和最大有效值。此日期时间用于提高返回范围的准确性。如果由于不支持该字段或其他原因而无法返回范围,则会引发异常。

  
    @Test
    public void test6() {
        LocalDateTime now = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
        ValueRange range = now.range(ChronoField.DAY_OF_MONTH);
        long maximum = range.getMaximum();
        long minimum = range.getMinimum();
        System.out.println(maximum);//输出结果:29
        System.out.println(minimum);//输出结果:1
        LocalDateTime now2 = LocalDateTime.of(2023, 2, 1, 12, 18, 56);
        ValueRange range2 = now2.range(ChronoField.DAY_OF_MONTH);
        long maximum2 = range2.getMaximum();
        long minimum2 = range2.getMinimum();
        System.out.println(maximum2);//输出结果:28
        System.out.println(minimum2);//输出结果:1
    }

LocalDateTime#get(...)、LocalDateTime#getLong(...)、LocalDateTime#getYear(...)、LocalDateTime#getMonthValue(...)、LocalDateTime#getMonth(...)、LocalDateTime#getDayOfMonth(...)、LocalDateTime#getDayOfYear(...)、LocalDateTime#getDayOfWeek(...)、LocalDateTime#getHour(...)、LocalDateTime#getMinute(...)、LocalDateTime#getSecond(...)、LocalDateTime#getNano(...)

  • LocalDateTime#get(TemporalField):此方法获取给定时间字段的值。参数可以是年、月、日、时、分、秒或纳秒等。它通常用于对日期和时间进行精细操作或计算。
  • LocalDateTime#getLong(TemporalField):此方法获取给定时间字段的长整型值。它的使用场景与get方法类似,但返回值是长整型的。
  • LocalDateTime#getYear():此方法返回当前日期的年份。它通常用于进行年份相关的计算或处理。
  • LocalDateTime#getMonthValue():此方法返回当前月份的值,以整数形式表示。它通常用于处理或操作月份信息。
  • LocalDateTime#getMonth():此方法返回当前月份的Text,如"January"、"February"等。它主要用于获取月份的全称。
  • LocalDateTime#getDayOfMonth():此方法返回当前日期的日,以整数形式表示。它通常用于处理或操作具体的日期信息。
  • LocalDateTime#getDayOfYear():此方法返回当前日期是一年中的第几天,以整数形式表示。它主要用于计算或处理一年中的日期信息。
  • LocalDateTime#getDayOfWeek():此方法返回当前日期是星期几,以Text形式表示,如"Monday"、"Tuesday"等。它主要用于获取星期的全称。
  • LocalDateTime#getHour():此方法返回当前时间的时,以整数形式表示。它通常用于处理或操作具体的小时信息。
  • LocalDateTime#getMinute():此方法返回当前时间的分,以整数形式表示。它通常用于处理或操作具体的分钟信息。
  • LocalDateTime#getSecond():此方法返回当前时间的秒,以整数形式表示。它通常用于处理或操作具体的秒信息。
  • LocalDateTime#getNano():此方法返回当前时间的纳秒,以整数形式表示。它主要用于获取纳秒级别的精度信息。
@Test
    public void test7() {
        LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
        int year = localDateTime.get(ChronoField.YEAR);
        System.out.println(year);//输出结果:2020
        int month = localDateTime.get(ChronoField.MONTH_OF_YEAR);
        System.out.println(month);//输出结果:2
        long yearLong = localDateTime.getLong(ChronoField.YEAR);
        System.out.println(yearLong);//输出结果:2020
        long monthLong = localDateTime.getLong(ChronoField.MONTH_OF_YEAR);
        System.out.println(monthLong);//输出结果:2
        int year1 = localDateTime.getYear();
        System.out.println(year1);//输出结果:2020
        int monthValue = localDateTime.getMonthValue();
        System.out.println(monthValue);//输出结果:2
        int dayOfMonth = localDateTime.getDayOfMonth();
        System.out.println(dayOfMonth);//输出结果:1
        int dayOfYear = localDateTime.getDayOfYear();
        System.out.println(dayOfYear);//输出结果:32
        DayOfWeek dayOfWeek = localDateTime.getDayOfWeek();
        int dayOfWeekValue = dayOfWeek.getValue();
        System.out.println(dayOfWeekValue);//输出结果:6
        int hour = localDateTime.getHour();
        System.out.println(hour);//输出结果:12
        int minute = localDateTime.getMinute();
        System.out.println(minute);//输出结果:18
        int second = localDateTime.getSecond();
        System.out.println(second);//输出结果:56
    }

LocalDateTime#toLocalDate(...)、LocalDateTime#toLocalTime(...)

  • toLocalDate() 方法:该方法用于从 LocalDateTime 对象中获取 LocalDate 对象。它返回一个 LocalDate 实例,表示此 LocalDateTime 对象的日期部分。
  • toLocalTime() 方法:该方法用于从 LocalDateTime 对象中获取 LocalTime 对象。它返回一个 LocalTime 实例,表示此 LocalDateTime 对象的时间部分。
@Test
public void test8() {
    LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
    LocalDate localDate = localDateTime.toLocalDate();
    LocalTime localTime = localDateTime.toLocalTime();
    System.out.println(localDate);//输出结果:2020-02-01
    System.out.println(localTime);//输出结果:12:18:56
}

LocalDateTime#with(...)、LocalDateTime#withYear(...)、LocalDateTime#withMonth(...)、LocalDateTime#withDayOfMonth(...)、LocalDateTime#withDayOfYear(...)、LocalDateTime#withHour(...)、LocalDateTime#withMinute(...)、LocalDateTime#withSecond(...)、LocalDateTime#withNano(...)

上述这些方法可以在不改变日期和时间的其他部分的情况下,对日期和时间的特定部分进行修改和操作。具体来说:

  • LocalDateTime#with():该方法用于使用 TemporalAdjuster 调整此日期时间,并在调整后返回调整后的日期时间的副本。使用指定的调整器策略对象进行调整。
  • LocalDateTime#withYear():该方法用于获取此 LocalDateTime 的副本,并将年份更改为作为该方法的参数传递的年份。此 LocalDateTime 的其余值保持不变。年份的值范围可以从 MIN_YEAR 到 MAX_YEAR。
  • LocalDateTime#withMonth():该方法用于获取此 LocalDateTime 的副本,并将月份更改为作为该方法的参数传递的月份。此 LocalDateTime 的其余值保持不变。月份的值范围从 1 到 12。
  • LocalDateTime#withDayOfMonth():该方法用于获取此 LocalDateTime 的副本,并将日更改为作为该方法的参数传递的日。此 LocalDateTime 的其余值保持不变。日的值范围从 1 到月份的天数。
  • LocalDateTime#withDayOfYear():该方法用于获取此 LocalDateTime 的副本,并将一年中的日子更改为作为该方法的参数传递的日子。此 LocalDateTime 的其余值保持不变。天的值范围从 1 到 365 或 366(取决于年份是否为闰年)。
  • LocalDateTime#withHour():该方法用于获取此 LocalDateTime 的副本,并将小时更改为作为该方法的参数传递的小时。此 LocalDateTime 的其余值保持不变。小时的值范围从 0 到 23。
  • LocalDateTime#withMinute():该方法用于获取此 LocalDateTime 的副本,并将分钟更改为作为该方法的参数传递的分钟。此 LocalDateTime 的其余值保持不变。分钟的值的范围从 0 到 59。
  • LocalDateTime#withSecond():该方法用于获取此 LocalDateTime 的副本,并将秒更改为作为该方法的参数传递的秒。此 LocalDateTime 的其余值保持不变。秒的值范围从 0 到 59(或 60,如果该秒是闰秒)。
  • LocalDateTime#withNano():该方法用于获取此 LocalDateTime 的副本,并将纳秒更改为作为该方法的参数传递的纳秒。此 LocalDateTime 的其余值保持不变。纳秒的值范围从 0 到 999,999,999。
@Test
public void test9() {
    LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
    TemporalAdjuster temporalAdjuster = item -> item.plus(1, ChronoUnit.HOURS);
    LocalDateTime localDateTime1 = localDateTime.with(temporalAdjuster);
    System.out.println(localDateTime1);//输出结果:2020-02-01T13:18:56
    LocalDateTime localDateTime2 = localDateTime.with(ChronoField.HOUR_OF_DAY, 1);
    System.out.println(localDateTime2);//输出结果:2020-02-01T01:18:56
    LocalDateTime localDateTime3 = localDateTime.withYear(2023);
    System.out.println(localDateTime3);//输出结果:2023-02-01T12:18:56
    LocalDateTime localDateTime4 = localDateTime.withMonth(1);
    System.out.println(localDateTime4);//输出结果:2020-01-01T12:18:56
    LocalDateTime localDateTime5 = localDateTime.withDayOfMonth(10);
    System.out.println(localDateTime5);//输出结果:2020-02-10T12:18:56
    LocalDateTime localDateTime6 = localDateTime.withHour(18);
    System.out.println(localDateTime6);//输出结果:2020-02-01T18:18:56
    LocalDateTime localDateTime7 = localDateTime.withMinute(30);
    System.out.println(localDateTime7);//输出结果:2020-02-01T12:30:56
    LocalDateTime localDateTime8 = localDateTime.withSecond(59);
    System.out.println(localDateTime8);//输出结果:2020-02-01T12:18:59
}

LocalDateTime#truncatedTo(...)

LocalDateTime#truncatedTo()用于将当前LocalDateTime对象的时间部分截断到给定的时间单位。

功能作用:

  • 截断日期时间:通过调用LocalDateTime#truncatedTo()方法,可以将当前LocalDateTime对象的时间部分截断到给定的时间单位,例如分钟、小时、天等。截断后的LocalDateTime对象将不再包含被截断单位之前的时间信息。
  • 提供灵活的时间操作:使用LocalDateTime#truncatedTo()方法可以根据具体需求将日期时间截断到不同的时间单位,从而实现灵活的时间操作。例如,可以将日期时间截断到分钟级别,然后进行加减运算,以实现精确到分钟的日期时间计算。

使用场景:

  • 需要截断日期时间时:在一些特定的应用场景中,可能需要对日期时间进行截断操作。例如,在进行统计或数据分析时,可能只需要日期时间中的某一部分信息,而不需要保留完整的时间信息。在这种情况下,可以使用LocalDateTime#truncatedTo()方法将日期时间截断到所需的时间单位。
  • 需要进行时间运算时:在进行时间运算时,如计算两个日期时间之间的差值或进行日期的加减运算等,可以将日期时间截断到分钟或小时级别,以避免因毫秒级的时间差异而产生误差。例如,可以使用LocalDateTime#truncatedTo()方法将日期时间截断到分钟级别,然后进行加减运算,以实现精确到分钟的日期时间计算。
@Test
public void test10() {
    LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
    LocalDateTime localDateTime1 = localDateTime.truncatedTo(ChronoUnit.DAYS);
    System.out.println(localDateTime1);//输出结果:2020-02-01T00:00
}

LocalDateTime#plus(...)、LocalDateTime#plusYears(...)、LocalDateTime#plusMonths(...)、LocalDateTime#plusWeeks(...)、LocalDateTime#plusDays(...)、LocalDateTime#plusHours(...)、LocalDateTime#plusMinutes(...)、LocalDateTime#plusSeconds(...)、LocalDateTime#plusNanos(...)

上述方法,主要用于在现有的日期时间对象上增加指定的时间单位或量。

具体如下:

  • LocalDateTime#plus(long amount, TemporalUnit unit):增加给定数量的单位到当前的日期时间对象。参数amount表示要增加的数量,参数unit表示要增加的时间单位,例如DAYS、WEEKS、MONTHS等。
  • LocalDateTime#plusYears(long years):在当前日期时间对象上增加指定的年份数。参数years表示要增加的年份数,可以为负数。
  • LocalDateTime#plusMonths(long months):在当前日期时间对象上增加指定的月份数。参数months表示要增加的月份数,可以为负数。
  • LocalDateTime#plusWeeks(long weeks):在当前日期时间对象上增加指定的周数。参数weeks表示要增加的周数,可以为负数。
  • LocalDateTime#plusDays(long days):在当前日期时间对象上增加指定的天数。参数days表示要增加的天数,可以为负数。
  • LocalDateTime#plusHours(long hours):在当前日期时间对象上增加指定的小时数。参数hours表示要增加的小时数,可以为负数。
  • LocalDateTime#plusMinutes(long minutes):在当前日期时间对象上增加指定的分钟数。参数minutes表示要增加的分钟数,可以为负数。
  • LocalDateTime#plusSeconds(long seconds):在当前日期时间对象上增加指定的秒数。参数seconds表示要增加的秒数,可以为负数。
  • LocalDateTime#plusNanos(long nanos):在当前日期时间对象上增加指定的纳秒数。参数nanos表示要增加的纳秒数,可以为负数。

使用场景:

  • 日期时间的计算和运算:可以通过调用这些方法来对日期时间进行计算和运算。例如,可以使用LocalDateTime#plusYears()方法来计算未来某一年的日期时间,或者使用LocalDateTime#plusDays()方法来计算未来某一天的日期时间。
  • 定时器和定时任务:这些方法可以与Java中的定时器类(如java.util.Timer)结合使用,以实现定时任务或定时触发某些操作。例如,可以使用LocalDateTime#now()方法获取当前日期时间,然后将其作为定时器的触发时间。
  • 时间的调整和格式化:可以使用这些方法来对日期时间进行调整和格式化。例如,可以使用LocalDateTime#plusHours()方法来将当前时间向前移动几个小时,或者使用LocalDateTime#format()方法将日期时间格式化为特定的字符串格式。
  • 日历和日程安排:这些方法可以用于日历和日程安排应用中。例如,可以使用LocalDateTime#plusMonths()方法来计算下个月的日期时间,或者使用LocalDateTime#plusWeeks()方法来计算未来一周的日期时间。
@Test
public void test11() {
    LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
    LocalDateTime localDateTime1 = localDateTime.plus(Period.ofDays(3));
    LocalDateTime localDateTime2 = localDateTime.plus(3, ChronoUnit.DAYS);
    System.out.println(localDateTime1);//输出结果:2020-02-04T12:18:56
    System.out.println(localDateTime2);//输出结果:2020-02-04T12:18:56
    LocalDateTime localDateTime3 = localDateTime.plusYears(1);
    System.out.println(localDateTime3);//输出结果:2021-02-01T12:18:56
    LocalDateTime localDateTime4 = localDateTime.plusMonths(1);
    System.out.println(localDateTime4);//输出结果:2020-03-01T12:18:56
    LocalDateTime localDateTime5 = localDateTime.plusWeeks(1);
    System.out.println(localDateTime5);//输出结果:2020-02-08T12:18:56
    LocalDateTime localDateTime6 = localDateTime.plusDays(10);
    System.out.println(localDateTime6);//输出结果:2020-02-11T12:18:56
    LocalDateTime localDateTime7 = localDateTime.plusHours(3);
    System.out.println(localDateTime7);//输出结果:2020-02-01T15:18:56
    LocalDateTime localDateTime8 = localDateTime.plusMinutes(12);
    System.out.println(localDateTime8);//输出结果:2020-02-01T12:30:56
    LocalDateTime localDateTime9 = localDateTime.plusSeconds(4);
    System.out.println(localDateTime9);//输出结果:2020-02-01T12:19
}

LocalDateTime#minus(...)、LocalDateTime#minusYears(...)、LocalDateTime#minusMonths(...)、LocalDateTime#minusWeeks(...)、LocalDateTime#minusDays(...)、LocalDateTime#minusHours(...)、LocalDateTime#minusMinutes(...)、LocalDateTime#minusSeconds(...)、LocalDateTime#minusNanos(...)

上述这些方法,用于对日期和时间的减法操作,需要注意的是,这些方法的计算结果值超过限制时可能会抛出DateTimeException异常。

具体如下:

  • LocalDateTime#minus():该方法用于在当前LocalDateTime对象中减去指定的时间间隔。它接受一个TemporalAmount参数,表示要减去的金额。返回值是此日期时间的副本,减去指定的金额。使用场景:在进行日期时间的减法操作时,可以使用该方法来减去指定的时间间隔。
  • LocalDateTime#minusYears():该方法用于从此日期时间对象中减去给定的年份并返回LocalDateTime。它接受一个long类型的参数,表示要减去的年份数。返回值是保存从该LocalDateTime减去给定年份的值的LocalDateTime。使用场景:在进行日期时间的减法操作时,可以使用该方法来减去指定的年份数。
  • LocalDateTime#minusMonths():该方法用于从此日期时间对象中减去给定的月份并返回LocalDateTime。它接受一个long类型的参数,表示要减去的月份数。返回值是保存从该LocalDateTime减去给定月份的值的LocalDateTime。使用场景:在进行日期时间的减法操作时,可以使用该方法来减去指定的月份数。
  • LocalDateTime#minusWeeks():该方法用于从此日期时间对象中减去给定的周数并返回LocalDateTime。它接受一个long类型的参数,表示要减去的周数数。返回值是保存从该LocalDateTime减去给定周数的值的LocalDateTime。使用场景:在进行日期时间的减法操作时,可以使用该方法来减去指定的周数数。
  • LocalDateTime#minusDays():该方法用于从此日期时间对象中减去给定的天数并返回LocalDateTime。它接受一个long类型的参数,表示要减去的天数数。返回值是保存从该LocalDateTime减去给定天数的值的LocalDateTime。使用场景:在进行日期时间的减法操作时,可以使用该方法来减去指定的天数数。
  • LocalDateTime#minusHours():该方法用于从此日期时间对象中减去给定的小时数并返回LocalDateTime。它接受一个long类型的参数,表示要减去的小时数。返回值是保存从该LocalDateTime减去给定小时数的值的LocalDateTime。使用场景:在进行日期时间的减法操作时,可以使用该方法来减去指定的小时数。
  • LocalDateTime#minusMinutes():该方法用于从此日期时间对象中减去给定的分钟数并返回LocalDateTime。它接受一个long类型的参数,表示要减去的分钟数。返回值是保存从该LocalDateTime减去给定分钟数的值的LocalDateTime。使用场景:在进行日期时间的减法操作时,可以使用该方法来减去指定的分钟数。
  • LocalDateTime#minusSeconds():该方法用于从此日期时间对象中减去给定的秒数并返回LocalDateTime。它接受一个long类型的参数,表示要减去的秒数。返回值是保存从该LocalDateTime减去给定秒数的值的LocalDateTime。使用场景:在进行日期时间的减法操作时,可以使用该方法来减去指定的秒数。
  • LocalDateTime#minusNanos():该方法用于从此日期时间对象中减去给定的纳秒数并返回LocalDateTime。它接受一个long类型的参数,表示要减去的纳秒数。返回值是保存从该LocalDateTime减去给定纳秒数的值的LocalDateTime。使用场景:在进行高精度日期时间的减法操作时,可以使用该方法来减去指定的纳秒数。
@Test
public void test12() {
    LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
    LocalDateTime localDateTime1 = localDateTime.minus(Period.ofDays(3));
    LocalDateTime localDateTime2 = localDateTime.minus(3, ChronoUnit.DAYS);
    System.out.println(localDateTime1);//输出结果:2020-01-29T12:18:56
    System.out.println(localDateTime2);//输出结果:2020-01-29T12:18:56
    LocalDateTime localDateTime3 = localDateTime.minusYears(1);
    System.out.println(localDateTime3);//输出结果:2019-02-01T12:18:56
    LocalDateTime localDateTime4 = localDateTime.minusMonths(1);
    System.out.println(localDateTime4);//输出结果:2020-01-01T12:18:56
    LocalDateTime localDateTime5 = localDateTime.minusWeeks(1);
    System.out.println(localDateTime5);//2020-01-25T12:18:56
    LocalDateTime localDateTime6 = localDateTime.minusDays(10);
    System.out.println(localDateTime6);//输出结果:2020-01-22T12:18:56
    LocalDateTime localDateTime7 = localDateTime.minusHours(3);
    System.out.println(localDateTime7);//输出结果:2020-02-01T09:18:56
    LocalDateTime localDateTime8 = localDateTime.minusMinutes(12);
    System.out.println(localDateTime8);//输出结果:2020-02-01T12:06:56
    LocalDateTime localDateTime9 = localDateTime.minusSeconds(4);
    System.out.println(localDateTime9);//输出结果:2020-02-01T12:18:52
}

LocalDateTime#query(...)

LocalDateTime#query()接受一个TemporalQuery作为参数,用于查询此LocalDateTime。查询的结果会根据传递的查询逻辑来决定。通常在需要基于特定的查询逻辑处理日期和时间的情况下使用。传递给查询方法的逻辑是通过TemporalQuery对象定义的。因此,这个方法在使用时需要结合具体的查询需求和TemporalQuery的实现来使用。

@Test
public void test13() {
    LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
    TemporalQuery<Integer> temporalQuery = item -> item.get(ChronoField.YEAR);
    Integer year = localDateTime.query(temporalQuery);
    System.out.println(year);//输出结果:2020
}

LocalDateTime#until(...)

LocalDateTime#until() 方法用于计算两个 LocalDateTime 对象之间的时间量,并以指定的 TemporalUnit 为单位返回结果。这个方法返回一个整数,表示两个 LocalDateTime 对象之间完整的时间单位数。

功能作用:

  • 计算时间差:LocalDateTime#until() 方法可以计算两个 LocalDateTime 对象之间的时间差。通过调用该方法并传递一个 TemporalUnit 参数,可以获取两个日期时间之间的差距,单位可以是秒、分钟、小时、天等。
  • 提供灵活的时间计算:使用 LocalDateTime#until() 方法可以根据具体需求计算不同时间单位之间的差值。这使得开发者能够根据实际需求进行精确到秒、分钟、小时或天的时间计算,以满足不同的业务需求。

使用场景:

  • 需要计算时间差时:在一些特定的应用场景中,可能需要对两个日期时间之间的时间差进行计算。例如,在记录用户活动日志时,需要计算用户两次操作之间的时间差,以便对用户行为进行分析。在这种情况下,可以使用 LocalDateTime#until() 方法来获取准确的时间差值。
  • 需要进行时间运算时:除了计算时间差,LocalDateTime#until() 方法还可以用于时间运算。例如,可以使用该方法计算两个日期之间的天数,然后根据计算结果进行相应的操作。这可以帮助开发者在处理日期时间时提高计算的准确性和灵活性。
@Test
public void test14() {
    LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
    long until = localDateTime.until(LocalDateTime.of(2023, 2, 1, 12, 30, 56), ChronoUnit.YEARS);
    System.out.println(until);//输出结果:3
}

LocalDateTime#format(...)

LocalDateTime#format(...)用于将当前 LocalDateTime 对象格式化为指定的日期时间字符串。

@Test
public void test15() {
    LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
    String format = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    System.out.println(format);//输出结果:2020-02-01 12:18:56
}

LocalDateTime#atOffset(...)

LocalDateTime#atOffset() 主要是用于合并当前LocalDateTime对象与给定的偏移量。具体来说,该方法创建并返回一个 OffsetDateTime 对象,该对象将保存将当前LocalDateTime 与给定偏移量合并后的值。主要在需要对LocalDateTime对象进行偏移量调整的情况下使用。例如,如果你需要根据当前的LocalDateTime创建一个在特定偏移量(如一小时,一天)后的日期时间,就可以通过使用LocalDateTime#atOffset()方法来实现。这个方法的使用非常灵活,你可以根据需要选择不同的偏移量进行合并,得到的 OffsetDateTime 对象可以用于进一步的日期时间计算或展示等操作。

@Test
public void test16() {
    LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
    OffsetDateTime offsetDateTime = localDateTime.atOffset(ZoneOffset.ofHours(8));
    System.out.println(offsetDateTime);//输出结果:2020-02-01T12:18:56+08:00
}

LocalDateTime#atZone(...)

LocalDateTime#atZone()用于将给定的LocalDateTime对象合并到给定的时区,从而创建一个ZonedDateTime对象。该方法是一个非静态方法,只能通过类对象访问。通过该方法,可以将在不同时区存储的日期时间数据统一到一个时区中进行处理和比较。

使用场景:

  • 需要处理跨时区的日期时间数据时:在一些特定的应用场景中,可能需要对来自不同时区的日期时间数据进行处理和比较。例如,在跨国公司中,可能需要将不同地区的日期时间数据统一到一个时区中进行统计分析。在这种情况下,可以使用LocalDateTime#atZone()方法将LocalDateTime对象转换为ZonedDateTime对象,以便进行跨时区的日期时间操作。
  • 需要确保日期时间数据的一致性时:在一些需要确保日期时间数据一致性的场景中,也可以使用LocalDateTime#atZone()方法。例如,在金融交易中,确保交易时间的准确性非常重要。通过使用该方法,可以将不同地区的日期时间数据转换为相同的时区,以确保交易时间的一致性。
@Test
public void test17() {
    LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
    ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
    System.out.println(zonedDateTime);//输出结果:2020-02-01T12:18:56+08:00[Asia/Shanghai]
}

LocalDateTime#compareTo(...)、LocalDateTime#isAfter(...)、LocalDateTime#isBefore(...)、LocalDateTime#isEqual(...)

  • compareTo(...):此方法用于比较当前LocalDateTime实例和其他日期时间的大小关系。它返回一个整数,如果当前实例大于、小于或等于给定的日期时间,则返回正整数、负整数或零。这个方法通常用于排序或比较日期时间的大小。
  • isAfter(...):此方法用于检查作为参数传递的日期是否在此LocalDateTime实例之后。它返回一个布尔值,如果给定的日期时间小于当前实例,则返回false,否则返回true。这个方法通常用于判断某个日期时间是否在当前时间之后。
  • isBefore(...):此方法的功能与isAfter()相反,用于检查作为参数传递的日期是否在此LocalDateTime实例之前。返回值与isAfter()相同,如果给定的日期时间大于当前实例,则返回false,否则返回true。这个方法通常用于判断某个日期时间是否在当前时间之前。
  • isEqual(...):此方法用于检查作为参数传递的日期是否与当前LocalDateTime实例相等。它返回一个布尔值,如果两个实例的时间值完全相等,则返回true,否则返回false。这个方法通常用于比较两个日期时间是否完全相同。
@Test
public void test18() {
    LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 12, 18, 56);
    LocalDateTime localDateTime2 = LocalDateTime.of(2023, 2, 1, 12, 18, 56);
    int compareTo = localDateTime2.compareTo(localDateTime);
    System.out.println(compareTo);//输出结果:3
    boolean before = localDateTime2.isBefore(localDateTime);
    System.out.println(before);//输出结果:false
    boolean after = localDateTime2.isAfter(localDateTime);
    System.out.println(after);//输出结果:true
    boolean equal = localDateTime2.isEqual(localDateTime);
    System.out.println(equal);//输出结果:false
}

使用LocalDateTime的注意事项

在使用 LocalDateTime 时,有一些注意事项需要特别注意,了解这些限制和注意事项可以确保正确有效地使用它:

  • 时区问题:LocalDateTime 不包含时区信息,这可能会导致在处理具有时区差异的日期和时间时出现问题。
  • 精度问题:LocalDateTime 精度到秒,不包含毫秒,这可能在某些需要更高精度的情况下会限制其使用。
  • 不可变对象:LocalDateTime 是一个不可变对象,这意味着对 LocalDateTime 对象的任何修改操作都会生成一个新的实例返回,而不会改变原来的对象。这使得多线程操作中无需考虑线程安全问题,因为本身 API 层面就不支持修改。
  • 空指针异常:在使用 LocalDateTime 的 get 方法访问年、月、日等信息时,需要注意空指针异常的问题。可以使用 isPresent() 方法来检查是否存在值。
  • 日期/时间格式化:LocalDateTime 没有提供内置的格式化方法,因此在使用时需要注意格式化问题。可以使用 DateTimeFormatter 类来进行日期/时间格式化。
  • 与其它日期/时间类型的转换:在使用 LocalDateTime 时,可能需要将其与其它日期/时间类型进行转换,如 LocalDate、LocalTime、ZonedDateTime 等。在进行转换时,需要注意时区、精度等差异,以避免可能的问题。
  • 时区处理:虽然 LocalDateTime 不包含时区信息,但在某些情况下可能需要考虑时区的影响。例如,在将 LocalDateTime 转换为 ZonedDateTime 时,需要提供时区信息。
  • 时间戳的获取和比较:LocalDateTime 可以用于获取当前时间戳(以毫秒为单位)以及进行时间戳的比较。在进行时间戳比较时,需要注意时区、精度等差异。
  • 与数据库中的日期/时间类型的转换:在将 LocalDateTime 与数据库中的日期/时间类型进行转换时,需要注意数据库中日期/时间的格式和类型,以及可能的时区差异。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/198967.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

idea创建spring boot项目,java版本只能选择17和21

1.问题描述 java版本为"11.0.20"&#xff0c;idea2023创建spring boot项目时&#xff08;File->Project->Spring Initializr&#xff09;&#xff0c;java版本无法选择11&#xff0c;导致报错&#xff0c;如下图所示&#xff1a; 2.原因 spring2.X版本在2023…

类 —— 友元、常/静态成员函数

类 类的大小 和结构体大小求法一致。但需注意&#xff0c;普通空类也会占用 1 字节大小&#xff0c;因为普通空类可以实例化对象。 而 抽象空类占 4 字节&#xff08;32 位机中&#xff09;&#xff0c;因为抽象空类中含有虚指针&#xff08;含有虚函数的非抽象空类同理&am…

Vue指令之v-html

在Vue中有很多特殊的标签属性&#xff0c;这些属性一般以’v’开头&#xff0c;用于在标签中实现特殊的功能。 例如&#xff0c;当Vue实例的data是一个inner html&#xff0c;我们想在网页上渲染这部分html&#xff0c;如果依然使用之前的{{ variable }}&#xff0c;则只会将i…

排序算法:n个0~1000之间的整数,将他们从大到小排序

上榜理由&#xff1a; 如果没见过这种排序题&#xff0c;可能首先想到的就是常用的排序算法&#xff0c;比如快速排序&#xff0c;归并排序&#xff0c;那如果输入的n足够大&#xff0c;时间复杂度肯定比较高。其实题目0-1000的范围是一个题眼&#xff0c;所以一定有更优的排序…

【鸿蒙应用ArkTS开发系列】- 选择图片、文件和拍照功能实现

文章目录 前言创建多媒体Demo工程创建MediaBean 实体类创建MediaHelper工具类API标记弃用问题动态申请多媒体访问权限实现选择图片显示功能打包测试 前言 在使用App的时候&#xff0c;我们经常会在一些社交软件中聊天时发一些图片或者文件之类的多媒体文件&#xff0c;那在鸿蒙…

网络安全--基于Kali的网络扫描基础技术

文章目录 1. 标准ICMP扫描1.1使用Ping命令1.1.1格式1.1.2实战 1.2使用Nmap工具1.2.1格式1.2.2实战1.2.2.1主机在线1.2.2.2主机不在线 1.3使用Fping命令1.3.1格式1.3.2实战 2. 时间戳查询扫描2.1格式2.2实战 3. 地址掩码查询扫描3.1格式3.2实战 2. TCP扫描2.1TCP工作机制2.2TCP …

拆解按摩器:有意思的按键与LED控制电路,学习借鉴一下!

拆解 外观和配色个人感觉还行,比较青春 拉开拉链&#xff0c;拆开外面的布面&#xff0c;里面还有一层纱面 按键部分使用魔术贴固定 拆开纱面后&#xff0c;看到里面的结构&#xff0c;整体是一个海绵 可以看到如下&#xff0c;电池&#xff0c;按键板&#xff0c;充电线的三条…

【Java】文件路径-绝对路径与相对路径

1、绝对路径与相对路径 先来看一下绝对路径和相对路径的定义&#xff1a; 绝对路径是指完整的描述文件位置的路径就是绝对路径。如Windows系统中的D:\Project\data\test.txt&#xff0c;MAC系统中的/Users/liuwenwen/Desktop/Project/test.txt 相对路径是指相对于当前文件位置…

[操作系统] 面试宝典之~死锁连环系列

文章目录 2.22 什么是死锁2.24 解决死锁的方法死锁的预防死锁的避免死锁的检测死锁的解除 2.22 什么是死锁 在多道程序环境下&#xff0c;多个进程可以竞争有限数量的资源。当一个进程申请资源时&#xff0c;如果这时没有可用资源&#xff0c;那么这个进程进入等待状态。有时&…

什么是高级语言、机器语言、汇编语言?什么是编译和解释?

1、高级语言 计算机程序是一种让计算机执行特定任务的方法。程序是由程序员用一种称为编程语言的特殊语言编写的。编程语言有很多种&#xff0c;例如 C、C、Java、Python 等。这些语言被称为高级语言&#xff0c;因为它们更接近人类的自然语言&#xff0c;而不是计算机能够直接…

【数据结构 —— 二叉树的链式结构实现】

数据结构 —— 二叉树的链式结构实现 1.树的概念及其结构1.1.树概念1.2.树的结构1.3树的相关概念1.4.树的表示1.5. 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 2.二叉树的概念及其结构2.1二叉树的概念2.2.现实中的二叉树&#xff1a;2.3. 特殊的二叉树…

C++单调向量(栈):好子数组的最大分数

作者推荐 利用广度优先或模拟解决米诺骨牌 题目 给你一个整数数组 nums &#xff08;下标从 0 开始&#xff09;和一个整数 k 。 一个子数组 (i, j) 的 分数 定义为 min(nums[i], nums[i1], …, nums[j]) * (j - i 1) 。一个 好 子数组的两个端点下标需要满足 i < k <…

32+OLED之IIC手撕亚索七级狗牌

成品效果&#xff1a; 硬件配方&#xff1a;STM32F103C8T6 SSD1306 软件配方&#xff1a;字模提取V2.1 CopyLeft By Horse2000 STM32CubeMX keil5 思路&#xff1a; 1.找到图片&#xff0c;将其转化为128*64 像素大小的二值化图片&#xff1b;【python实现转化】&#xff…

配置zabbix-proxy主动式

IP地址对应关系如下&#xff1a; zabbix-server122.9.8.21zabbix-proxy122.9.4.102zabbix-agent2116.63.9.109 一、 安装zabbix-server https://blog.csdn.net/qq_50247813/article/details/132131774 二、 安装zabbix-proxy a. 安装zabbix源 rpm -Uvh https://repo.zabbix…

机器学习笔记 - 基于百度飞桨PaddleSeg的人体分割

一、简述 虽然Segment Anything用于图像分割的通用大模型看起来很酷(飞桨也提供分割一切的模型),但是个人感觉落地应用的时候心里还是更倾向于飞桨这种场景式的,因为需要用到一些人体分割的需求,所以这里主要是对飞桨高性能图像分割开发套件进行了解和使用,但是暂时不训练…

Modbus平台:协议中间件(支持Modbus TCP、RTU、ASCII)

该程序可放置外网中&#xff0c;适用于DTU长连接&#xff08;心跳包必须包含DTU&#xff0c;可以是tcp/udp&#xff09;&#xff0c;也可以在内网中&#xff0c;短连接访问设备server 支持协议&#xff1a;Modbus TCP | RTU | ASCII 连接方式&#xff1a;TcpAtive: TCP主动 | …

机器人制作开源方案 | 智能扶老助残辅助管家

作者&#xff1a;孙运通 黄善越 卢瑀 张宇峰 郑乐怡 单位&#xff1a;河海大学 指导老师&#xff1a;陆其清 人口老龄化始终是我国一个极为严峻的社会问题。独居老人和空巢老人占总人口比重日益提高&#xff1a;预计至2050年老龄人口占比将超20%&#xff0c;绝大部分城市和地…

基于单片机环境监测温湿度PM2.5系统设计

**单片机设计介绍&#xff0c;基于单片机环境监测温湿度PM2.5系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 设计一个基于单片机环境监测温湿度PM2.5的系统是一个非常有意义的项目。以下是一个基本的介绍&#xff1a; …

云原生实战课大纲<2>

我们pod的数据挂载文件可以使用 pv-pvc的方式 1. 创建pv池 2. 在pv池中创建pv&#xff0c;并且设置pv的模式 3. 编写pod 写对应的pvc 申请书 就可以了这就是我们k8s中的pv和pvc 基于pv池创建pv的时候会有容量限制呢么关于配置呢&#xff0c;我们以前会有这种场景 比如说在dock…

Android Studio导入项目一直显示正在下载Gradle项目

如题&#xff0c;问题图类似如下&#xff1a; &#xff08;此图是解决以后截的&#xff0c;之前遇到问题没截图&#xff09; 解决方法 先找到你正在下载的gradle的版本是哪个 然后在链接中 ​​​​​​Gradle Distributions 找到你所对于gradle的版本&#xff0c;下载对应…