Как получить текущую дату / время в Java
Какой наилучший способ получить текущую дату / время в Java?
Переведено автоматически
Ответ 1
Какой наилучший способ получить текущую дату / время в Java?
"Лучшего" способа не существует.
Это зависит от того, какую форму даты / времени вы хотите:
Если вы хотите получить дату / время в виде единственного числового значения, то
System.currentTimeMillis()
дает вам это значение, выраженное в количестве миллисекунд после эпохи UNIX (как Javalong
). Это значение является разницей от временной точки 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
- Более поздние версии Android включают реализации классов java.time.
- Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). Смотрите Как использовать ThreeTenABP ....
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательным полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и больше.