Есть ли строка формата для SimpleDateFormat, чтобы получить значение даты и времени в миллисекундах вместо понятной человеку формы? - PullRequest
0 голосов
/ 11 января 2020

С помощью таких классов, как SimpleDateFormat, можно форматировать время и дату в подходящем формате.

Примеры здесь

https://developer.android.com/reference/java/text/SimpleDateFormat#examples

В Java оно начинается со значения в миллисекундах, а затем это значение переводится в удобочитаемый для человека формат.

Иногда полезно иметь это значение вместо удобочитаемой для человека формы.

Пример:

Если я не ошибаюсь, значение 1578738100000 просто означает значение UT C Сб 11 января 2020 года 10: 21: 40.

Возможно ли иметь строку формата, которая дает строку с миллисекундами вместо удобочитаемой формы?

Я знаю, что можно получить значение миллисекунд непосредственно из класса Date, но здесь я спрашиваю, являются ли миллисекунды одной из возможных строк формата для подачи SimpleDateFormat (или аналогичные классы) с.

Ответы [ 2 ]

2 голосов
/ 11 января 2020

Необходимо четко понимать, что объекты значений даты и времени и объекты форматирования играют разные роли.

  • Объект даты и времени не имеет формата, он представляет дату и / или время суток с контекстом часового пояса или со смещением от UT C или без него.
  • Форматер не имеет значения, даты и времени суток. Работа форматера состоит в том, чтобы работать с объектом даты и времени для создания текста в определенном формате, представляющем значение этого объекта даты и времени.

Таким образом, отслеживание количества миллисекунд, так как ссылка на эпоху является задачей объект даты и времени, а не форматер. Создание удобочитаемого текста - работа форматера. Поэтому нет, средство форматирования не производит подсчет миллисекунд.

И, нет, вам не следует использовать подсчет миллисекунд для передачи значений даты и времени. Такие цифры не имеют смысла для читателя, что приводит к тому, что легко пропустить ошибочные данные. И такие данные не могут легко идентифицировать себя - это целые секунды, миллисекунды, микросекунды или наносекунды? И какова эталонная дата эпохи, какая из пары дюжин обычно используемых эпох ?

Вместо этого сообщайте значения даты и времени в виде текста, используя стандартные форматы ISO 8601.

Другая проблема: вы используете ужасные классы даты и времени, которые были заменены годами на go современными java .time классами, определенными в JSR 310.

Если ваш номер отсчет миллисекунд с начала отсчета эпохи первого момента 1970 года в UT C, анализируется как Instant.

Instant instant = Instant.ofEpochMilli( 1_578_738_100_000L ) ;

Если вы настаиваете на работе с отсчетом времени против моего совета, Вы можете запросить Instant.

long milliseconds = instant.toEpochMilli() ;

Создать текст в стандартном формате ISO 8601.

String output = instant.toString() ;

Для других форматов установите Instant в OffsetDateTime или ZonedDateTime объекта и генерировать текст с DateTimeFormatter. Все это уже освещалось много, много раз. Поэтому ищите переполнение стека, чтобы узнать больше.

instant
.atZone( 
    ZoneId.of( "America/Montreal" ) 
)
.format(
    DateTimeFormatter
    .ofLocalizedDateTime( FormatStyle.FULL )
    .withLocale( Locale.CANADA_FRENCH )
)

Наконец, имейте в виду, что, хотя унаследованные классы были ограничены разрешением в миллисекундах, классы java .time вращаются до гораздо более мелких наносекунд. Поэтому остерегайтесь возможной потери данных при вызове Instant::toEpochMilli, так как любые микросекунды или наносекунды игнорируются,

0 голосов
/ 11 января 2020

Старый и устаревший SimpleDateFormat класс не может этого сделать. Его замена, современный DateTimeFormatter, может.

    DateTimeFormatter epochMilliFormatter = new DateTimeFormatterBuilder()
            .appendValue(ChronoField.INSTANT_SECONDS)
            .appendValue(ChronoField.MILLI_OF_SECOND, 3)
            .toFormatter();

    Instant sampleInstant = OffsetDateTime
            .of(2020, 1, 11, 10, 21, 40, 0, ZoneOffset.UTC)
            .toInstant();

    String formattedValue = epochMilliFormatter.format(sampleInstant);
    System.out.println(formattedValue);

Выход из этого фрагмента - номер, который вы упомянули:

1578738100000

Использование ChronoField.INSTANT_SECONDS в форматере дает нам секунд с эпохи. Мы хотели миллисекунд , поэтому нам нужно немедленно добавить ChronoField.MILLI_OF_SECOND и убедиться, что они печатаются точно в 3 позициях с добавлением нуля. Вот что делает 3 в качестве второго аргумента appendValue().

Возможно ли иметь строку формата , которая дает строку с миллисекундами ...?

Нет, со строкой шаблона формата это невозможно, ни с SimpleDateFormat, ни с DateTimeFormatter. Вы можете go просмотреть возможную букву каждого из шаблонов и увидеть, что со времен эпохи нет ни одного шаблона, ни букв, ни секунд, ни миллисекунд.

Вы уверены, что хотите его? Даже если это для хранения или для обмена данными между системами, используется миллисекунды, так как эпоха обычно не рекомендуется именно потому, что они не читаются человеком и, следовательно, проблематичны при отладке и в специальных запросах c. В большинстве случаев вам лучше использовать строку в формате ISO 8601, например 2020-01-11T10:21:40Z. Смотрите другой ответ Василия Бурка для деталей. Формат ISO 8601 предназначен для чтения как людьми, так и компьютерами.

В любом случае вам не следовало использовать SimpleDateFormat

Класс SimpleDateFormat общеизвестно проблематичен (хотя даже больше для анализа) чем для форматирования). Это также давно устарело. Класс Date, который вы упомянули, плохо спроектирован и тоже давно устарел. Я рекомендую использовать java .time, современный Java API даты и времени, как я делаю выше.

Ссылки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...