Преобразование даты в миллисекунды эпохи

У меня есть дата Java (Fri Jun 28 10:00:01 GMT+01:00 2024), которую я хочу преобразовать в миллис эпохи, чтобы отправить на сервер.

Я пробовал следующее:

typealias Dates = java.util.Date

fun Dates.toEpochMillis(timeZoneId: ZoneId): Long {
    val one = Instant.ofEpochMilli(time).toEpochMilli() // 1719565201000
    val three = secsToMillis(this.toLocalDateTime(timeZoneId).utcEpochSecs) // 1719568801000
    return one
}

fun Dates.toLocalDateTime(timeZoneId: ZoneId): LocalDateTime {
    return Instant.ofEpochMilli(time).atZone(timeZoneId).toLocalDateTime()
}

fun secsToMillis(timeInSecs: Long): Long {
    return timeInSecs * 1000
}

Что из вышеперечисленного верно или вы предлагаете какой-либо другой способ сделать это?

Зависит от входных данных и ожидаемого результата.

aled 27.06.2024 23:37

можешь немного объяснить @aled

BRDroid 27.06.2024 23:51

ввод — это Fri Jun 28 10:00:01 GMT+01:00 2024, когда вы говорите ожидаемый результат? Поясните, пожалуйста, что вы имеете в виду?

BRDroid 27.06.2024 23:51

Что такое Dates?

Leviathan 27.06.2024 23:52

и val one = Instant.ofEpochMilli(time).toEpochMilli() как это сделать правильно? поскольку это дает мне правильные значения

