2013-04-18 48 views
0

我在我們現有的應用程序中面臨一個問題,即員工(從他的組織/商店使用時鐘應用程序)輸入的時間首先轉換爲GMT,然後存儲在數據庫中。並且爲了顯示回來,格林威治標準時間將轉換回存儲本地時區並顯示。在大多數情況下,這種情況可以很好地工作,但當時區轉移到DST時,反之亦然。轉換到GMT在DST期間給出問題

讓我更具體。假設商店的標準時區爲格林威治標準時間8,而員工在早上8點上午打卡,所以時間轉換爲格林威治標準時間,格林威治標準時間爲16:00,然後存儲在數據庫中。 轉換過程首先將此08:00 AM轉換爲本地時間,以某種方式給出 17:00 CET,然後將17:00 CET轉換爲格林威治標準時間,即16:00 CET。

但是,如果我們舉一個3月31日的例子,當夏令時發生在02:00 AM變成03:00 AM時。假設emplyoee在18:00(3月30日)出拳,它會在第一次轉換爲本地時返回我04:00 AM CEST,然後當我將其轉換爲GMT時,它會給出03:00 CEST。所以在將它轉換回來時,這給出了19:00,這是不正確的。 設計說當地時間轉換爲UTC然後存儲在數據庫中,但如果它仍然是UTC,那麼它應該存儲02:00 AM而不是03:00 AM,因爲GMT/UTC沒有DST。

用於執行轉換的代碼是:

步驟1

final Date localPunchDateTime = R3ValConverter.convertFromTimeZone(teData.m_dtTm, 
               TimeZone.getTimeZone("GMT-8")); 

步驟2

teData.m_dtTm = R3ValConverter.convertToGMT(localPunchDateTime); 

R3ValConverter.java

public static Date convertFromTimeZone(final Date dtSrc, final TimeZone tzSrc) 
    { 

     final SISDateTime dtTmTemp = new SISDateTime(dtSrc, TimeZone.getDefault()); 
     final SISDateTime dtTmSrc = new SISDateTime(dtTmTemp.getYear(), dtTmTemp.getMonth(), 
                dtTmTemp.getDate(), dtTmTemp.getHour(), 
                dtTmTemp.getMinute(), dtTmTemp.getSecond(), 
                tzSrc); 

     return dtTmSrc.toDate();              
    } 

SISDateTime

GregorianCalendar m_cal; 

public SISDateTime(Date dt, TimeZone tz) throws SISDateTimeException 
    { 

     m_cal = new GregorianCalendar(tz); 
     m_cal.setTime(dt); 
     resetMillis(); 
    } 

另一SISDateTime方法也使用相同的GregorianCalendar。

我真的很感謝這方面的幫助。我在這裏假設我們在第一步有一些問題,但目前還不知道有什麼好的解決方案。

回答

0

您必須在數據庫中存儲從本地時間到UTC的UTC +當前偏移量。 所以,如果你想保護當地的時候,你總是需要一對(UTC時間,偏移)

然後TimezoneWithOffsetFromGMT您可以使用(或simmiliar命名)

+0

我們的偏移量在標準時間7 8在夏令時,但如果我拿我的例子,我們在18:00有衝,並將其存儲爲03:00 AM(轉換爲格林威治標準時間後),然後在轉換期間它不起作用,因爲03:00 - 8(偏移量)給出19: 00 .. – user2293813 2013-04-18 09:01:23

+0

你不應該將它存儲爲03:AM,你應該將它存儲爲長時間值utc自1.1.1970(unix時間)以來的毫秒或秒數 – AlexWien 2013-04-18 09:41:43

+0

在18:00和3 AM之間有9小時,而不是8! – AlexWien 2013-04-18 09:44:58