2017-06-08 45 views
2

我正面臨時區問題。現在我從客戶端保存時區並以UTC存儲所有DateTime。它工作正常,但是當我試圖將CST,EST,EDT等時區後面的UTC轉換爲UTC時,它會顯示錯誤的數據。Asp.Net中的TimeZone問題MVC

問題 - 讓我們假設,如果我做任何任務,在晚上10點EDT,它會爲凌晨2點(根據UTC)被保存在數據庫,但是當我試圖一天獲取數據並傳遞當前UTC日期。

我的問題是如果我試圖從像午夜11點(從EST)到當前時間的數據獲取數據,但由於UTC而導致UTC到EST的轉換錯誤12 PMnight是昨天晚上8點(如EDT後4小時來自UTC)。 (從日期[UTC轉換爲EDT] - 06/07/2017 08:00 pm)和截止日期 - 2017年6月7日11:00 pm)由於此轉換,我只能從晚上8點到晚上11點獲取數據< - 我期待從日期06/07/2017 04:00 AM按照UTC。

代碼 - 以下是轉換代碼。

function setTimezoneCookie() { 
      try { 
       var timezone_cookie = "timezoneoffset"; 
       var timeZoneName = "timezonename" 

       var tz = jstz.determine(); 
       var aa = tz.name(); 
       // if the timezone cookie not exists create one. 

       if (!$.cookie(timezone_cookie)) { 
        // create a new cookie 
        $.cookie(timezone_cookie, new Date().getTimezoneOffset()); 
        $.cookie(timeZoneName, aa); 
       } 
       else { 
        var storedOffset = parseInt($.cookie(timezone_cookie)); 
        var currentOffset = new Date().getTimezoneOffset(); 
        if (storedOffset !== currentOffset) { 
         $.cookie(timezone_cookie, new Date().getTimezoneOffset()); 
         $.cookie(timeZoneName, aa); 
         location.reload(); 
        } 
        else { 
         $.cookie(timeZoneName, aa); 
        } 
       } 
      } 

C#代碼 - - 從日期我只和一個日期

Javascript代碼採取utcnow.date

fromDate =Convert.ToDateTime(fromDate).ToClientTimeZoneinDateTime().ToString(); 
       toDate = Convert.ToDateTime(toDate).ToClientTimeZoneinDateTime().ToString(); 

       ObjectParameter totalRecords = new ObjectParameter("TotalRecords", typeof(int)); 
       var DetailsList = objDetailsList.GetDetails(loginUserId,locationId, userId, taskType, pageIndex, numberOfRows, sortColumnName, sortOrderBy, textSearch, totalRecords, fromDate, toDate); 
       if (DetailsList.Count() > 0) 
       { 
        string output = BuildJQGridResults(DetailsList, numberOfRows, pageIndex, Convert.ToInt32(totalRecords.Value)); 
        response.Write(output); 
       } 
       else 
       { 
        JQGridResults result = new JQGridResults(); 
        List<JQGridRow> rows = new List<JQGridRow>(); 
        result.rows = rows.ToArray(); 
        result.page = 0; 
        result.total = 0; 
        result.records = 0; 
        response.Write(new JavaScriptSerializer().Serialize(result)); 
       } 

下面是轉換UTC時間的方法到客戶端時區

public static DateTime ToClientTimeZoneinDateTime(this DateTime dt) 
{ 
    try {    
     if (System.Web.HttpContext.Current.Request.Cookies["timezoneoffset"] != null || System.Web.HttpContext.Current.Request.Cookies["timezonename"] != null) 
     {     
      var timezonename = System.Web.HttpContext.Current.Request.Cookies["timezonename"].Value; 
      timezonename = timezonename.Replace("%2F", "/"); 
      var timezoneLocal1 = FindTimezoneName(timezonename); 
      TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(timezoneLocal1); 
      bool isCurrentlyDaylightSavings = tzi.IsDaylightSavingTime(dt); 
      if (isCurrentlyDaylightSavings == true) 
       dt.AddHours(1); 

      var timeOffSet = System.Web.HttpContext.Current.Request.Cookies["timezoneoffset"].Value; 

      var offset = int.Parse(timeOffSet.ToString()); 
      dt = dt.AddMinutes(-1 * offset);     
      return dt; 
     }    
     return dt.ToLocalTime(); 
    } 
    catch (Exception) 
    { 
     return DateTime.UtcNow; 
    } 
} 

毫無疑問,當時區正確處理,但如果最終用戶試圖在美國東部時間晚上8點之後嘗試獲取數據,則會面臨UTC時區之後的問題。我也附上了截圖。

下面的IMG轉換前 - enter image description here

如何,我需要處理這種情況 - enter image description here

以上的IMG轉換後?

+1

你能提供一個[mcve]你的代碼和'DateTime'的轉換嗎? – gravity

+0

http://blog.nodatime.org/2011/08/what-wrong-with-datetime-anyway.html – adPartage

+0

這聽起來像你的查詢使用錯誤的日期。請記住,查詢中的日期也應使用UTC。發佈一些示例代碼以獲得更好的答案 –

回答

1

主要問題是您正在轉換錯誤的方向。您正在將UTC轉換爲用戶的時區,但您的輸入位於用戶的時區,因此您需要將另一個方向 - 從用戶的時區轉換爲UTC。然後您的查詢將顯示更好的結果。

一些其他的東西:

  • 不要試圖通過手動加/減分或小時轉換時區。使用TimeZoneInfo上提供的轉換功能,如ConvertTimeFromUtc,ConvertTimeToUtc等。不需要測試DST。

  • try/catch不應該在你的代碼中。如果無法執行操作,則拋出異常。不要通過吞嚥異常來掩蓋重要的錯誤。

  • dt.ToLocalTime()不應該在你的代碼中。永遠不要依靠服務器的本地時區。

  • 的偏移new Date().getTimezoneOffset()返回是用戶的當前偏移。你不能假設它是所選日期的正確偏移量。不管怎樣,你已經得到了時區名稱。 (您不需要timezoneoffset餅乾都沒有。)

  • 通過jstz.determine()在客戶端返回的時區名稱將是一個IANA TZDB標識符,如America/Los_Angeles。這些不能在服務器端使用TimeZoneInfo.FindSystemTimeZoneById(除非您在Linux或Mac上運行.NET Core)。轉換到Windows時區是必需的。我看到你有一個FindTimeZoneName函數,我認爲它正在執行轉換。您沒有在代碼中顯示詳細信息,但我強烈建議您使用我的TimeZoneConverter庫實現該功能,因爲它隨時區更改而保持不變。

  • 讀取Cookie和時區轉換是單獨的問題。不要將它們捆綁在一起。

最後,你應該有這樣的事情:

public static DateTime FromTimeZoneToUtc(this DateTime dt, string timeZone) 
{ 
    var windowsId = TimeZoneConverter.TZConvert.IanaToWindows(timeZone); 
    var tzi = TimeZoneInfo.FindSystemTimeZoneById(windowsId); 
    return TimeZoneInfo.ConvertTimeFromUtc(dt, tzi); 
} 

,或者甚至更好,如果你使用Noda Time,那麼你就需要轉換時區的。

public static DateTime FromTimeZoneToUtc(this DateTime dt, string timeZone) 
{ 
    var tz = DateTimeZoneProviders.Tzdb[timeZone]; 
    var local = LocalDateTime.FromDateTime(dt); 
    return local.InZoneLeniently(tz).ToDateTimeUtc(); 
} 
+0

我需要根據用戶的時區將UTC時間傳遞給數據庫,例如EDT UTC的凌晨4點是凌晨4點。由於用戶的開始時間是UTC 4 am,因此我需要根據用戶時區在凌晨4點通過UTC。 –

+0

是的,沒錯。您需要從本地轉換爲UTC。這就是我的答案告訴你如何去做的。 –

+0

我已經做了更改,但它顯示我錯誤的轉換。 Ex - UTC(06/12/2017 12:00 AM)至(06/11/2017 04:00 AM)。 但是我想轉換爲美國東部時間的開始日期,即06/11/2017 04:00 AM。 毫無疑問,轉換是真實的UTC(06/12/2017 12:00 AM) 是(06/11/2017 08:00 PM) 請問我可以如何處理這種情況? –