Вопрос-ответ

How to get the current date/time in Java [duplicate]

Как получить текущую дату / время в Java

Какой наилучший способ получить текущую дату / время в Java?

Переведено автоматически
Ответ 1

Какой наилучший способ получить текущую дату / время в Java?


"Лучшего" способа не существует.

Это зависит от того, какую форму даты / времени вы хотите:


  • Если вы хотите получить дату / время в виде единственного числового значения, то System.currentTimeMillis() дает вам это значение, выраженное в количестве миллисекунд после эпохи UNIX (как Java long). Это значение является разницей от временной точки UTC и не зависит от местного часового пояса1.



  • Если вам нужна дата / время в форме, позволяющей получить доступ к компонентам (год, месяц и т.д.) численно, вы могли бы использовать одно из следующих действий:



    • new Date() предоставляет вам Date объект, инициализированный текущей датой / временем. Проблема в том, что Date методы API в основном некорректны ... и устарели.



    • Calendar.getInstance() предоставляет вам Calendar объект, инициализированный текущей датой / временем, используя значения по умолчанию Locale и TimeZone. Другие перегрузки позволяют использовать определенное Locale и / или TimeZone. Календарь работает ... но API по-прежнему громоздки.



    • new org.joda.time.DateTime() предоставляет вам объект Joda-time, инициализированный текущей датой / временем, используя часовой пояс и хронологию по умолчанию. Существует множество других альтернатив Joda ... слишком много, чтобы описывать здесь. (Но обратите внимание, что некоторые люди сообщают, что у Joda time проблемы с производительностью.; например, https://javalang.ru/questions/6280829.)



    • в Java 8 вызов java.time.LocalDateTime.now() и java.time.ZonedDateTime.now() даст вам представления2 для текущей даты / времени.





До появления Java 8 большинство людей, которые знают об этих вещах, рекомендовали Joda-time как имеющие (на сегодняшний день) лучшие Java API для выполнения операций, связанных с вычислением временных точек и длительности.

Для Java 8 и более поздних версий рекомендуется использовать стандартный java.time пакет. Joda time теперь считается "устаревшим", и разработчики Joda рекомендуют пользователям перенести3.


Примечание: решения Calendar, org.joda.time и java.time могут использовать либо часовой пояс платформы по умолчанию, либо явный часовой пояс, предоставляемый через аргументы конструктора. Как правило, использование явного часового пояса вместо зоны по умолчанию сделает поведение вашего приложения более предсказуемым / менее подверженным проблемам, если (например) вы повторно выполняете развертывание в центре обработки данных в другом часовом поясе.

Но что бы вы ни делали, вы (и, возможно, ваше приложение) должны знать, что часовой пояс пользователя, вашей службы и центра обработки данных могут отличаться. Концепция "текущей даты / времени" сложна.


1 - System.currentTimeMillis() задает "системное" время. Хотя обычно системные часы устанавливаются на (номинальный) UTC, будет разница (дельта) между локальными часами UTC и истинным UTC. Размер дельты зависит от того, насколько хорошо (и как часто) системные часы синхронизированы с UTC.
2 - Обратите внимание, что LocalDateTime не включает часовой пояс. Как сказано в javadoc: "Он не может представлять момент в строке времени без дополнительной информации, такой как смещение или часовой пояс".
3 - Примечание: ваш код Java 8 не сломается, если вы не выполните миграцию, но кодовая база Joda может в конечном итоге перестать получать исправления ошибок и другие исправления. По состоянию на 2020-02 официальный "конец срока службы" для Joda не был объявлен, и API-интерфейсы Joda не были помечены как устаревшие.

Ответ 2

(Внимание: только для использования с версиями Java <8. Для Java 8+ проверьте другие ответы.)

Если вам просто нужно вывести временную метку в формате ГГГГ.ММ.ДД-ЧЧ.ММ.СС (очень частый случай), то вот способ это сделать:

String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());
Ответ 3

Если вам нужна текущая дата в виде строки, попробуйте это:

DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
System.out.println(dateFormat.format(date));

или

DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Calendar cal = Calendar.getInstance();
System.out.println(dateFormat.format(cal.getTime()));

http://www.mkyong.com/java/java-how-to-get-current-date-time-date-and-calender/

Ответ 4

tl; dr

Instant.now()                         // Capture the current moment in UTC, with a resolution of nanoseconds. Returns a `Instant` object.

... или …

ZonedDateTime.now(                    // Capture the current moment as seen in…
ZoneId.of( "America/Montreal" ) // … the wall-clock time used by the people of a particular region (a time zone).
) // Returns a `ZonedDateTime` object.

java.time

В нескольких ответах упоминается, что классы java.time являются современной заменой устаревших устаревших классов даты и времени, поставляемых в комплекте с самыми ранними версиями Java. Ниже приведено немного больше информации.

введите описание изображения здесь

Часовой пояс

В других ответах не объясняется, насколько часовой пояс важен для определения текущей даты и времени. Для любого данного момента дата и время различаются по всему миру в зависимости от зоны. Например, через несколько минут после полуночи в Париже, Франция, наступает новый день, в то время как в Монреале-Квебеке он все еще “вчерашний”.

Instant

