Java Дата и время
⚡ Умное резюме
Java Обработка даты и времени сочетает в себе устаревшие классы java.util.Date и SimpleDateFormat с современным API java.time, представленным в [ссылка на API]. Java 8. Предоставляя разработчикам неизменяемые, потокобезопасные типы для точной работы с календарем.

Обработка дат и времени в Java Это стандартная часть построения логики планирования, регистрации временных меток, отчетов и журналов аудита. Прежде чем писать какой-либо код, полезно знать параметры, из которых состоит дата:
- год (в двух или четырех цифрах).
- месяц (в виде двух цифр, первых трех букв названия месяца или полного названия месяца).
- даты (фактический номер дня месяца).
- день (Название дня недели на указанную дату, например, воскресенье, понедельник, вторник).
Java Предоставляет доступ ко многим другим параметрам, описывающим момент времени на временной шкале, включая эпоху, неделю в году, часовой пояс и смещение. В разделах ниже каждый из них рассматривается на примерах, готовых к использованию.
Отображение даты в Java
Java обеспечивает Date класс в java.util Этот класс хранит конкретный момент времени с точностью до миллисекунды и предлагает вспомогательные методы для вывода, сравнения и форматирования этого момента. Чтобы получить текущую дату и время, создайте экземпляр класса с помощью его конструктора по умолчанию:
import java.util.Date; class Date_Ex1 { public static void main(String args[]) { // Instantiate a Date object by invoking its constructor Date objDate = new Date(); // Display the Date and Time using toString() System.out.println(objDate.toString()); } }
Выход:
Wed Nov 29 06:36:22 UTC 2017
В примере дата выводится в формате toString по умолчанию. Чтобы отобразить тот же момент времени в другом формате, сначала нужно понять, какие символы форматирования используются. Java использует.
SimpleDateFormat: анализ и форматирование дат
SimpleDateFormat класс в java.text преобразует Date преобразует объект в форматированную строку и анализирует форматированную строку обратно в объект. DateВ ней используются буквенные шаблоны, которые соответствуют компонентам даты или времени. В таблице ниже перечислены все поддерживаемые буквы:
| Письмо | Компонент даты или времени | Пример |
|---|---|---|
| G | Обозначение эпохи | AD |
| y | Год | 2026 |
| M | Месяц в году | июль или июль или 07 |
| w | Неделя в году | 27 |
| W | Неделя в месяц | 2 |
| D | День в году | 189 |
| d | День в месяце | 10 |
| F | День недели в месяце | 2 |
| E | Название дня недели | вторник или вторник |
| u | Номер дня недели (1 = Monday, 7 = воскресенье) | 1 |
| a | маркер AM или PM | PM |
| H | Час в день (0-23) | 0 |
| k | Час в день (1-24) | 24 |
| K | Час в утра или вечера (0-11) | 0 |
| h | Час в утра или вечера (1-12) | 12 |
| m | Минута в час | 30 |
| s | Секунда в минуту | 55 |
| S | миллисекунды | 978 |
| z | Часовой пояс (название) | Тихоокеанское стандартное время; ТИХООКЕАНСКОЕ СТАНДАРТНОЕ ВРЕМЯ; GMT-08: 00 |
| Z | Часовой пояс (смещение RFC 822) | -0800 |
| X | Часовой пояс (смещение по стандарту ISO 8601) | -08 или -0800 или -08:00 |
Вам не нужно запоминать всю таблицу. Обращайтесь к ней всякий раз, когда создаете новый шаблон.
Как использовать SimpleDateFormat
SimpleDateFormat это подкласс DateFormat Это позволяет форматировать и анализировать даты, используя указанные выше буквенные шаблоны. Объедините буквы, чтобы точно описать строку, которую вы хотите получить или прочитать.
Например:
- Требуемый формат даты: 2012.10.23 20:20:45 по тихоокеанскому стандартному времениСоответствующий шаблон форматирования:
yyyy.MM.dd HH:mm:ss zzz. - Требуемый формат даты: 09:30:00 AM 23-May-2012Соответствующий шаблон форматирования:
hh:mm:ss a dd-MMM-yyyy.
Наконечник: Часы, регистр букв. Заглавные буквы. M месяц, строчными буквами m минутный. Заглавная буква. H это 24-часовые часы, строчные буквы h Это 12-часовые часы. Перепутав их, вы получите некорректный результат, который не будет отображаться автоматически.
Приведённая ниже программа выводит текущую дату дважды: один раз в формате по умолчанию, а второй раз с использованием шаблона SimpleDateFormat:
import java.text.SimpleDateFormat; import java.util.Date; class TestDates_Format { public static void main(String args[]) { // Current system date and time is assigned to objDate Date objDate = new Date(); System.out.println(objDate); // Build the target pattern and format the date String strDateFormat = "hh:mm:ss a dd-MMM-yyyy"; SimpleDateFormat objSDF = new SimpleDateFormat(strDateFormat); System.out.println(objSDF.format(objDate)); } }
Выход:
Wed Nov 29 06:31:41 UTC 2017 06:31:41 AM 29-Nov-2017
Пример сравнения дат
Самый надежный способ заказать два Date объекты — это compareTo() Этот метод возвращает отрицательное целое число, если вызывающий момент времени наступил раньше, ноль, если оба момента времени совпадают, и положительное целое число, если вызывающий момент времени наступил позже. Приведенный ниже фрагмент кода анализирует две строковые даты и выводит их относительный порядок:
import java.text.SimpleDateFormat; import java.text.ParseException; import java.util.Date; class TestDates_Compare { public static void main(String args[]) throws ParseException { SimpleDateFormat objSDF = new SimpleDateFormat("dd-MM-yyyy"); Date dt_1 = objSDF.parse("20-08-1981"); Date dt_2 = objSDF.parse("12-10-2012"); System.out.println("Date1 : " + objSDF.format(dt_1)); System.out.println("Date2 : " + objSDF.format(dt_2)); // compareTo returns > 0 when dt_1 is after dt_2 if (dt_1.compareTo(dt_2) > 0) { System.out.println("Date 1 occurs after Date 2"); } // compareTo returns < 0 when dt_1 is before dt_2 else if (dt_1.compareTo(dt_2) < 0) { System.out.println("Date 1 occurs before Date 2"); } // compareTo returns 0 when both dates are equal else { System.out.println("Both are the same date"); } } }
Выход:
Date1 : 20-08-1981 Date2 : 12-10-2012 Date 1 occurs before Date 2
Примечание: В исходном коде использовался следующий шаблон dd-mm-yyyy, Строчные буквы mm Буква обозначает минуту, а не месяц, поэтому парсер молча выдал неверное значение месяца. В приведенном выше исправлении используется верхний регистр. MM для месяца, какая буква является правильным образцом?
Java 8. Современный API для работы с датами и временем (java.time)
Java 8 ввел java.time Пакет, переработанный API, вдохновленный библиотекой Joda-Time. Новые классы являются неизменяемыми, потокобезопасными и разделяют человеческий календарь от машинной временной шкалы. Наиболее распространенные типы:
LocalDateдля даты без указания времени или часового пояса (например, день рождения).LocalTimeдля отображения времени по настенным часам без даты или часового пояса.LocalDateTimeдля даты и времени без указания часового пояса.ZonedDateTimeдля даты и времени с учетом конкретного часового пояса.OffsetDateTimeдля даты и времени со смещением UTC, но без указания именованной зоны.Instantдля метки времени машины, измеренной от начала эпохи UNIX.DurationиPeriodдля сумм, привязанных ко времени и дате.
В приведенном ниже примере с помощью современного API отображаются текущая дата, время, метка времени и часовой пояс:
import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZonedDateTime; import java.time.Instant; import java.time.ZoneId; class ModernDateDemo { public static void main(String args[]) { LocalDate today = LocalDate.now(); LocalDateTime now = LocalDateTime.now(); ZonedDateTime zoned = ZonedDateTime.now(ZoneId.of("Asia/Kolkata")); Instant epoch = Instant.now(); System.out.println("LocalDate : " + today); System.out.println("LocalDateTime : " + now); System.out.println("ZonedDateTime : " + zoned); System.out.println("Instant : " + epoch); } }
Для каждого типа существуют свои заводские методы (now, of, parse) и неизменяемые операции (plusDays, minusHours, withYear) которые возвращают новое значение вместо изменения исходного объекта.
DateTimeFormatter: Форматирование дат в современном формате Java
DateTimeFormatter in java.time.format заменяет SimpleDateFormatОн использует тот же стиль буквенных шаблонов, является неизменяемым и безопасен для совместного использования в разных потоках без дополнительной синхронизации. Класс также предоставляет готовые константы, такие как ISO_LOCAL_DATE и ISO_ZONED_DATE_TIME для стандартных форматов.
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; class FormatterDemo { public static void main(String args[]) { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter iso = DateTimeFormatter.ISO_LOCAL_DATE_TIME; DateTimeFormatter human = DateTimeFormatter.ofPattern("hh:mm:ss a dd-MMM-yyyy"); System.out.println(now.format(iso)); System.out.println(now.format(human)); LocalDateTime parsed = LocalDateTime.parse("2026-07-04T09:30:00", iso); System.out.println("Parsed back : " + parsed); } }
Для сравнения двух дат в современном API вызовите isBefore, isAfter или isEqualЭти методы читаются понятнее, чем... compareTo и работать со всеми java.time класса.
Безопасность резьбовых соединений и лучшие практики для Java Дата и время
Оба формата java.util.Date и SimpleDateFormat предшествовали современному периоду JavaИ у каждого из них есть свои известные недостатки. Следуйте приведенным ниже рекомендациям, чтобы обеспечить корректную обработку дат в рабочем коде:
- Предпочтительнее использовать `java.time` вместо `Date` и `Calendar`. Новые типы данных являются неизменяемыми и потокобезопасными, а также более точно моделируют предметную область (даты без времени, время без зон и т. д.).
- Не используйте один и тот же SimpleDateFormat в разных потоках. Этот класс хранит внутреннее состояние парсинга и не является потокобезопасным. Оберните его в
ThreadLocalсинхронизировать на экземпляре или переключиться наDateTimeFormatter. - Всегда указывайте локаль. Названия месяцев и дней меняются в зависимости от локали JVM по умолчанию, что приводит к таким закономерностям, как...
MMMиEEEНепереносимый. Укажите локаль явно (например,Locale.ENGLISH). - Укажите часовые пояса четко.
LocalDateTimeзона отсутствует, поэтому преобразуйте вZonedDateTimeorInstantВ тот момент, когда важен точный момент, особенно для логов, столбцов баз данных и сетевых данных. - При преобразовании между двумя API следует проявлять осторожность. Используйте
date.toInstant(),Date.from(instant)иcalendar.toInstant().atZone(zone)на границе между устаревшим и современным кодом. - Сохраняйте метки времени в формате UTC. Упорствовать и transmit даты в формате UTC (an
Instantили строку ISO 8601) и преобразовывать в пользовательскую зону только при отображении.


