Java ChronoField 枚举
最后修改时间:2025 年 4 月 16 日
java.time.temporal.ChronoField
枚举实现了 TemporalField
接口,代表日期和时间的标准字段。它提供了诸如年、月、日、小时、分钟和秒之类的单位。每个字段都有一个有效值的范围。
ChronoField
用于像 LocalDate
、LocalTime
和 ZonedDateTime
这样的时间对象。它允许访问日期时间对象的特定组件。枚举包含与日期和时间相关的字段。
ChronoField 枚举概述
ChronoField
提供了所有标准日期时间字段的常量。每个字段都有获取其范围和基本单位的方法。该枚举实现了 TemporalField
接口,用于时间访问和调整。
public enum ChronoField implements TemporalField { NANO_OF_SECOND, NANO_OF_DAY, MICRO_OF_SECOND, MICRO_OF_DAY, MILLI_OF_SECOND, MILLI_OF_DAY, SECOND_OF_MINUTE, SECOND_OF_DAY, MINUTE_OF_HOUR, MINUTE_OF_DAY, HOUR_OF_AMPM, HOUR_OF_DAY, AMPM_OF_DAY, DAY_OF_WEEK, DAY_OF_MONTH, DAY_OF_YEAR, EPOCH_DAY, ALIGNED_WEEK_OF_MONTH, ALIGNED_WEEK_OF_YEAR, ALIGNED_DAY_OF_WEEK_IN_MONTH, ALIGNED_DAY_OF_WEEK_IN_YEAR, MONTH_OF_YEAR, PROLEPTIC_MONTH, YEAR_OF_ERA, YEAR, ERA, INSTANT_SECONDS, OFFSET_SECONDS; // Methods public ValueRange range(); public boolean isDateBased(); public boolean isTimeBased(); public TemporalUnit getBaseUnit(); public TemporalUnit getRangeUnit(); }
以上代码显示了枚举常量和关键方法。字段分为基于日期或基于时间。每个字段都有一个定义的有效值范围,可通过 range()
方法访问。
访问日期组件
ChronoField
可以提取日期组件,如年、月和日。基于日期的字段与包含日期信息的时间对象一起使用。该示例显示了常见的日期字段操作。
package com.zetcode; import java.time.LocalDate; import java.time.temporal.ChronoField; public class Main { public static void main(String[] args) { LocalDate date = LocalDate.of(2025, 4, 15); // Get year int year = date.get(ChronoField.YEAR); System.out.println("Year: " + year); // Get month int month = date.get(ChronoField.MONTH_OF_YEAR); System.out.println("Month: " + month); // Get day of month int day = date.get(ChronoField.DAY_OF_MONTH); System.out.println("Day: " + day); // Get day of year int dayOfYear = date.get(ChronoField.DAY_OF_YEAR); System.out.println("Day of year: " + dayOfYear); // Check if field is supported boolean supported = date.isSupported(ChronoField.ERA); System.out.println("ERA supported: " + supported); } }
此示例演示了如何使用 ChronoField
访问日期组件。get()
方法从时间对象中检索字段值。isSupported()
检查某个字段是否适用于时间类型。
访问时间组件
基于时间的字段提供对小时、分钟、秒和纳秒值的访问。这些字段与包含时间信息的时间对象一起使用。该示例显示了常见的时间字段操作。
package com.zetcode; import java.time.LocalTime; import java.time.temporal.ChronoField; public class Main { public static void main(String[] args) { LocalTime time = LocalTime.of(14, 30, 45, 500_000); // Get hour int hour = time.get(ChronoField.HOUR_OF_DAY); System.out.println("Hour: " + hour); // Get minute int minute = time.get(ChronoField.MINUTE_OF_HOUR); System.out.println("Minute: " + minute); // Get second int second = time.get(ChronoField.SECOND_OF_MINUTE); System.out.println("Second: " + second); // Get nano int nano = time.get(ChronoField.NANO_OF_SECOND); System.out.println("Nanosecond: " + nano); // Check AM/PM int ampm = time.get(ChronoField.AMPM_OF_DAY); System.out.println("AMPM: " + (ampm == 0 ? "AM" : "PM")); } }
此示例展示了如何使用 ChronoField
访问时间组件。HOUR_OF_DAY
提供 24 小时制,而 AMPM_OF_DAY
区分上午和下午。所有时间字段都有定义的范围。
使用日期时间对象
ChronoField
与完整的日期时间对象(如 LocalDateTime
和 ZonedDateTime
)一起使用。可以从这些对象访问日期和时间字段。
package com.zetcode; import java.time.LocalDateTime; import java.time.ZonedDateTime; import java.time.temporal.ChronoField; public class Main { public static void main(String[] args) { LocalDateTime ldt = LocalDateTime.now(); System.out.println("Current date-time: " + ldt); // Get combined fields int year = ldt.get(ChronoField.YEAR); int hour = ldt.get(ChronoField.HOUR_OF_DAY); System.out.printf("Year: %d, Hour: %d%n", year, hour); ZonedDateTime zdt = ZonedDateTime.now(); System.out.println("Zoned date-time: " + zdt); // Get day of week (1-7) int dow = zdt.get(ChronoField.DAY_OF_WEEK); System.out.println("Day of week: " + dow); // Get epoch day long epochDay = zdt.getLong(ChronoField.EPOCH_DAY); System.out.println("Epoch day: " + epochDay); } }
此示例演示了如何将 ChronoField
与日期时间对象一起使用。可以从同一对象访问日期和时间字段。某些字段(如 EPOCH_DAY
)返回 long 值而不是整数。
字段验证和范围
每个 ChronoField
都有定义的有效值范围。可以在访问字段之前检查这些范围。range()
方法提供最小值和最大值。
package com.zetcode; import java.time.LocalDate; import java.time.temporal.ChronoField; import java.time.temporal.ValueRange; public class Main { public static void main(String[] args) { // Get range for day of month ValueRange dayRange = ChronoField.DAY_OF_MONTH.range(); System.out.println("Day of month range: " + dayRange); // Get range for month ValueRange monthRange = ChronoField.MONTH_OF_YEAR.range(); System.out.println("Month range: " + monthRange); // Check if value is valid LocalDate date = LocalDate.of(2025, 2, 1); boolean valid = date.isSupported(ChronoField.DAY_OF_MONTH) && date.range(ChronoField.DAY_OF_MONTH).isValidValue(30); System.out.println("Is 30 valid for February: " + valid); // Check hour range ValueRange hourRange = ChronoField.HOUR_OF_DAY.range(); System.out.println("Hour range: " + hourRange); } }
此示例展示了如何使用字段范围和验证。range()
方法返回最小和最大的有效值。isValidValue()
检查特定值对于该字段是否有效。
调整时间对象
ChronoField
可用于调整时间对象。with()
方法创建一个带有修改字段的新对象。这对于日期时间操作很有用。
package com.zetcode; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoField; public class Main { public static void main(String[] args) { LocalDate date = LocalDate.of(2025, 4, 15); System.out.println("Original date: " + date); // Change year LocalDate newYear = date.with(ChronoField.YEAR, 2026); System.out.println("New year: " + newYear); // Change month LocalDate newMonth = date.with(ChronoField.MONTH_OF_YEAR, 12); System.out.println("New month: " + newMonth); LocalDateTime dateTime = LocalDateTime.now(); System.out.println("Original date-time: " + dateTime); // Change hour LocalDateTime newHour = dateTime.with(ChronoField.HOUR_OF_DAY, 23); System.out.println("New hour: " + newHour); // Change minute LocalDateTime newMinute = dateTime.with(ChronoField.MINUTE_OF_HOUR, 0); System.out.println("New minute: " + newMinute); } }
此示例演示了如何使用 ChronoField
调整时间对象。with()
方法返回一个新对象,其中指定的字段已更改。原始对象保持不可变,这符合 Java Time API 的设计。
特殊字段和转换
ChronoField
包括用于转换的特殊字段,如 EPOCH_DAY
和 INSTANT_SECONDS
。这些字段允许使用不同的时间表示方式。
package com.zetcode; import java.time.Instant; import java.time.LocalDate; import java.time.ZonedDateTime; import java.time.temporal.ChronoField; public class Main { public static void main(String[] args) { // EPOCH_DAY example LocalDate date = LocalDate.of(2025, 1, 1); long epochDay = date.getLong(ChronoField.EPOCH_DAY); System.out.println("Epoch day: " + epochDay); // Convert back from epoch day LocalDate fromEpoch = LocalDate.ofEpochDay(epochDay); System.out.println("From epoch day: " + fromEpoch); // INSTANT_SECONDS example ZonedDateTime zdt = ZonedDateTime.now(); long instantSeconds = zdt.getLong(ChronoField.INSTANT_SECONDS); System.out.println("Instant seconds: " + instantSeconds); // Convert back from instant seconds Instant instant = Instant.ofEpochSecond(instantSeconds); System.out.println("From instant seconds: " + instant); } }
此示例显示了用于时间转换的特殊字段。EPOCH_DAY
表示自 1970-01-01 以来的天数,而 INSTANT_SECONDS
表示自同一纪元以来的秒数。这些字段允许在不同的时间表示之间进行互操作。
来源
在本文中,我们介绍了 Java ChronoField 枚举的基本字段和特性。理解这些概念对于在 Java 应用程序中使用日期和时间组件至关重要。
作者
列出所有Java教程。