Как разобрать вывод новой Date(). toString()
Мне нужен формат даты (возможно, SimpleDateFormat), который анализирует достоверность вывода, который я получаю, когда вызываю toString() в объекте Date. Вывод на мою немецкую (!) Систему: "Sun Dec 12 13:45:12 CET 2010", поэтому, похоже, он не уважает локали, что, похоже, упрощает.
Кто-нибудь?
Ответы
Ответ 1
Этот формат указан в Date#toString()
.
Преобразует этот объект Date
в String
формы:
dow mon dd hh:mm:ss zzz yyyy
Итак, в SimpleDateFormat
шаблонные термины:
EEE MMM dd HH:mm:ss zzz yyyy
Не связанный с проблемой, интересно, было ли на первом месте плохой идеей использовать Date#toString()
вместо SimpleDateFormat#format()
для вывода дат. Я бы решил исправить это прямо там.
Ответ 2
BalusC дал вам правильный формат, я бы сказал - не надо. Метод toString()
не должен использоваться ни для чего, кроме ведения журнала.
Вы можете использовать SimpleDateFormat
для форматирования и разбора.
Ответ 3
TL; DR
Instant parsedBack = Instant.parse(Instant.now().toString());
System.out.println(parsedBack);
2019-05-30T08: 36: 47.966274Z
Используйте ISO 8601 и java.time
- Если вашей реальной целью является сериализация и десериализация даты и времени (например, для передачи данных или для сохранения), сериализуйте в ISO 8601, стандартный формат для данных даты и времени.
- Пропустить класс устаревших
Date
. Современный API даты и времени Java, известный как java.time
намного приятнее работать. Класс, который вам нужен от этого, вероятно, Instant
(это зависит от ваших более точных требований).
Две точки прекрасно сочетаются друг с другом:
Instant i = Instant.now();
String s = i.toString();
Instant theSameInstant = Instant.parse(s);
Современные методы toString
классов производят формат ISO 8601 (например, 2018-01-11T10:59:45.036Z
), и их методы parse
читают тот же формат обратно. Так что этот фрагмент - все, что вам нужно, и вы получите мгновение, равное первому, с точностью до наносекунды.
Если вы не можете контролировать полученную строку и получаете результат от Date.toString()
, строка шаблона формата в ответе java.time
также работает с java.time
:
DateTimeFormatter dtf
= DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT);
Date d = new Date();
String s = d.toString();
Instant nearlyTheSameInstant = ZonedDateTime.parse(s, dtf).toInstant();
Некоторые предупреждения, однако:
- Миллисекунды от первоначальной
Date
теряются, поскольку они не находятся в строке, что приводит к неточности до 999 миллисекунд (именно поэтому я назвал переменную nearlyTheSameInstant
). - Эра от оригинальной
Date
не в строке. Поэтому, если ваша первоначальная Date
была в 44 году до н.э., вы получите соответствующую дату в 44 году нашей эры (нашей эры) (в любом случае имя переменной nearlyTheSameInstant
было ложью в любом случае). - Сокращение часового пояса в строке часто (чаще всего?) Неоднозначно, поэтому существует большой риск получения неправильного часового пояса и, следовательно, неправильного времени. Что еще хуже, неоднозначное сокращение часового пояса будет интерпретироваться по-разному на разных JVM
- Важно обеспечить локаль. В противном случае будет использоваться языковой стандарт по умолчанию для JVM, и, если это не английский язык, синтаксический анализ не будет выполнен. В худшем случае вы увидите, что ваш код работает нормально в течение многих лет, и внезапно он сломается, когда однажды кто-нибудь запустит его на компьютере или устройстве с другой настройкой локали. Я использую
Locale.ROOT
для "локаль-нейтральной локали" или "не применять обработку, специфичную для локали". Кажется, здесь правильный подход.
связи