BRDroid 27.06.2024 23:52
long inst = OffsetDateTime.parse("Fri Jun 28 10:00:01 GMT+01:00 2024", DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O uuuu")).toInstant().toEpochMilli(); возможно
g00se 28.06.2024 00:03

Ваши примеры сбивают с толку: вы анализируете эпоху, а затем возвращаете эпоху (?). Если вы имеете в виду, что у вас есть Instant, то да, как следует из названия, toEpochMilli предназначен именно для этой цели. Если у вас есть другие типы даты/времени, обычно они имеют toInstant или аналогичный метод, тогда toEpochMilli.

broot 28.06.2024 00:06

Кстати, не имеет значения, какой часовой пояс вы используете. Эпоха всегда UTC.

broot 28.06.2024 00:09

@broot, спасибо, что вернулся, ты имеешь в виду val one = Instant.ofEpochMilli(time).toEpochMilli() это достаточно хорошо?

BRDroid 28.06.2024 00:17

Понятия не имею, потому что этот код не имеет для меня особого смысла. Он принимает число в качестве входных данных и возвращает точно такое же число. Если вы имеете в виду только последнюю часть, то да, именно так мы получаем миллис эпохи, если у нас есть Instant.

broot 28.06.2024 00:19

Какого ответа вы ожидаете на этот ввод? Ты единственный, кто это знает.

aled 28.06.2024 01:23

@aled: В вопросах говорится: «Я хочу конвертировать в миллис-эпоху». Это Время Эпохи в миллисекундах, которое очень четко определено.

Leviathan 28.06.2024 01:28

У ОП, похоже, есть некоторая путаница по этому поводу.

aled 28.06.2024 02:00

если у вас «есть дата Java» (при условии, что java.util.Date в настоящее время существуют более качественные типы данных), то вы можете использовать его метод getTime() - из его документации: «Возвращает количество миллисекунд с 1 января 1970 года, 00:00 :00 GMT, представленное этим объектом Date». [Комментарий на основе Java]

user85421 28.06.2024 08:24

Также для большинства целей я рекомендую не использовать миллисекунды с начала эпохи для передачи значения на серверную часть. Пусть ваша серверная часть примет формат ISO 8601 и пусть ваш Instant создаст это. Это то, что уже делает этот метод toString.

Anonymous 28.06.2024 11:00

@ g00se Никакого синтаксического анализа не требуется. У вопрошающего уже есть старомодный java.util.Date.

Anonymous 28.06.2024 16:28

@Anonymous Я не был в этом уверен. Но я хотел утверждать, какое значение даты и времени было представлено.

g00se 28.06.2024 16:37
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
17
119
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы можете использовать это:

fun Dates.toEpochMillis(): Long =
    toInstant().toEpochMilli()

на самом деле это просто более дорогой способ вызова Date#getTime -- в основном так и есть Instant.ofEpochMilli(date.getTime()).toEpochMilli() (оба метода Instant даже выполняют некоторые вычисления для преобразования миллисекунд в/из секунд и наносекунд)

user85421 29.06.2024 10:07

@user85421 user85421 Не просто (немного) дороже. Также более понятно и понятно.

Anonymous 29.06.2024 14:43

вр; доктор

В синтаксисе Java:

long millisSinceEpoch = myJavaUtilDate.toInstant().toEpochMilli() ;

Подробности

У меня есть дата Java

Не.

Оба класса Date имеют ужасные недостатки и много лет назад были вытеснены современным классом java.time. Избегайте устаревших классов даты и времени, где это возможно.

Если вам вручили объект java.util.Date, немедленно преобразуйте его в замену: java.time.Instant . Используйте новые методы преобразования to…/from…, добавленные к старым классам. В данном случае java.util.Date#toInstant.

Instant instant = myJavaUtilDate.toInstant() ;

в эпоху миллисекунд

Просто вызовите Instant#toEpochMilli().

Остерегайтесь возможной потери данных, поскольку Instant может содержать микросекунды или наносекунды.

long millisSinceEpoch = instant.toEpochMilli() ;

toLocalDateTime

Совершенно неправильный класс для вас.

Никогда не используйте LocalDateTime, когда речь идет о конкретном моменте, конкретной точке на временной шкале. В LocalDateTime намеренно отсутствует контекст часового пояса или смещения от UTC. Итак, этот класс не может представлять момент. LocalDateTime — это буквально не что иное, как дата с указанием времени суток. Поэтому мы понятия не имеем, предназначались ли эти дату и время для просмотра с помощью настенных часов/календаря кто-то в Токио, Япония, кто-то в Тулузе, Франция, или кто-то в Толедо, штат Огайо, США — три разных момента с интервалом в несколько часов.

Если вы намерены представить определенную точку на временной шкале, используйте только эти классы: Instant, OffsetDateTime или ZonedDateTime. (Или их эквивалент в негригорианских календарях, таких как буддийский календарь или исламский календарь.)

Немного неясно, что вы подразумеваете под «обаими классами Date» - я вижу только один класс Date, о котором говорится в вопросе.

Klitos Kyriacou 28.06.2024 09:58

@KlitosKyriacou В библиотеках Java есть два Date класса. Этот неудачный выбор имен является одним из многих недостатков устаревших классов даты и времени. См. Javadoc. В этом квестоне не указано, какой Date класс.

Basil Bourque 28.06.2024 10:12

Кстати, оба класса Date предоставляют метод getTime(), который возвращает миллисекунды с начала эпохи Unix ||| ¹ java.sql.Date расширяет java.util.Date и, следовательно, наследует его методы

user85421 29.06.2024 10:03

@user85421 user85421 Да, но обучение людей использованию ужасно ошибочных устаревших классов окажет им медвежью услугу. Лучше сосредоточиться на современных классах-заменителях.

Basil Bourque 06.07.2024 00:04

@Basil согласился, но myJavaUtilDate.toInstant().toEpochMilli() просто использует Instant как временный экземпляр и все еще использует один из «ужасно испорченных устаревших классов» (и, ИМХО, не лучше, чем myJavaUtilDate.getTime(), не имея в виду здесь производительность)

user85421 06.07.2024 09:22

java.util.Date в основном является оберткой над значением эпохи в миллисах, поэтому единственное, что нам нужно сделать, это получить его обернутое значение:

myDate.time

Однако, как говорили другие, Date — очень старая, устаревшая и плохо продуманная утилита. В идеале вам вообще не следует использовать его, а вместо этого использовать более современные альтернативы, такие как: Instant, ZonedDateTime и т. д. Ближайшим эквивалентом Date является Instant.

one результат правильный, но он не имеет особого смысла — мы создаем Instant для данной эпохи только для того, чтобы вернуть ее эпоху. three результат неверный. Это эпоха для даты UTC 2024-06-28T10:00:01Z, а не для смещения +1: 2024-06-28T10:00:01+01:00.

Другие вопросы по теме