Java Convert Long to Date?

У меня есть список с длинными значениями (например: 1220227200, 1220832000, 1221436800...), которые я загрузил из веб-службы. Я должен преобразовать его в Даты. К сожалению, этот способ, например:

Date d = new Date(1220227200);

возвращает 1 января 1970 года. Кто-нибудь знает другой способ его правильного преобразования?

Ответ 1

Конструктор Date (щелкните ссылку!) принимает время как long в миллисекундах, а не секунды. Вам нужно умножить его на 1000 и убедиться, что вы его поставьте как long.

Date d = new Date(1220227200L * 1000);

Здесь показано

Вс 31 авг 20:00:00 GMT-04: 00 2008

Ответ 2

Похоже, ваши длинные секунды, а не миллисекунды. Конструктор даты принимает время в миллисекундах, поэтому

Date d = new Date(timeInSeconds * 1000);

Ответ 3

TL;DR

Instant.ofEpochSecond( 1_220_227_200L )

Знать свои данные

Люди используют различные оценки во время отслеживания как число с epoch. Поэтому, когда вы получаете некоторые числа, которые будут интерпретироваться как счет с эпохи, вы должны определить:

  • Какая эпоха?
    Многие эпохи дат использовались в различных системах. Обычно используется POSIX/Unix time, где эпоха является первым моментом 1970 года в UTC. Но вы не должны считать эту эпоху.
  • Какая точность?
    Мы говорим секунды, миллисекунды, микросекунды или наносекунды с эпохи?
  • Какой часовой пояс?
    Обычно счет с эпохи находится в UTC/часовой пояс GMT, что не имеет никакого смещения часового пояса. Но иногда, когда речь идет о неопытных программистах с неопределенными датами, может быть подразумеваемый часовой пояс.

В вашем случае, как отмечали другие, вам кажется, что вам дали секунды со времен Unix. Но вы передаете эти секунды конструктору, который ожидает миллисекунды. Таким образом, решение умножается на 1000.

Извлеченные уроки:

  • Определите, не принимайте значения полученных данных.
  • Прочитайте документ.

Graph showing various granularities of resolution in date-time systems including whole seconds, milliseconds, microseconds, and nanoseconds.

Ваши данные

Ваши данные, кажется, целые секунды. Если мы примем эпоху начала 1970 года, и если мы примем часовой пояс UTC, то 1,220,227,200 - это первый момент первого дня сентября 2008 года.

Joda времени

Классы java.util.Date и .Calendar в комплекте с Java, как известно, являются неприятными. Избежать их. Вместо этого используйте библиотеку Joda-Time или новый пакет java.time в комплекте с Java 8 (и вдохновлен Joda-Time).

Обратите внимание, что в отличие от juDate, DateTime в Joda-Time действительно знает свою собственную назначенную часовой пояс. Итак, в приведенном ниже примере кода Joda-Time 2.4 обратите внимание, что мы сначала разбираем миллисекунды, используя стандартное предположение о UTC. Затем, во-вторых, мы назначим часовой пояс Парижа. В тот же момент на временной шкале Вселенной, но разные время настенных часов. Для демонстрации мы снова настраиваемся на UTC. Почти всегда лучше явно указать желаемый/ожидаемый часовой пояс, а не полагаться на неявное значение по умолчанию (часто это является причиной проблем в работе с датой).

Нам нужно миллисекунды для создания DateTime. Так что сделайте свой вклад в секундах и умножьте на тысячу. Обратите внимание, что результат должен быть 64-разрядным long, поскольку мы переполнили бы 32-разрядный int.

long input = 1_220_227_200L;  // Note the "L" appended to long integer literals.
long milliseconds = ( input * 1_000L ); // Use a "long", not the usual "int". Note the appended "L".

Подайте количество миллисекунд на конструктор. Этот конкретный конструктор предполагает, что подсчет относится к эпохе Unix 1970 года. Так что настройте часовой пояс по желанию после строительства.

Используйте правильные часовые пояса, сочетание континентов и города/региона. Никогда не используйте 3 или 4 буквенных кода, например EST, поскольку они не являются стандартизованными не уникальными.

DateTime dateTimeParis = new DateTime( milliseconds ).withZone( DateTimeZone.forID( "Europe/Paris" ) );

