Java: дата из метки времени Unix

237

Мне нужно преобразовать метку времени Unix в объект даты.
Я попробовал это:

java.util.Date time = new java.util.Date(timeStamp);

Значение метки времени: 1280512800

Дата должна быть «2010/07/30 - 22:30:00» (как я понимаю по PHP), но вместо этого я получаю Thu Jan 15 23:11:56 IRST 1970.

Как это должно быть сделано?

RYN
источник
3
Если вы используете Java 8 или новее: посмотрите на этот ответ: stackoverflow.com/a/24703644/1115554
micha
1
К вашему сведению, проблемные старые классы даты и времени, такие как java.util.Dateтеперь, унаследованы , заменены классами java.time . Смотрите Учебник по Oracle .
Василий Бурк

Ответы:

429

Для 1280512800, умножьте на 1000, так как Java ожидает миллисекунды:

java.util.Date time=new java.util.Date((long)timeStamp*1000);

Если у вас уже были миллисекунды, то просто new java.util.Date((long)timeStamp);

Из документации :

Выделяет объект Date и инициализирует его для представления указанного количества миллисекунд со стандартного базового времени, известного как «эпоха», а именно 1 января 1970 года, 00:00:00 по Гринвичу.

Пабло Санта Круз
источник
41
Приведение к (long)очень важно: без него целое число переполняется.
Mneri
2
@TomasK java.util.Date- это полное имя класса. DateВероятно, это то же самое, если вы импортируете java.utilпакет в свой класс.
Пабло Санта Круз
5
Бросок на долго не нужен. time = new java.util.Date (timeStamp * 1000L) работает точно так же (так как 1000L длинная, временная метка будет передана задолго до умножения)
Тони БенБрахим
2
Я лично сделал бы:Date time = new Date(TimeUnit.MILLISECONDS.convert(unixTimestamp, TimeUnit.SECONDS));
Райан Амарал
3
К вашему сведению, проблемные старые классы даты и времени, такие как java.util.Dateтеперь, унаследованы , заменены классами java.time . Смотрите Учебник по Oracle .
Василий Бурк
60

java.time

Java 8 представила новый API для работы с датами и временем: пакет java.time .

С помощью java.time вы можете анализировать количество секунд с начала отсчета эпохи первого момента 1970 года в UTC, 1970-01-01T00: 00Z. Результатом является Instant.

Instant instant = Instant.ofEpochSecond( timeStamp );

Если вам нужно java.util.Dateвзаимодействовать со старым кодом, который еще не обновлен для java.time , конвертируйте. Вызовите новые методы преобразования, добавленные к старым классам.

Date date = Date.from( instant );
Миха
источник
3
Хотя этот ответ технически верен, обратите внимание, что классы java.time вытесняют старые классы даты и времени, такие как java.util.Date. Старые классы унаследованы и их следует избегать. Хотя вы действительно можете конвертировать в / из старых классов и классов java.time, лучше по возможности придерживаться java.time.
Василий Бурк
44

Это правильный путь:

Date date = new Date ();
date.setTime((long)unix_time*1000);
Марко Фантазия
источник
27

Похоже, календарь это новый путь:

Calendar mydate = Calendar.getInstance();
mydate.setTimeInMillis(timestamp*1000);
out.println(mydate.get(Calendar.DAY_OF_MONTH)+"."+mydate.get(Calendar.MONTH)+"."+mydate.get(Calendar.YEAR));

Последняя строка - это просто пример того, как ее использовать, например, «14.06.2012».

Если вы использовали System.currentTimeMillis () для сохранения метки времени, вам не нужна часть «* 1000».

Если у вас есть временная метка в строке, вам нужно сначала проанализировать ее как long: Long.parseLong (timestamp).

https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html

Стефан
источник
8
Предупреждение: если timestampэто целое число, вам нужно привести его к (long)первому, иначе вы получите неправильные даты. mydate.setTimeInMillis((long) timestamp*1000);
svenkapudija
Я исправил ссылку.
Рикбит
К вашему сведению, проблемные старые классы даты и времени, такие как java.util.Date, java.util.Calendarи java.text.SimpleDateFormatтеперь унаследованные , вытеснены классами java.time, встроенными в Java 8 и более поздние версии . Смотрите Учебник по Oracle .
Василий Бурк
26

ТЛ; др

Instant.ofEpochSecond( 1_280_512_800L )

2010-07-30T18: 00: 00Z

java.time

Новый фреймворк java.time, встроенный в Java 8 и более поздние версии, является преемником Joda-Time.

Эти новые классы включают удобный фабричный метод для преобразования количества целых секунд от эпохи. Вы получаете Instantмгновение на временной шкале в UTC с разрешением до наносекунд.

Instant instant = Instant.ofEpochSecond( 1_280_512_800L );

instant.toString (): 2010-07-30T18: 00: 00Z

