2012-05-11 2 views
3

Даже с около 15 лет в Java всегда натыкается на тему работы с датами и времени ...даты Синтаксической с разными часовыми поясами

Вот ситуация: я получаю временную метку от некоторой внешней системы в качестве String представления , Семантика временной метки состоит в том, что она представляет дату UTC. Эта метка времени должна быть помещена в объект, а затем в базу данных PostgreSQL в поле TIMESTAMP. Кроме того, мне нужно поставить ту же метку времени, что и местное время (в моем случае CEST), в объект, а затем в базу данных в поле TIMESTAMP WITH TIME ZONE.

Каков правильный способ гарантировать, что независимо от того, какие настройки машины выполняются в коде, отметки времени сохраняются правильно в сущности (чтобы сделать некоторые проверки с другими отметками времени UTC) и в базе данных (для использования их в отчетах позже)?

Вот код, который отлично работает на моей локальной машине:

SimpleDateFormat sdfUTC = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); 
sdfUTC.setTimeZone(TimeZone.getTimeZone("UTC")); 
Date utcTimestamp = sdfUTC.parse(utcTimestampString); 
// getMachinesTimezone is some internal util method giving the TimeZone object of the machines Location 
Calendar localTimestamp = new GregorianCalendar(getMachinesTimezone()); 
localTimestamp.setTimeInMillis(utcTimestamp.getTime()); 

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

PS: Я читал о времени Джоды при поиске в этом форуме, но в данном проекте я не могу представить новые библиотеки, так как я меняю только существующий модуль, поэтому мне нужно жить со стандартным JDK1.6

+0

Hi Geziesfer, если вы не получили ответ, который вы ищете, подумайте над тем, чтобы добавить несколько примеров фактических результатов, которые вы получали, как на локальном компьютере, так и на сервере. Это даст нам еще больший контекст проблемы. +1 для хорошо написанного, аккуратного и грамматически правильного вопроса! – jmort253

+0

Кажется глупым хранить одну и ту же дату в базе данных – stew

+0

@stew: Ну, я не из тех, кто судит о глупости существующей системы, но причина в том, что утверждение, которое позже приводит к отчету иметь utc и локальное время непосредственно в качестве входных параметров, а не вычислять его в этой точке. –

ответ

0

Я думаю, вы должны установить целевой часовой пояс в своем календарном объекте. Я думаю, что-то вроде:

Calendar localTimestamp = new GregorianCalendar(TimeZone.getTimeZone("GMT+10")); 
localTimestamp.setTimeInMillis(utcTimestamp.getTime()); 

В другом случае Java принимает системный часовой пояс по умолчанию для экземпляра календаря.

+0

Хорошо, я адаптировал это в приведенном выше коде - все равно он не будет работать так, как ожидалось на сервере. –

+0

@ Geziefer Можете ли вы сказать о появлении проблемы. В базе данных или уже в java? – sebastian

+0

Кажется, что он правильно хранится в базе данных, поскольку я вижу неправильную метку времени при отладке. –

6

Если я правильно понял, вам нужно установить часовой пояс на том же объекте данных/календаря, который вы печатаете. Например:

private Locale locale = Locale.US; 
private static final String[] tzStrings = { 
    "America/New_York", 
    "America/Chicago", 
    "America/Denver", 
    "America/Los_Angeles", 
}; 

    Date now = new Date(); 
    for (TimeZone z : zones) { 
     DateFormat df = new SimpleDateFormat("K:mm a,z", locale); 
     df.setTimeZone(z); 
     String result = df.format(now); 
     System.out.println(result); 
    } 

Если я установил часовой пояс для SimpleDateFormat, он работает нормально.

вот пример кода ...

String date="05/19/2008 04:30 AM (EST)"; 
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm aaa (z)"); 
TimeZone.setDefault(TimeZone.getTimeZone("PST")); 
long millis = sdf.parse(date).getTime(); 
sdf.setTimeZone(TimeZone.getDefault()); 
System.out.println(sdf.format(new Date(millis))); 
+0

Дело в том, что я его не печатаю, но сохраняю его. В приведенном выше ответе я изложил то, что, по моему мнению, странно. –

+0

У меня была аналогичная проблема с стартером темы: у меня была дата в виде строки и я хотел разобрать ее как дату в часовом поясе utc. Используя SimpleDateFormat и установив свой часовой пояс как utc через 'sdf.setTimeZone (TimeZone.getTimeZone (« UTC »)), было недостаточно. Парсер все еще использовал свое местное время. Что трюк использовал «TimeZone.setDefault» (TimeZone.getTimeZone («UTC»)). Так спасибо за ваш ответ. – Torsten

0

Вы можете сделать это, в приведенном ниже примере кода.

Date date = new Date(); 

DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z"); 
formatter.setTimeZone(TimeZone.getTimeZone("CET")); 

Date date1 = dateformat.parse(formatter.format(date)); 

// Set the formatter to use a different timezone 
formatter.setTimeZone(TimeZone.getTimeZone("IST")); 

Date date2 = dateformat.parse(formatter.format(date)); 
// Prints the date in the IST timezone 
// System.out.println(formatter.format(date)); 
+0

Проблема в том, что я не пришел с даты, как в вашем примере, но из строки, например. "2012-01-01T12: 00: 00,000". Теперь, когда я разбираю это в DF в UTC и сохраняю его в db postgreSQL через объект JPA в поле TIMESTAMP, это приводит к неправильной метке времени: «2012-01-01 13:00:00». Машина выполняется в GMT. Если я переключусь на местное время (CET), он производит что-то другое. И это то, чего я не понимаю, так как у меня есть данная строка и она должна быть отформатирована как UTC. –

+0

Он будет отформатирован в формате UTC. –

+0

@BhavikAmbani Вы пробовали это с разбором строки, как упоминал Гезифер? Это не сработало для меня ни с помощью вашего метода. – Torsten

Смежные вопросы