Java Дата и час
⚡ Умно обобщение
Java Работата с дата и час комбинира наследените класове java.util.Date и SimpleDateFormat с модерния API java.time, въведен в 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 | Час в AM или PM (0-11) | 0 |
| h | Час в AM или PM (1-12) | 12 |
| m | Минута в час | 30 |
| s | Секунда в минута | 55 |
| S | Милисекунда | 978 |
| z | Часова зона (име) | Тихоокеанско стандартно време; PST; GMT-08:00 |
| Z | Часова зона (RFC 822 отместване) | -0800 |
| X | Часова зона (отместване по ISO 8601) | -08 или -0800 или -08:00 |
Не е нужно да запомняте цялата таблица. Обръщайте се към нея всеки път, когато изграждате нов модел.
Как да използвате SimpleDateFormat
SimpleDateFormat е подклас на DateFormat което ви позволява да форматирате и анализирате дати, използвайки горните букви от шаблона. Комбинирайте буквите, за да опишете точния низ, който искате да генерирате или прочетете.
Например:
- Изисква се формат на датата: 2012.10.23 г. 20:20:45 PSTПодходящият шаблон за форматиране е
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: Форматиране на дати в Modern 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. - Винаги посочвайте езикова променлива (Locale). Имената на месеците и дните се променят в зависимост от локала по подразбиране на JVM, което прави модели като
MMMнамляваEEEнепреносим. Предайте локал изрично (напримерLocale.ENGLISH). - Бъдете ясни относно часовите зони.
LocalDateTimeняма зона, така че конвертирайте вZonedDateTimeorInstantвинаги когато точният момент е от значение, особено за лог файлове, колони от база данни и мрежови полезни товари. - Внимателно конвертирайте между двата API. употреба
date.toInstant(),Date.from(instant), иcalendar.toInstant().atZone(zone)на границата между стария и съвременния код. - Съхранявайте времевите отметки в UTC. Упорствайте и transmit дати като UTC (
Instantили низ по ISO 8601) и се конвертира в потребителската зона само при показване.