Посмотрите, как работает этот код на IdeOne.com .

Таблица типов даты и времени в Java, как современных, так и устаревших

Asia/Kabulили Asia/Tehranчасовые пояса?

Вы сообщили о получении значения времени дня 22:30 вместо 18:00, показанного здесь. Я подозреваю, что ваша утилита PHP неявно применяет часовой пояс по умолчанию для настройки из UTC. Мое значение здесь - UTC, обозначенное как Z(сокращение от ZuluUTC). Есть ли шанс, что на вашей машине установлена ​​ОС или PHP Asia/Kabulили Asia/Tehranчасовые пояса? Полагаю, что так, как вы сообщаете IRSTв своих материалах, это, по-видимому, означает иранское время В настоящее время в 2017 году это единственные зоны, работающие в летнее время, которое на четыре с половиной часа опережает UTC.

Укажите правильное время имя зоны в формате continent/region, например America/Montreal, Africa/Casablancaили Pacific/Auckland. Никогда не используйте 3-4 письмо аббревиатуры , такие как ESTили ISTили IRSTкак они не настоящие часовые пояса, не стандартизирован, и даже не единственный (!).

Если вы хотите увидеть свой момент через призму часового пояса определенного региона, примените a, ZoneIdчтобы получить a ZonedDateTime. Все тот же одновременный момент, но рассматриваемый как другое время настенных часов .

ZoneId z = ZoneId.of( "Asia/Tehran" ) ;
ZonedDateTime zdt = instant.atZone( z );  // Same moment, same point on timeline, but seen as different wall-clock time.

2010-07-30T22: 30 + 04: 30 [Азия / Тегеран]

Преобразование из java.time в унаследованные классы

Вы должны придерживаться новых классов java.time. Но вы можете конвертировать в старый, если требуется.

java.util.Date date = java.util.Date.from( instant );

Joda времени

ОБНОВЛЕНИЕ: проект Joda-Time сейчас находится в режиме обслуживания , и команда рекомендует перейти на классы java.time .

К вашему сведению, конструктор Joda-Time DateTime похож: умножьте на тысячу, чтобы получить long(не int!).

DateTime dateTime = new DateTime( ( 1_280_512_800L * 1000_L ), DateTimeZone.forID( "Europe/Paris" ) );

Лучше всего избегать печально известных классов java.util.Date и .Calendar. Но если вам нужно использовать дату, вы можете конвертировать из Joda-Time.

java.util.Date date = dateTime.toDate();

О java.time

Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые устаревшие классы даты и времени , такие как java.util.Date, Calendar, и SimpleDateFormat.

Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, смотрите Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии . Нет необходимости в строках, нет необходимости в java.sql.*классах.

Где взять классы java.time?

  • Java SE 8 , Java SE 9 и более поздние
    • Встроенный.
    • Часть стандартного 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, и более .

Базилик Бурк
источник
11

Конструктор даты ожидает, что значение timeStamp будет в миллисекундах. Умножьте значение вашей временной метки на 1000, затем передайте значение конструктору.

F1sh
источник
7

Если вы конвертируете значение метки времени на другом компьютере, вам также следует проверить часовой пояс этого компьютера. Например;

Приведенные выше описания приведут к различным значениям даты, если вы работаете с часовыми поясами EST или UTC.

Установить часовой пояс; или UTC, вы можете просто переписать;

    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    java.util.Date time= new java.util.Date((Long.parseLong(timestamp)*1000));
пмр
источник
6
Я бы не рекомендовал это, потому что это устанавливает часовой пояс для всего jvm, а не только для процесса анализа!
1

Для котлин

fun unixToDate(timeStamp: Long) : String? {
    val time = java.util.Date(timeStamp as Long * 1000)
    val sdf = SimpleDateFormat("yyyy-MM-dd")
    return sdf.format(time)

}
kzncrda
источник
0

Иногда вам нужно работать с настройками.

Не используйте бросок на долго! Используйте нанорегулировку.

Например, используя Oanda Java API для торговли, вы можете получить datetime в формате UNIX.

Например: 1592523410.590566943

    System.out.println("instant with nano = " + Instant.ofEpochSecond(1592523410, 590566943));
    System.out.println("instant = " + Instant.ofEpochSecond(1592523410));

ты получаешь:

instant with nano = 2020-06-18T23:36:50.590566943Z
instant = 2020-06-18T23:36:50Z

Также используйте:

 Date date = Date.from( Instant.ofEpochSecond(1592523410, 590566943) );
Дамир Исанбердин
источник
-4
Date d = new Date(i * 1000 + TimeZone.getDefault().getRawOffset());
Масацугу Хосой
источник
3
Без дополнительного текста неясно, почему этот ответ предпочтительнее многих других в этом вопросе. Можете ли вы уточнить?
Дункан Джонс
Это изменит дату, а не конвертирует ее!
обратная косая