Создать дату UTC с отметкой времени на основе часового пояса - PullRequest
0 голосов
/ 01 декабря 2011

Странный вопрос, но вы должны сначала знать, что Facebook API определяет все даты с отметкой времени (long = номер секунды ), начатой ​​01.01.1970 00:00: 00 находится в часовой пояс PDT (тихоокеанское время) .Это число секунд - не временная метка UTC, а поддельная, основанная на нестандартном местоположении.

Есть ли в java простой способ преобразовать эту длинную временную метку в обычный объект Date, который я мог бы использовать (и напечатать(во французском формате со стандартными форматерами даты)?

PS: Это не просто вопрос +7 часов, летнее время включено в эту метку времени.Кроме того, у нас также есть летнее время во Франции, но не то же самое ...

Спасибо

ОБНОВЛЕНИЕ: Это сложнее, чемпросто фиксированная дельта.Я думаю, что Facebook записывает дату, которую я даю, как дату PSD.Если я записываю четверг 26/10/2011 16:00 (Парижский часовой пояс), Facebook записывает 26/10/2011 16:00 (часовой пояс Сан-Франциско) и преобразует его в соответствующее количество секунд UTC с 1970 года. Проблема заключается в том, что это преобразование учитываетлетнее время в Сан-Франциско.Для демонстрации я выполнил следующий тест:

  • (31.12.2011, 16:00 - по французскому времени) Отметка времени FB = 1325376000 вместо 1325343600 (отметка времени UTC) -> Дельта: -32400
  • (31/07/2012 16:00 - по французскому времени) Метка времени FB = 1343775600 вместо 1343743200 -> Дельта: -32400
  • (10.03.2012 16:00 - по французскому времени) FBОтметка времени = 1349305200 вместо 1349272800 -> Дельта: -32400
  • (28/10/2012 08:00 - время Франции) Отметка времени FB = 1351436400 вместо 1351407600 -> Дельта: -28800
  • (25.03.2012 08:00 - французское время) FB Timestamp = 1332687600 вместо 1332655200 -> Delta: -32400
  • (24/03/2012 23:30 - France Time) FB Timestamp = 1332657000 вместо1332628200 -> Дельта: -28800
  • (27/10/2012 23:30 - время по Франции) Метка времени FB = 1351405800 вместо 1351373400 -> Дельта: -32400

ВНа самом деле мне нужен способ конвертации 31.10.2011 16H00 (PDT) в 31.10.2011 16H00 (Paris TZ) ...

Ответы [ 2 ]

0 голосов
/ 01 декабря 2011

Так что у фейсбука фиксированное смещение +7 часов по сравнению со стандартной эпохой? Разве вы не можете просто вычесть это смещение при разборе метки времени? Например:

@Test
public void testFacebook() throws Exception {
  long SEVEN_HRS_IN_MILLIS = 25200000;
  DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
  TimeZone cet = TimeZone.getTimeZone("Europe/Paris");
  df.setTimeZone(cet);
  long facebookTimestamp = 1322769308471L;
  Date then = new Date();
  then.setTime(facebookTimestamp - SEVEN_HRS_IN_MILLIS);
  assertEquals("2011-12-01 13:55:08 +0100", df.format(then));
}

Обратите внимание, что метка времени обычно определяется как «количество (милли) секунд с момента обращения», и это никогда не может включать переход на летнее время. Количество секунд с 1970-01-01 00:00:00 UTC не изменится, если вы переместите стрелки часов.

ОБНОВЛЕНИЕ: То есть вы даете Facebook дату для хранения, и ваша реальная проблема в том, что вы не можете указать правильный часовой пояс, чтобы он сохранялся в любое время в Сан-Франциско? Вы можете преобразовать время в часовой пояс "America / Los_Angeles" перед сохранением. Кроме того, вы можете преобразовать его обратно после извлечения, с помощью чего-то вроде этого:

private DateFormat getDateFormat(String timezone) {
  DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  TimeZone tz = TimeZone.getTimeZone(timezone);
  df.setTimeZone(tz);
  return df;
}

private Date getDateWithCorrectedOffset(long timestamp, DateFormat source, DateFormat target) throws ParseException {
  Date d = new Date(timestamp);
  return target.parse(source.format(d));
}

@Test
public void testFacebook() throws ParseException {
  DateFormat parisTime = getDateFormat("Europe/Paris");
  DateFormat sfTime = getDateFormat("America/Los_Angeles");
  assertEquals("2011-12-31 16:00:00", parisTime.format(getDateWithCorrectedOffset(1325376000000L, sfTime, parisTime)));
  assertEquals("2012-07-31 16:00:00", parisTime.format(getDateWithCorrectedOffset(1343775600000L, sfTime, parisTime)));
  assertEquals("2012-10-03 16:00:00", parisTime.format(getDateWithCorrectedOffset(1349305200000L, sfTime, parisTime)));
  assertEquals("2012-10-28 08:00:00", parisTime.format(getDateWithCorrectedOffset(1351436400000L, sfTime, parisTime)));
  assertEquals("2012-03-25 08:00:00", parisTime.format(getDateWithCorrectedOffset(1332687600000L, sfTime, parisTime)));
  assertEquals("2012-03-24 23:30:00", parisTime.format(getDateWithCorrectedOffset(1332657000000L, sfTime, parisTime)));
  assertEquals("2012-10-27 23:30:00", parisTime.format(getDateWithCorrectedOffset(1351405800000L, sfTime, parisTime)));    
} 
0 голосов
/ 01 декабря 2011

При создании SimpleDateFormat вы можете указать часовой пояс. Дата, которую это произвело, является GMT + 0. Вы можете отобразить его в своем местном часовом поясе, используя другой SimpleDateFormat с вашим часовым поясом. (Или вы можете использовать JodaTime, чтобы сделать то же самое)

Если вам нужно количество миллисекунд с 01.01.1970 в часовом поясе PST, вы можете сделать

public static final long PST_1970; static {
    try {
        final SimpleDateFormat MM_DD_YYYY = new SimpleDateFormat("MM/dd/yyyy");
        MM_DD_YYYY.setTimeZone(TimeZone.getTimeZone("PST"));
        PST_1970 = MM_DD_YYYY.parse("01/01/1970").getTime();
    } catch (ParseException e) {
        throw new AssertionError(e);
    }
}

public static void main(String... args) throws InterruptedException {
    long now = System.currentTimeMillis();
    long timeSincePST = now - PST_1970;
    System.out.println("now since 1970 GMT " + now);
    System.out.println("millis since 1970 PST " + timeSincePST);
}

Поскольку в GMT нет летних изменений, это хорошее общее время для использования.

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