2012-06-04 33 views
0

讓我先給大家簡單介紹一下我們的應用程序! (請不要立即關閉我的大帖子,它很簡單的場景,我只是描述!)我們有一個ASP.NET網站,主要是C#,它充當我們所有商店的商店前臺特許經營權。服務器上的ASP.NET時間轉換(夏令時)

每家商店可能位於不同的時區,但我們需要在我們的網站上指明商店是開放還是關閉。

服務器有一個DB,其中包含的行可以指示不同商店的不同時間表,可以在我們的asp.net網站上顯示。

在我的數據庫中,我有保存位置偏移量的列和行,並以UTC存儲小時。例;

  • LocationID:21
  • 的timezoneoffset:-5:00
  • SundayOpen:15:45
  • SundayClose:16:20

我想出了一種方法來確定服務器如果位置是否打開。我有一個艱難的時間來確定它是否可以與夏令時一起使用。我的問題是,這是否代表夏令時,並且我是否正確地處理了這種情況,因爲我沒有像這樣的時間處於保密狀態?

這是我在我的服務器端代碼中做的事情;

//這裏是我的課的重要組成部分,我用它來從DB

持有存儲調度
public class TimeSchedule 
{ 
    public TimeSpan locationOffset { get; set; } 
    public TimeSpan sundayOpen { get; set; } 
    public TimeSpan sundayClose { get; set; } 

    public TimeSchedule() 
    { 
     locationOffset = new TimeSpan(); 
     sundayOpen = new TimeSpan(); 
     sundayClose = new TimeSpan(); 
    } 

} 

//I have loaded a TimeSchedule object by id 
TimeSchedule schedule = location.getTimeScheduleByLocationID(21); 

// Get the UTC time 
DateTime utcNow = new DateTime(); 
utcNow = DateTime.UtcNow; 

//Get the offset value that we stored in our schedule object 
TimeSpan locationOffSetHour = schedule.locationOffset; 

//I then apply the location offset hour to the server utc time. 
DateTime locationTime = new DateTime(); 
locationTime = utcNow.Add(locationOffSetHour); 

// Get the day of the week from our locationTime that we off setted from UTC 
string LocationWeekDay = locationTime.DayOfWeek.ToString(); 

// Now for each case of week day, I check to see if the difference in time is >= 0 
// If so I assume the store is open 



TimeSpan zeroDifference = new TimeSpan(0, 0, 0); 


    // This switch case just gets the difference in time according to LocationTime (that we offset'd from UTC) and stored time for the location on the server. 
    // Then verifies that the location is open for that day 
    switch (LocationWeekDay) 
     { 
      case "Sunday": 
       // Verify that location is open, turn on open sign 
       TimeSpan differenceOpenTimeSun = new TimeSpan(); 
       differenceOpenTimeSun = locationTime.TimeOfDay - schedule.sundayOpen; 

      TimeSpan differenceCloseTimeSun = new TimeSpan(); 
      differenceCloseTimeSun = schedule.sundayClose - locationTime.TimeOfDay; 

      if (differenceOpenTimeSun >= zeroDifference && differenceCloseTimeSun > zeroDifference) 
      { 

       imgSign.ImageUrl = "~/SiteImages/open.jpg"; 
      } 
      else 
      { 
       imgSign.ImageUrl = "~/SiteImages/closed.jpg"; 
      } 
      break; 
} 

感謝您抽出時間來看看我的解決方案!任何「單挑」或「禁止」都將不勝感激!在你的程序代碼

回答

2

重構了自由。不是說我將盡一切正是這樣,因爲我可能會在非規範化數據庫中的打開和關閉值,但是......這裏是......

//I have loaded a TimeSchedule object by id 
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(schedule.LocationId); 

// Get the UTC time 
DateTime utcNow = DateTime.UtcNow; 

//I then apply the location offset hour to the server utc time. 
DateTime currentUtcTime = DateTime.UtcNow; 
DateTime locationTime = TimeZoneInfo.ConvertTimeFromUtc(currentUtcTime, tzi); 

// Get the day of the week from our locationTime that we off setted from UTC 
string locationWeekDay = locationTime.DayOfWeek.ToString(); 

