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

news2024/11/24 23:54:35

 

阅读建议

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

  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 与数据库中的日期/时间类型进行转换时,需要注意数据库中日期/时间的格式和类型,以及可能的时区差异。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

离散数学-集合论基础

3.1集合的基本概念 1&#xff09;集合及元素 2&#xff09;集合的表示 3&#xff09;集合的关系 4&#xff09;特殊集合 3.2集合的运算 并、交、差、对称差 3.3集合的划分与覆盖 3.4排斥包含管理 3.1集合的基本概念 1&#xff09;集合及元素 将某种具有同种属性的个体…

记录Windows下安装redis的过程

开源博客项目Blog支持使用EasyCaching组件操作redis等缓存数据库&#xff0c;在继续学习开源博客项目Blog之前&#xff0c;准备先学习redis和EasyCaching组件的基本用法&#xff0c;本文记录在Windows下安装redis的过程。   虽然redis官网文档写着支持Linux、macOS、Windows等…

pyecharts绘制自定义点+连线取消箭头+时间帧叠加

pyecharts之Geo地图大法&#xff08;详解&#xff0c;代码带注释效果图&#xff09; 近期项目上有地图自定义绘点连线分严重等级的需求&#xff0c;整了&#xff0c;分开处理啥都好说&#xff0c;多个数据放在同一维度的时候&#xff0c;只恨pyecharts的开发者为什么把功能整得…

简介vue

目录 一、介绍 渐进式框架​ 单文件组件​ 选项式 API (Options API)​ 组合式 API (Composition API)​ 该选哪一个&#xff1f;​ 创建一个 Vue 应用 应用实例​ 根组件​ DOM 中的根组件模板 应用配置​ 多个应用实例​ 一、介绍 Vue (发音为 /vjuː/&#xff…

Selenium 学习(0.17)——软件测试之测试用例设计方法——白盒测试——逻辑覆盖法(条件覆盖和条件判定覆盖)

条件覆盖 设计测试用例&#xff0c;使每个判断中每个条件的可能取值至少满足一次。 条件判定覆盖 通过设计足够的测试用例&#xff0c;满足如下条件&#xff1a; 所有条件的可能至少执行一次的取值 所有判断的可能结果至少执行一次 条件判定覆盖同时满足判定覆…

灰度发布专题---3、Nginx+Lua灰度发布

上一章已经讲解了配置文件灰度发布、应用版本灰度发布、API网关灰度发布实现&#xff0c;但如果用户这时候在代理层如何做灰度发布呢&#xff1f; 代理层灰度发布分析 用户无论访问应用服务还是静态页&#xff0c;都要经过Nginx代理层&#xff0c;我们可以在Nginx这里做灰度发…

读像火箭科学家一样思考笔记12_实践与测试(下)

1. 舆论的火箭科学 1.1. 如果苹果违反了“即飞即测”原则&#xff0c;那苹果的iPhone就不会问世了 1.1.1. iPhone在其上市前的民意调查中相当失败 1.1.1.1. iPhone不可能获得太大市场份额&#xff0c;不可能。 1.1.1.1.1. 微软前CEO史蒂夫鲍尔默&#xff08;Steve Ballmer&…

AIGC系列之:GroundingDNIO原理解读及在Stable Diffusion中使用

目录 1.前言 2.方法概括 3.算法介绍 3.1图像-文本特征提取与增强 3.2基于文本引导的目标检测 3.3跨模态解码器 3.4文本prompt特征提取 4.应用场景 4.1结合生成模型完成目标区域生成 4.2结合stable diffusion完成图像编辑 4.3结合分割模型完成任意图像分割 1.前言 …

第20章 多线程

创建线程 继承Thread 类 Thread 类时 java.lang 包中的一个类&#xff0c;从类中实例化的对象代表线程&#xff0c;程序员启动一个新线程需要建立 Thread 实例。 Thread 对象需要一个任务来执行&#xff0c;任务是指线程在启动时执行的工作&#xff0c;start() 方法启动线程…

