2011-07-12 27 views
4

我從未創建過提醒應用程序。這是我如何看待它。如果我的方式正確,請讓我知道。如何在正確的時間爲不同時區的用戶發送提醒?

所以我有來自不同時區的用戶。

ID   DateTimeUTC    TimeZoneID    

1   2011-07-12 02:15:15.000 TimeZneID1 
2   2011-07-13 16:00:00.000 TimeZneID2 
3   2013-11-03 17:00:00.000 TimeZneID3 
4   2011-08-22 03:00:00.000 TimeZneID4 
5   2011-07-16 22:00:00.000 TimeZneID5 

創建計劃的進程來運行,每15分鐘,做下面的步驟:

  1. 獲取記錄;
  2. 第二個是將DateTimeUTC轉換爲正確時區的時間
  3. 比較是否匹配
    a。發送提醒
    var tzi = TimeZoneInfo.FindSystemTimeZoneById(TimeZneID1);
    var local = TimeZoneInfo.ConvertTimeFromUtc(DateTimeUTC, tzi);
    var timeNow = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Now, tzi);
    if(local == timeNow)
    SendReminder();

它是有效的方式嗎?這是正確的方式嗎?

回答

8

如果數據庫中的日期/時間值已經是UTC,則不需要執行任何轉換,當然......您只需要查看當前UTC時刻是否匹配,如果是,發送提醒。

這就是假設你確實是這意味着它是數據庫中的UTC,即你已經從用戶輸入提醒時的當地時間(假設他們這樣做開始)轉換它。

+0

好的,非常感謝你 –

+0

爲了再次強調Jon的觀點 - 如果你希望在將數據從數據庫中提取出來時能夠進行這種日期數學計算,則必須將時間轉換爲UTC,然後再將其存儲到數據庫中數據庫。 –

1

在我看來,你可能會過度複雜化它。由於您正在以UTC格式存儲內容,因此請以UTC格式提醒,並在UTC時間內進行匹配。然後,只需將提醒與要提醒的用戶相關聯即可。

1

通常情況下,在處理像這樣的日期時,您可以使用UTC進行所有計算,並且只需在時間(無雙關語)的情況下切換到本地時間即可顯示結果。我從你的問題中假設這是一個管理所有任務的中央數據庫,你只需要它們在當地正確的時間運行?

if (dateTimeUtc == DateTime.UtcNow) 
{ 
    // If your reminder needs to display the local time, pass it in: 
    var tzi = TimeZoneInfo.FindSystemTimeZoneById(TimeZneID1); 
    SendReminder(TimeZoneInfo.ConvertFromUtc(DateTime.UtcNow, tzi)); 
} 

注意DateTime.Now本地時間;你想要DateTime.UtcNow跨時區的一致性。

另一件需要注意的事情是你每15分鐘只能運行你的任務調度程序,所以像02:15:15匹配的機率恰好很小。你通常會希望做的是檢查上次運行以來想出了任何提醒時間:

var currentRun = DateTime.UtcNow; 
foreach (dateTimeUtc in GetReminderDateTimes()) 
{ 
    if (dateTimeUtc > lastRun && dateTimeUtc <= currentRun) 
    { 
    } 
} 
lastRun = currentRun; 
+0

+1提及尋求*確切*匹配的問題。 –

0

我想要做類似的東西,並一直在爭論什麼是適當的做法。從本質上講,我正在撰寫一個應用程序,可以在午夜(當地時間)爲特定國家發送消息。我有大約100個這樣的國家,我也必須注意夏令時。我只能想到2種方法, 1.爲每個國家創建相應的線程,並且每隔一小時左右醒來一次,並檢查是否是午夜(當地時間)併發送消息。所以基本上,我將在大多數時間創建100個無所事事的線程。 2.在這種方法中,只有一個定時器可以檢查100個國家的每分鐘或30秒的本地時間併發送消息。這將需要一些額外的邏輯,因爲永遠不會有精確的午夜比賽。 不確定,如果有更好的方法來解決上述情況。如果我能在這裏得到一些想法/建議,那將是非常好的。 謝謝, SP。

相關問題