2014-10-20 50 views
1

分配在我WPF .NET客戶端應用程序我分配一個DateTime變量的當前時間值:保持.NET DateTime值在服務器客戶端

class MyClass 
{ 
    public DateTime CreatedDate {get; set;} 
} 

MyClass myClass = new MyClass(); 
myClass.CreatedDate = DateTime.Now; 

任務後我對象發送到位於歐洲的WCF服務(UTC + 1)將對象保存在數據庫中。如果客戶和服務在同一TimeZone沒有問題。但是,如果我更改TimeZone,例如我的客戶端位於(UTC-6)並且服務位於(UCT + 1),則該服務將讀取CreatedDate值,因爲它是DateTime.Now服務(UCT + 1) (UCT-6)在客戶端分配。如果在客戶端(UTC-6)設置了CreatedDate,則2014年10月31日的20:00服務中將存儲爲(UTC + 1)01/11/2014 at 01:00並且此影響我係統上的一些進程。

這不是我想要的行爲,我希望服務始終按照客戶提交的方式存儲該日期。

我有機會爲服務器和客戶端的代碼,我試圖設置分配CreatedDate當:沒有運氣

myClass.CreatedDate = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Unspecified); 

。我能想到的唯一解決方案是使用字符串而不是DateTime,但這意味着代碼中的很多更改。任何人都知道一種方法來忽略TimeZone設置?

+3

你爲什麼不把'DateTime'存儲在UT中?每個客戶端都將「看到」當地時間(當您在可視化中轉換爲字符串時,例如您在StackOverflow中看到的內容)。作爲替代方法(保留每個時區的時區),您可以使用「DateTimeOffset」。總的來說......從來沒有想過在有更好的類型時使用字符串...... – 2014-10-20 13:48:03

+2

記錄您的服務並聲明它只應發送utc-values,並且只會返回utc值。讓用戶界面處理轉換。看看http://nodatime.org/這是甜蜜的甜美音樂,以datetime損壞的耳朵... – sisve 2014-10-20 13:50:34

+0

感謝您的提示!然而,我有點失去了UTC。如果(UTC + 6)中的客戶端在20:00在31/10/2014存儲了CreatedDate,則服務以UTC讀取的值仍然是01/11/2014在00:00,對吧? – CiccioMiami 2014-10-20 13:59:53

回答

4

您有幾種不同的選擇:

  • 保留一切爲DateTime,但與UTC值,而不是本地值工作。這意味着使用DateTime.UtcNow獲取當前時間。

    在客戶端上,您可以使用ToLocalTime生成一個顯示值,將UTC的值轉換爲運行客戶端代碼的計算機的本地時區。

  • 切換到DateTimeOffset。這可以確保將值從客戶端傳輸到服務器時,您可以保留時區偏移量 - 這會告訴您距UTC有多遠,該特定時間戳記是。

    您可以使用DateTimeOffset.UtcNowDateTimeOffset.Now獲取當前時間。後者具有保留當地時間的優點,因爲客戶可以理解它。如果您打算根據當地日期/時間對數據進行任何彙總分析,那麼您將需要這一信息。請記住,「今天」對地球上的每個人都是不一樣的。

  • 如果你有另一種方式來溝通客戶端的時區,或者如果你知道這一點已經從外部的信息,那麼你就可以傳輸要麼一個DateTimeDateTimeOffset,然後使用TimeZoneInfo類做服務器上的轉換。

    然而,有一個「陷阱」。如果您發送的模糊時段(在「後退」轉換期間)的本地DateTime,則可能會發生錯誤轉換。使用UTC或DateTimeOffset將避免此問題。

又見The Case Against DateTime.NowDateTime vs DateTimeOffset

+0

偉大的答覆,你讓一切變得清晰並給出了幾個解決方案。非常感謝你! – CiccioMiami 2014-10-21 11:37:20