Для демонстрации снова настройте часовой пояс.

DateTime dateTimeUtc = dateTimeParis.withZone( DateTimeZone.UTC );
DateTime dateTimeMontréal = dateTimeParis.withZone( DateTimeZone.forID( "America/Montreal" ) );

Дамп для консоли. Обратите внимание на то, как в Монреале эта дата отличается, поскольку новый день начался в Европе, но еще не в Америке.

System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeUTC: " + dateTimeUtc );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );

При запуске.

dateTimeParis: 2008-09-01T02:00:00.000+02:00
dateTimeUTC: 2008-09-01T00:00:00.000Z
dateTimeMontréal: 2008-08-31T20:00:00.000-04:00

java.time

Создатели Joda-Time попросили нас перейти на его замену, java.time, как только это будет удобно. Хотя Joda-Time продолжает активно поддерживаться, все будущие разработки будут выполняться на классах java.time и их расширениях в проекте ThreeTen-Extra.

Структура java-time определяется JSR 310 и встроена в Java 8 и более поздних версий. Классы java.time были перенесены на Java 6 и 7 в проект ThreeTen-Backport и на Android в ThreeTenABP.

An Instant - это момент на временной шкале в UTC с разрешением наносекунд. Его эпоха - это первый момент 1970 года в UTC.

Instant instant = Instant.ofEpochSecond( 1_220_227_200L );

Примените offset-from-UTC ZoneOffset, чтобы получить OffsetDateTime.

Еще лучше, если известно, примените часовой пояс ZoneId, чтобы получить ZonedDateTime.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

Ответ 4

Вероятно, это отметки времени секунды, а не миллисекунды, которые необходимы для нового конструктора Date (long). Просто умножьте их на 1000, и вы должны быть в порядке.

Ответ 5

Установите время в мельницах только на объект календаря

Calendar c = Calendar.getInstance();
c.setTimeInMillis(1385355600000l);
System.out.println(c.get(Calendar.YEAR));
System.out.println(c.get(Calendar.MONTH));
System.out.println(c.get(Calendar.DAY_OF_MONTH));
// get Date
System.out.println(c.getTime());

Ответ 6

Попробуйте следующее:

Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(1220227200 * 1000);
System.out.println(cal.getTime());

Ответ 7

Длинные значения, скорее всего, соответствуют Epoch timestamps, а значения:

1220227200 = Пн, 01 сен 2008 00:00:00 GMT

1220832000 = Пн, 08 сен 2008 00:00:00 GMT

1221436800 = Пн, 15 сен 2008 00:00:00 GMT

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

// note: enforcing long literals (L), without it the values would just be wrong.
Date date = new Date(1220227200L * 1000L); 

Теперь, чтобы правильно отобразить дату, можно использовать java.text.DateFormat, как показано ниже:

DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("Wrong date time value: " + date);
System.out.println("Correct date time value: " + df.format(date));

Ниже приведены результаты отображения преобразованного длинного значения в java.util.Date без использование и использование DateFormat:

Date wrong (off by 2 hours): Mon Sep 01 02:00:00 CEST 2008
Correct date : Monday, 1 September 2008 00:00:00 o'clock UTC

Ответ 8

Новая дата (число) возвращает дату, которая number миллисекунды после 1 января 1970 года. Вероятность того, что вы даете формат, не показывает часы, минуты и секунды, чтобы вы могли видеть, что это немного позже после 1 января 1970 года.

Вам нужно проанализировать дату в соответствии с правильной разводкой. Я не знаю, что такое 1220227200, но если он после 1 января 1970 года, умножьте его на миллисекунды. Если это не так, то конвертируйте его каким-то образом в миллисекунды после 1970 года (если вы хотите продолжать использовать java.util.Date).

Ответ 9

Работает для меня. Вероятно, вы хотите умножить его на 1000, так как то, что вы получаете, это секунды с 1970 года, и вам нужно пройти миллисекунды с 1 января 1970 года.

Ответ 10

1220227200 соответствует 15 января 1980 года (и действительно новая дата (1220227200).toString() возвращает "Thu Jan 15 03:57:07 CET 1970" ). Если вы передадите длинную сумму на дату, то есть до 01.01.1970, она фактически вернет дату 01/01/1970. Убедитесь, что ваши значения не в этой ситуации (ниже 82800000).