Большая часть вашей бизнес-логики и хранения / обмена данными должна выполняться в UTC, как наилучшая практика.

Чтобы получить текущий момент в UTC с разрешением в наносекундах, используйте Instant class . Точность обычных компьютерных аппаратных часов ограничена, поэтому текущий момент может быть зафиксирован в миллисекундах или микросекундах, а не в наносекундах.

Instant instant = Instant.now();

ZonedDateTime

Вы можете настроить это Instant для других часовых поясов. Примените ZoneId объект, чтобы получить ZonedDateTime.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

Мы можем пропустить Instant и получить текущее ZonedDateTime напрямую.

ZonedDateTime zdt = ZonedDateTime.now( z );

Всегда передавайте этот необязательный аргумент часового пояса. Если он опущен, применяется текущий часовой пояс вашей JVM по умолчанию. Значение по умолчанию может измениться в любой момент, даже во время выполнения. Не подвергайте свое приложение внешним воздействиям, находящимся вне вашего контроля. Всегда указывайте желаемый / ожидаемый часовой пояс.

ZonedDateTime do_Not_Do_This = ZonedDateTime.now(); // BAD - Never rely implicitly on the current default time zone.

Позже вы можете извлечь Instant из ZonedDateTime.

Instant instant = zdt.toInstant();

Всегда используйте Instant или ZonedDateTime вместо LocalDateTime, когда вам нужен актуальный момент на временной шкале. В Local… типах намеренно нет понятия часового пояса, поэтому они представляют лишь приблизительное представление о возможном моменте. Чтобы получить актуальный момент, вы должны назначить часовой пояс, чтобы преобразовать Local… типы в ZonedDateTime и тем самым придать им смысл.

LocalDate

Класс LocalDate представляет значение только для даты без указания времени суток и часового пояса.

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z ); // Always pass a time zone.

Строки

Чтобы сгенерировать строку, представляющую значение даты/времени, просто вызовите toString классы java.time для стандартных форматов ISO 8601.

String output = myLocalDate.toString();  // 2016-09-23

... или …

String output = zdt.toString();  // 2016-09-23T12:34:56.789+03:00[America/Montreal]

Класс ZonedDateTime расширяет стандартный формат, мудро добавляя название часового пояса в квадратных скобках.

Для получения других форматов выполните поиск в Stack Overflow по многим вопросам и ответам в DateTimeFormatter классе.

Избегайте LocalDateTime

Вопреки комментарию RamanSB к вопросу, вам не следует не использовать LocalDateTime class для текущей даты-времени.

В LocalDateTime намеренно отсутствует информация о часовом поясе или смещении от UTC. Таким образом, это не подходит, когда вы отслеживаете определенный момент на временной шкале. Конечно, не подходит для фиксации текущего момента.

A LocalDateTime содержит только дату и время суток, например "полдень 23 января 2020 года", но мы понятия не имеем, полдень ли это в Токио, Япония, или полдень в Толедо, Огайо, США, два разных момента с разницей в много часов.

Формулировка “Local” противоречит интуиции. Это означает любой населенный пункт, а не какую-то одну конкретную местность. Например, Рождество в этом году начинается в полночь 25 декабря: 2017-12-25T00:00:00, чтобы быть представленным как LocalDateTime. Но это означает полночь в разных точках земного шара в разное время. Полночь наступает сначала на Кирибати, позже в Новой Зеландии, еще на несколько часов позже в Индии и так далее, и проходит еще несколько часов до начала Рождества во Франции, когда дети в Канаде все еще ждут этого дня. Каждая из этих точек начала Рождества будет представлена как отдельная ZonedDateTime.


Извне вашей системы

Если вы не можете доверять своим системным часам, см. Java: получение текущей даты и времени с сервера, а не с системных часов и мой ответ.

фото пары внешних устройств с радиочасами

java.time.Clock

Чтобы использовать альтернативного поставщика текущего момента, напишите подкласс абстрактного java.time.Clock класса.

Вы можете передать свою Clock реализацию в качестве аргумента различным методам java.time. Например, Instant.now( clock ).

Instant instant = Instant.now( yourClockGoesHere ) ;

В целях тестирования обратите внимание на альтернативные реализации, Clock доступные статически из Clock самого: fixed, offset, tick и другие.


О java.time

Платформа java.time встроена в Java 8 и более поздних версий. Эти классы заменяют старые, вызывающие беспокойство, устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

Чтобы узнать больше, ознакомьтесь с Руководством по Oracle. И найдите в Stack Overflow множество примеров и пояснений. Спецификация - JSR 310.

Проект Joda-Time, который сейчас находится в режиме обслуживания, рекомендует перейти на классы java.time.

Вы можете обмениваться объектами java.time непосредственно со своей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.* классах.

Где получить классы java.time?


  • Java SE 8, Java SE 9, Java SE 10, Java SE 11 и более поздние версии - часть стандартного Java API с комплексной реализацией.

    • Java 9 добавляет некоторые незначительные функции и исправления.


  • Java SE 6 и Java SE 7

    • Большая часть функциональных возможностей java.time перенесена обратно на Java 6 и 7 в ThreeTen-Backport.


  • Android

Таблица того, какую библиотеку java.time использовать с какой версией Java или Android

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательным полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и больше.

java