Я ищу способ, способный к созданию Java 6 Секунд с эпохи в GMT/UTC (также известный как отметка времени UNIX) из объекта java.sql.Date
.Быстрая реализация Java 6 для получения отметки времени UNIX в GMT
Мой Java 8 код:
Long seconds = dateObject.toLocalDate().atStartOfDay(ZoneId.of("GMT")).toEpochSecond()
Мой Java 6 код:
final Calendar cal = Calendar.getInstance();
cal.setTime(dateObject);
final int year = cal.get(Calendar.YEAR);
final int month = cal.get(Calendar.MONTH);
final int day = cal.get(Calendar.DAY_OF_MONTH);
final GregorianCalendar c = new GregorianCalendar();
c.clear();
c.setGregorianChange(new Date(Long.MIN_VALUE));
c.setTimeZone(TimeZone.getTimeZone("GMT"));
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_MONTH, day);
Long seconds = c.getTimeInMillis()/1000
Unfortunally, код Java 6 составляет примерно как половина так же быстро, как код Java 8. У меня было решение Java 6 с меньшим количеством кода в прошлом (и тем самым быстрее), но это было неправильно, когда дело доходило до необычных дат как «0001-01-01», где требуется setGregorianChange()
, а второй GergorianCalendar
.
Любая идея, что я могу сделать, чтобы быстро реализовать Java 6?
- мне нужна безопасность Thread
- "2010-01-01" должно привести к 1262304000
- "0001-01-01" должно привести к -62135596800
- "2999-12-31" должен в результате 32503593600
EDIT 1
Я также попытался следующие Java 6 код:
final TimeZone tz = TimeZone.getDefault();
Long seconds = (dateObject.getTime() + tz.getRawOffset())/1000;
Это работает с "2010-01-01" и "2999-12-31", но не с "0001-01-01" (ожидается: -62135596800, фактический: -62135769600) - догадайтесь недостатком «setGregorianChange» является то, что неприятности здесь.
РЕДАКТИРОВАТЬ 2
Код работает в JsonSerializer. У меня есть приложение, представляющее эти временные метки UNIX внутри JSON. Сторона-потребитель ожидает отметки времени как отметки времени по Гринвичу и создаст дату по этим временным шкафам, жестко привязывающим часовой пояс к GMT, но используя его позже, как там, где местный часовой пояс.
Чтобы сделать проблему более понятной, я приведу пример.
- Дата на моей стороне: 2010-01-01 (UTC + 100)
- миллисекунды: 1262300400000
- секунд: 1262300400
потребитель теперь занимает это секунд и формирует дату из из него:
- чт, 31 декабря 2009 23:00:00 GMT
Конечно - это на 100% верно, но потребитель использует эту дату, как если бы она находилась в локальном часовом поясе ...
Секунды, которые, как я предполагаю, будут перенесены, - 1262300400 + 3600 (мой TZ Offset) для этого примера.
EDIT 3
Я получил GregorianCalendar
-thing вниз к 4liner - но даже это гораздо медленнее, чем Java 8 вещь. Проблема заключается в создании нового объекта GregorianCalendar
каждый раз, когда выполняется код. Но это обязательный факт, поскольку Calendar
не является потоковым. Таким образом, быстрое решение должно каким-то образом работать без какого-либо объекта-инстанцирования. Пример ниже в основном похож на EDIT 1 и даже быстрее, чем код Java 8. Он просто не работает правильно с датами до юлианско -> григорианского переключателя (15 октября - 1582).
public class UnixTimestampSerializer extends JsonSerializer<Date> {
@Override
public void serialize(final Date dateObject, final JsonGenerator jgen, final SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeNumber((dateObject.getTime() - dateObject.getTimezoneOffset() * 60 * 1000)/1000)
}
}
Unfortunally он работает) с устаревшим методом и б) правильно не работает с датами, прежде чем 1582 :(. Использование статического TimeZone.getDefault().getRawOffset()
для решения а) не вариант, так как TimeZone может измениться (лето - против зимы) на каждую дату.
Я хочу быть «тот парень» и спросить, если вы пробовали время Joda http://www.joda.org/joda-time? –
Почему вы получаете экземпляр календаря и продолжаете создавать * другой * GregorianCalendar, полностью игнорируя полученный ранее календарь. Начните с удаления мертвого кода? – Durandal
@ DamienO'Reilly - Я хочу решение без каких-либо зависимостей. – Olli