// Now for each case of week day, I check to see if the difference in time is >= 0 
// If so I assume the store is open 
TimeSpan zeroDifference = new TimeSpan(0, 0, 0); 

// This switch case just gets the difference in time according to LocationTime (that we offset'd from UTC) and stored time for the location on the server. 
// Then verifies that the location is open for that day 
switch (locationWeekDay) 
{ 
    case "Sunday": 
      // Verify that location is open, turn on open sign 
      TimeSpan differenceOpenTimeSun = currentUtcTime.TimeOfDay - schedule.sundayOpen; 
      TimeSpan differenceCloseTimeSun = schedule.sundayClose - currentUtcTime.TimeOfDay; 

      if (differenceOpenTimeSun >= zeroDifference && differenceCloseTimeSun > zeroDifference) 
      { 

      imgSign.ImageUrl = "~/SiteImages/open.jpg"; 
     } 
     else 
     { 
      imgSign.ImageUrl = "~/SiteImages/closed.jpg"; 
     } 
     break; 

}

+0

感謝一大堆。 TimeZoneInfo類正是我正在尋找的。我認爲.NET可能比我更好地處理DST。雖然,schedule.LocationID不是時區,但我想我可以調整它以適應。在我嘗試完成後會更新你! – clamchoda

+0

對不起,花了我很長時間纔回到這裏,我的盤子上有一堆。這正是我正在尋找的,謝謝。 – clamchoda

1

以下行正在處理時區和獲取本地時間:

// Get the UTC time 
DateTime utcNow = new DateTime(); 
utcNow = DateTime.UtcNow; 

//Get the offset value that we stored in our schedule object 
TimeSpan locationOffSetHour = schedule.locationOffset; 

//I then apply the location offset hour to the server utc time. 
DateTime locationTime = new DateTime(); 
locationTime = utcNow.Add(locationOffSetHour); 

但是,這段代碼是處理只需要添加時區偏移值,並沒有在那裏照顧的DST。

所以,如果你想獲得DST也有兩個選項供您:

  1. 使用數據庫每個地方的DST週期的列,並完成一個邏輯得到查找是否當前在該地區的日期是在DST期間,並且相應地在DST中進行更改。
  2. 此選項可以,如果你使用的是.NET 3.5及以上應遵循:

    的DateTime東部= TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.UtcNow, 「東部標準時間」);

    TimeZoneInfo類僅在.NET 3.5起可用。

0

一些建議和意見...


看看C#TimeZoneInfo類。 http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx

它包含一些方法,將使您的時區轉換爲準確。例如,不是將TimeZoneOffset存儲在數據庫中,而是存儲TimeZoneId。然後使用...

TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(string id); 

然後,而不是..

locationTime = utcNow.Add(locationOffSetHour); 

你可以做...

DateTime locationTime = ConvertTimeFromUtc(utcNow, tzi) ; 

獲取本地時間。這將爲您提供更準確的偏移量,因爲它支持夏令時。

查看所有其他代碼,並查看TimeZoneInfo類是否包含您可以使用而不是滾動自己的屬性和方法。


你也不需要初始化值,然後立即將其覆蓋...

// Change this... 
DateTime utcNow = new DateTime();     
utcNow = DateTime.UtcNow;   

// to this... 
DateTime utcNow = DateTime.UtcNow;   

// and this... 
TimeSpan differenceOpenTimeSun = new TimeSpan();    
differenceOpenTimeSun = locationTime.TimeOfDay - schedule.sundayOpen; 

// to this... 
TimeSpan differenceOpenTimeSun = locationTime.TimeOfDay - schedule.sundayOpen; 

// etc... 

你說你是儲存一天的時間在UTC在數據庫中。我假設你正在轉換爲本地時間超出此代碼,因爲你正在做這個地方......

​​

你可以考慮使用UTC時間爲兩個值,所以你不必計算差值之前做轉換。

您可能還需要進行時區轉換以確定星期幾,但您不必執行轉換來確定商店是打開還是關閉。


您並未真正使用標準命名約定。不是必需的,但我會建議微軟標準作爲起點。更容易爲人們在計算器上提問的時候讀取的代碼:)

http://msdn.microsoft.com/en-us/library/ff926074.aspx

希望這有助於你。