Java 日期与时间高级处理:从基础到专业
\n\n日期与时间处理是任何企业级应用的核心任务之一。在 Java 中,长期以来标准是笨重的 java.util.Date 和 java.util.Calendar,但随着 Java 8 的发布,情况发生了根本性变化。新的 java.time API(JSR-310)为开发者提供了强大、线程安全且直观的工具集。在本文中,我们将深入探讨每位 Java 开发者都会用到的高级日期与时间处理技术。
1. java.time API 基础:LocalDate, LocalTime, LocalDateTime
\n\n迈向专业处理的第一步是理解取代旧有类的三个基本类:
\n\n- \n
- LocalDate — 不含时间的日期(年、月、日)。 \n
- LocalTime — 不含日期的时间(时、分、秒、纳秒)。 \n
- LocalDateTime — 日期与时间的组合,不绑定时区。 \n
// 获取当前日期和时间\nLocalDate today = LocalDate.now(); // 2025-03-21\nLocalTime now = LocalTime.now(); // 14:30:15.123\nLocalDateTime current = LocalDateTime.now(); // 2025-03-21T14:30:15.123\n\n// 创建特定日期\nLocalDate birthDate = LocalDate.of(1990, Month.JUNE, 15);\nLocalTime meetingTime = LocalTime.of(10, 30, 0);\n\n// 日期操作\nLocalDate nextWeek = today.plusWeeks(1);\nLocalDate lastMonth = today.minusMonths(1);\n\n这些类是不可变的——任何操作都会返回一个新对象。这保证了线程安全和代码的可预测性。
\n\n2. 时区处理:ZonedDateTime 和 ZoneId
\n\n全球性应用不能忽视时区。为此,java.time 提供了 ZonedDateTime 类。
// 当前 UTC 时间\nZonedDateTime utcNow = ZonedDateTime.now(ZoneOffset.UTC);\n\n// 特定时区的时间\nZoneId moscowZone = ZoneId.of("Europe/Moscow");\nZonedDateTime moscowTime = ZonedDateTime.now(moscowZone);\n\n// 时区转换\nZonedDateTime nyTime = moscowTime.withZoneSameInstant(ZoneId.of("America/New_York"));\n\n// 获取偏移量\nZoneOffset offset = moscowTime.getOffset(); // +03:00\n\n专业建议:始终在服务器端以 UTC 存储日期,仅在表示层(UI)转换为本地时区。这将避免夏令时/冬令时切换带来的问题。
\n\n3. 日期解析与格式化:DateTimeFormatter
\n\n最常见的任务之一是将字符串转换为日期,反之亦然。DateTimeFormatter 提供了灵活的功能。
基本格式化
\n\nDateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");\nLocalDateTime dateTime = LocalDateTime.parse("21.03.2025 14:30:00", formatter);\nString formatted = dateTime.format(formatter); // "21.03.2025 14:30:00"\n\n高级模板
\n\n// ISO-8601\nDateTimeFormatter isoFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;\nString isoDate = dateTime.format(isoFormatter); // "2025-03-21T14:30:00"\n\n// 本地化格式化\nDateTimeFormatter italianFormatter = DateTimeFormatter.ofPattern("d MMMM yyyy", Locale.ITALY);\nString italianDate = dateTime.format(italianFormatter); // "21 marzo 2025"\n\n// 自定义格式,包含文本字段\nDateTimeFormatter customFormatter = new DateTimeFormatterBuilder()\n .appendValue(ChronoField.YEAR)\n .appendLiteral(" 年, ")\n .appendText(ChronoField.MONTH_OF_YEAR, TextStyle.FULL)\n .appendLiteral(" ")\n .appendValue(ChronoField.DAY_OF_MONTH)\n .toFormatter();\nString custom = dateTime.format(customFormatter); // "2025 年, 三月 21"\n\n重要提示:DateTimeFormatter 也是线程安全的,可以安全地在多个线程之间共享。