Так что у фейсбука фиксированное смещение +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)));
}