第一百八十二回 自定义一个可以滑动的刻度尺

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法3. 示例代码4. 内容总结我们在上一章回中介绍了"如何绘制阴影效果"相关的内容,本章回中将介绍 如何自定义一个可以滑动的刻度尺.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 任何优美的文字在图…

[SaaS] 广告创意中stable-diffusion的应用

深度对谈&#xff1a;广告创意领域中 AIGC 的应用这个领域非常快速发展&#xff0c;所以你应该保持好奇心&#xff0c;不断尝试新事物&#xff0c;不断挑战自己。https://mp.weixin.qq.com/s/ux9iEABNois3y4wwyaDzAQ我对AIGC领域应用调研&#xff0c;除了MaaS服务之外&#xff…

电荷泵升压/降压电路

一、升压\降压电路原理分析 1、升压电路 电荷泵升压电路 VoutVa5V 5V_PLUS0V时&#xff0c;Va给C2充电&#xff0c;C2上节点电压比C2下节点电压高Va&#xff1b; 5V_PLUS5V时&#xff0c;C2电压不能突变&#xff0c;C2上节点电压依然比C2下节点电压高Va&#xff0c;但C2下节点…

supermap-iserver激活教程(linux)

本篇只介绍linux临时许可激活教程&#xff0c;windows的原理一摸一样不做赘述。 1.下载许可中心&#xff08;web版&#xff09; SuperMap技术资源中心|为您提供全面的在线技术服务 2.解压 supermap-bslicense-server-3.0.24-linux-x64.tar.gz tar -zxvf supermap-bslicense…

选择排序以及改进方案

选择排序以及改进方案 介绍&#xff1a; 选择排序是一种简单直观的排序算法&#xff0c;它的基本思想是在未排序序列中选择最小&#xff08;或最大&#xff09;的元素&#xff0c;然后将其放在已排序序列的末尾。选择排序的过程就像是每次从待排序的元素中选择最小的一个&…

Java基于ssm的租房求租网站房东直租中介托管房屋出租项目源码

演示视频 https://www.bilibili.com/video/BV1Lh411J7ic/?share_sourcecopy_web&vd_source11344bb73ef9b33550b8202d07ae139b 可转成springboot项目。 主要功能&#xff1a;租户可以浏览搜索收藏房源&#xff0c;预约看房&#xff0c;发布求租信息。房东可以发布管理房源…

2023-11-28-直播单细胞图表美化-seurat数据结构 featureplot dotplot vlnplot

单细胞常见的可视化方式有DimPlot&#xff0c;FeaturePlot &#xff0c;DotPlot &#xff0c;VlnPlot 和 DoHeatmap几种 &#xff0c;Seurat中均可以很简单的实现&#xff0c;但是文献中的图大多会精美很多。 之前 跟SCI学umap图| ggplot2 绘制umap图&#xff0c;坐标位置 &am…

SSL证书实惠品牌——JoySSL

随着互联网的普及和发展&#xff0c;网络安全问题日益严重。为了保护网站数据的安全&#xff0c;越来越多的网站开始使用SSL证书。JoySSL证书作为一款高性价比的SSL证书&#xff0c;受到了广泛的关注和好评。 目前市面上主流的证书基本上都是国外证书&#xff0c;也就是说你在验…

【用unity实现100个游戏之17】从零开始制作一个类幸存者肉鸽(Roguelike)游戏4(附项目源码)

文章目录 本节最终效果前言命中敌人闪白和击退效果敌人死亡效果等级 击杀数 经验绘制经验条显示等级和杀敌数游戏倒计时玩家血条参考源码完结 本节最终效果 前言 本节紧跟着上一篇&#xff0c;主要实现敌人受击死亡效果特效&#xff0c;主角等级、击杀数、经验、血条UI显示。 …

C# datagridview控件 绑定数据库中表中数据的方式-3

1.如下图所示&#xff0c;为数据库中的一张表结构&#xff0c;注意该表中共有11个字段 2.首先在窗体后台代码中拖入一个datagridview控件&#xff0c;并在窗体加载时&#xff0c;给datagridview控件添加列&#xff0c;添加的方式如下所示&#xff1a;请注意&#xff0c;每个列…

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

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