Выброси Date и забудь Calendar Если ты работал с java.util.Date или Calendar, то сталкивался с этими проблемами. Мутабельные объекты, месяцы с нуля, запутанный API. В Java 8 появился java.time (JSR-310), и это то, что должно было быть с самого начала.
🔹 Instant — source of truthInstant now = Instant.now(); // 2024-01-15T19:00:00Z// Из Unix timestampInstant fromSeconds = Instant.ofEpochSecond(1705341600L);// Получить timestamplong epochMilli = now.toEpochMilli();// АрифметикаInstant later = now.plusSeconds(3600); // +1 час// Наносекундная точность (не то что Date с миллисекундами)long nanos = now.getNano();
Храни в БД именно Instant. Никакой TZ-зависимости и никаких сюрпризов.
🔹 LocalDateTime, когда TZ не нужнаLocalDateTime dt = LocalDateTime.of(2024, 1, 15, 19, 0, 0);LocalDateTime parsed = LocalDateTime.parse("2024-01-15T19:00:00");// ✅ Юзер ввёл дату без TZ// ✅ Бизнес-логика без мультирегиональности// ❌ Хранение в БД — используй Instant// ❌ API-ответы — неоднозначно без TZ
🔹 ZonedDateTime для пользователейZonedDateTime ny = ZonedDateTime.now(ZoneId.of("America/New_York"));ZonedDateTime tokyo = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));// Конвертация между TZ — один и тот же момент времениZonedDateTime london = ny.withZoneSameInstant(ZoneId.of("Europe/London"));
DST обрабатывается автоматически:
// 10 марта 2:30 AM не существует (переход на летнее время)LocalDateTime nonExistent = LocalDateTime.of(2024, 3, 10, 2, 30);ZonedDateTime adjusted = nonExistent.atZone(ZoneId.of("America/New_York"));// → автоматически станет 3:30 AM EDT
🔹 ZonedDateTime vs OffsetDateTime// ZonedDateTime — знает правила DST, для будущих датZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("America/New_York"));// OffsetDateTime — просто смещение, без DST. Для прошлых событий и APIOffsetDateTime odt = OffsetDateTime.now(ZoneOffset.ofHours(-5));
🔹 DateTimeFormatter для форматирования и парсингаLocalDateTime dt = LocalDateTime.of(2024, 1, 15, 19, 0, 0);// Predefineddt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); // "2024-01-15T19:00:00"dt.format(DateTimeFormatter.BASIC_ISO_DATE); // "20240115"// CustomDateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");dt.format(fmt); // "2024-01-15 19:00:00"// Парсинг с обработкой ошибокpublic static Optional<LocalDateTime> parse(String s) { try { return Optional.of(LocalDateTime.parse(s, fmt)); } catch (DateTimeParseException e) { return Optional.empty(); }}
🔹 Шпаргалка по токенамyyyy → 2024 MM → 01 dd → 15HH → 19 (24h) hh → 07 (12h) mm → 00ss → 00 SSS → 123 a → PMz → EST Z → -0500 VV → America/New_York
🔹 Duration vs Period // Duration — точный временной интервалDuration duration = Duration.ofHours(24); // ровно 86400 секунд// Period — календарный интервалPeriod period = Period.ofDays(1); // 1 день (может быть 23 или 25 ч. при DST!)// Оба работают с LocalDateTime, но семантика разная:dt.plus(Duration.ofHours(24)); // +86400 секdt.plus(Period.ofDays(1)); // +1 календарный день
🔹 Миграция с легаси// Date → InstantInstant instant = oldDate.toInstant();// Instant → DateDate date = Date.from(instant);// Date → LocalDateTimeLocalDateTime ldt = oldDate.toInstant() .atZone(ZoneId.systemDefault()) .toLocalDateTime();
══════ Навигация ══════Вакансии • Задачи • Собесы
Библиотека джависта #Enterprise