У меня есть дата 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
ввод — это Fri Jun 28 10:00:01 GMT+01:00 2024
, когда вы говорите ожидаемый результат? Поясните, пожалуйста, что вы имеете в виду?
Что такое Dates
?
и val one = Instant.ofEpochMilli(time).toEpochMilli()
как это сделать правильно? поскольку это дает мне правильные значения
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();
возможно
Ваши примеры сбивают с толку: вы анализируете эпоху, а затем возвращаете эпоху (?). Если вы имеете в виду, что у вас есть Instant
, то да, как следует из названия, toEpochMilli
предназначен именно для этой цели. Если у вас есть другие типы даты/времени, обычно они имеют toInstant
или аналогичный метод, тогда toEpochMilli
.
Кстати, не имеет значения, какой часовой пояс вы используете. Эпоха всегда UTC.
@broot, спасибо, что вернулся, ты имеешь в виду val one = Instant.ofEpochMilli(time).toEpochMilli()
это достаточно хорошо?
Понятия не имею, потому что этот код не имеет для меня особого смысла. Он принимает число в качестве входных данных и возвращает точно такое же число. Если вы имеете в виду только последнюю часть, то да, именно так мы получаем миллис эпохи, если у нас есть Instant
.
Какого ответа вы ожидаете на этот ввод? Ты единственный, кто это знает.
@aled: В вопросах говорится: «Я хочу конвертировать в миллис-эпоху». Это Время Эпохи в миллисекундах, которое очень четко определено.
У ОП, похоже, есть некоторая путаница по этому поводу.
если у вас «есть дата Java» (при условии, что java.util.Date
в настоящее время существуют более качественные типы данных), то вы можете использовать его метод getTime()
- из его документации: «Возвращает количество миллисекунд с 1 января 1970 года, 00:00 :00 GMT, представленное этим объектом Date». [Комментарий на основе Java]
Также для большинства целей я рекомендую не использовать миллисекунды с начала эпохи для передачи значения на серверную часть. Пусть ваша серверная часть примет формат ISO 8601 и пусть ваш Instant
создаст это. Это то, что уже делает этот метод toString
.
@ g00se Никакого синтаксического анализа не требуется. У вопрошающего уже есть старомодный java.util.Date
.
@Anonymous Я не был в этом уверен. Но я хотел утверждать, какое значение даты и времени было представлено.
Вы можете использовать это:
fun Dates.toEpochMillis(): Long =
toInstant().toEpochMilli()
на самом деле это просто более дорогой способ вызова Date#getTime
-- в основном так и есть Instant.ofEpochMilli(date.getTime()).toEpochMilli()
(оба метода Instant даже выполняют некоторые вычисления для преобразования миллисекунд в/из секунд и наносекунд)
@user85421 user85421 Не просто (немного) дороже. Также более понятно и понятно.
В синтаксисе 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, о котором говорится в вопросе.
@KlitosKyriacou В библиотеках Java есть два Date
класса. Этот неудачный выбор имен является одним из многих недостатков устаревших классов даты и времени. См. Javadoc. В этом квестоне не указано, какой Date
класс.
Кстати, оба класса Date предоставляют метод getTime()
, который возвращает миллисекунды с начала эпохи Unix ||| ¹ java.sql.Date
расширяет java.util.Date
и, следовательно, наследует его методы
@user85421 user85421 Да, но обучение людей использованию ужасно ошибочных устаревших классов окажет им медвежью услугу. Лучше сосредоточиться на современных классах-заменителях.
@Basil согласился, но myJavaUtilDate.toInstant().toEpochMilli()
просто использует Instant
как временный экземпляр и все еще использует один из «ужасно испорченных устаревших классов» (и, ИМХО, не лучше, чем myJavaUtilDate.getTime()
, не имея в виду здесь производительность)
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
.
Зависит от входных данных и ожидаемого результата.