32

「オンライン リマインダー システム」プロジェクトに取り組んでいます (ASP.NET 2.0 (C#) / SQL Server 2005)

これは、特定の日付にユーザーにメールを送信するリマインダー サービスです。しかし問題は、ユーザーが特定の国から来たのではなく、世界中から、異なるタイム ゾーンから来たことです。ここで、登録時に、Windows がインストール時にタイム ゾーンを尋ねるのと同じ方法で、ユーザーのタイム ゾーンを尋ねます。

しかし、ユーザーが (+5.30) または何かのタイムゾーンを選択した場合、asp.net アプリケーションでこのタイムゾーンを処理する方法を取得できません。タイムゾーンに合わせた働き方。

そして、このアプリケーションでタイムゾーンを処理するためのより良い方法があれば提案してください??

ありがとう

4

7 に答える 7

29

まず、データがどのタイム ゾーンにあるかを確認します。保存する DateTime が UTC 時間で保存されていることを確認することをお勧めします (を使用しDateTime.ToUniversalTime()て取得します)。

ユーザーのリマインダーを保存する場合は、現在の UTC 時刻が必要になり、ユーザーのタイム ゾーンの差を追加または削除し、その新しい時刻を UTC に戻す必要があります。これがDBに保存したいものです。

次に、送信するリマインダーを確認したい場合は、UTC 時間に従って、今すぐ送信するリマインダーをデータベースで検索するだけです。基本的に、タイムスタンプが より前のすべてのリマインダーを取得しますDateTime.Now.ToUniversalTime()

いくつかの実装の詳細を更新TimeZoneInfo.GetSystemTimeZones()します。メソッドからタイム ゾーンのリストを取得できます。これらを使用して、ユーザーのタイムゾーンのリストを表示できます。Id選択したタイム ゾーンからプロパティを保存すると、そこから TimeZoneInfo クラス インスタンスを作成し、特定のローカル日付/時刻値の UTC 時刻を計算できます。

TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("<the time zone id>");
// May 7, 08:04:00
DateTime userDateTime = new DateTime(2009, 5, 7, 8, 4, 0);
DateTime utcDateTime = userDateTime.Subtract(tzi.BaseUtcOffset);
于 2009-05-07T05:24:15.603 に答える
19

サーバー側 (コード ビハインド、データベースなど) では常に UTC (GMT) 時間を使用し、表示のみを目的として時刻を UTC から現地時間に変換することをお勧めします。つまり、データベースでの時間の節約、計算の実行など、すべての時間操作は UTC を使用して行う必要があります。

問題は、コード ビハインドがクライアント ブラウザーのタイム ゾーンをどのように認識するかということです。ユーザーがフォームに日付/時刻の値 ( 12/30/2009 14:30など) を入力し、それをサーバーに送信したとします。ユーザーが現地時間を送信したと仮定すると、サーバーはこの値を UTC に変換する方法をどのように知るのでしょうか?

アプリケーションはユーザーにタイム ゾーンを指定する (そしてそれを永続的な Cookie またはデータベースに保存する) ように求めることができますが、それにはユーザーの余分な労力が必要であり、アプリはそのためのロジックと画面を実装する必要があります。アプリがクライアントのタイム ゾーンを自動的に判断できればもっといいでしょう。

私は JavaScript のgetTimezoneOffset関数を利用してこの問題に対処しました。これは、クライアントの現地時間と GMT の時差をサーバーに伝えることができる唯一の API です。これはクライアント側 API であるため、次のことを行いました。サーバー側で、タイム オフセット値を保持するカスタム セッション Cookie をチェックし、それが利用できない場合は、ページをリロードします (POST 呼び出しではなく GET 呼び出し中のみ)。タイム オフセットを生成して Cookie に保存するための JavaScript ロジックが追加されています。クライアント側からは、これはほとんど透過的です (セッション中に一度、GET でページをリロードします)。Cookie にオフセットを取得したら、時間変換の方向 (UTC から現地時間、または現地時間から UTC) に応じて、時間管理関数に適用します。

これは少し複雑に聞こえるかもしれませんが、ヘルパー関数を作成した後、この機能をサイトに統合するには、 (時間変換が必要なページの) Page_Load で1 回の呼び出しを行い、送信時に時間変換ルーチンを使用するだけで済みました。ブラウザとの間で時間値を取得します。使用方法の例を次に示します。

using My.Utilities.Web;
...

// Derive the form class from BaseForm instead of Page.
public class WebForm1: BaseForm
{
...
private void Page_Load(object sender, System.EventArgs e)
{
  // If we only want to load the page to generate the time
  // zone offset cookie, we do not need to do anything else.
  if (InitializeLocalTime())
    return;

  // Assume that txtStartDate is a TextBox control.
  if (!IsPostback)
  {
     // To display a date-time value, convert it from GMT (UTC)
     // to local time.
     DateTime startDate = GetStartDateFromDB(...);
     txtStartDate.Text  = FormatLocalDate(startDate);
     ...
  }
  else
  {
     // To save a date-time value, convert it from local
     // time to GMT (UTC).
     DateTime tempDate  = DateTime.Parse(txtStartDate.Text);
     DateTime startDate = ConvertLocalTimeToUtc(tempDate);
     SaveStartDateInDB(startDate, ...);
     ...
  }
}
...
}

詳細が必要な場合は、そろそろ時間です: ASP.NET アプリケーションでの時間のローカライズの記事をご覧ください (申し訳ありませんが、asp.netPRO は有料購読者のみへのアクセスを制限しているため、発行元のサイトに記事への直接リンクはありません。 ; ただし、PDF コピーへのリンクがあります)。記事のサンプルを投稿できればいいのですが、著作権を侵害したくありません。ただし、必要なすべての機能とドキュメントを含むヘルパー ライブラリを構築するプロジェクトを次に示します(不要なものは無視してください)。

更新: この記事は、新しい発行元によるサンプル プロジェクトと共にオンラインで投稿されました

于 2009-05-07T07:54:40.513 に答える
3

これまでのすべての回答の問題は、Prashant が達成しようとしていることを考慮していないことです。夏時間変更の前日にシステムのユーザーが +12 のオフセットを持っていて、翌日のリマインダーを設定した場合、リマインダーがトリガーされるはずのときのオフセットは +13 になります。

そのため、現在起こっていることに対してのみ現在のオフセットを使用できます。サーバー側(おそらく表示のみに使用されるものを除く)は常にUTCで保存する必要があることに、他のすべての人に同意します。

于 2009-05-12T02:26:06.953 に答える
2

フレームワーク 2.0 以降を使用している場合は、DateTime の代わりにDateTimeOffset構造を使用して確認することをお勧めします。

DateTimeOffset は、UTC 時間に対する特定の時点を表すため、この場合は扱いやすいはずです。

于 2009-05-07T06:36:53.087 に答える
1

2 つのステップがあります。

  • Javascript を使用して、クライアント側で異なるタイムゾーンを検出します。

    var dt = new Date();
    var diffInMinutes = -dt.getTimezoneOffset();
    
  • 次に、サーバー側で、上記の検出されたタイムゾーン オフセットに基づいてサーバー時間をクライアント時間に変換する C# コード:

------------------------;

string queryStr = Request.QueryString["diffInMinutes"];
int diffInMinutes = 0;
if (Int32.TryParse(queryStr, out diffInMinutes))
{
    clientTime = serverTime.ToUniversalTime().AddMinutes(diffInMinutes);
}
于 2015-04-14T14:00:10.433 に答える
0

基本的に、ユーザーが入力した現地時間にオフセット (時間 + 分) を追加するだけです。オフセットを追加すると、基本的に UTC (基本的には GMT) タイムゾーンの DateTime が得られます。

アプリケーション ロジックがオフセットを処理する必要がないように、通常はすべての時間を UTC に標準化するのが最も簡単です。

このページにはいくつかの良い例があります: http://msdn.microsoft.com/en-us/library/bb546099.aspx

于 2009-05-07T05:25:50.543 に答える
0

問題は、UTC からのオフセットが 1 年のさまざまな時期に異なることです。各タイム ゾーンには独自のルールがあります。(これは、会議室のスケジューリング アプリを開発するときに苦労して学びました。)

ここに組み込みのサポートがあるようです: http://msdn.microsoft.com/en-us/library/system.timezoneinfo.converttime.aspx

自分で試したことはありませんが、夏時間を考慮して正しい変換を約束しているようです。

そうでない場合は、私が使用した (高価な) 商用ツールを次に示します: http://www.worldtimeserver.com/time_zone_guide/

于 2009-05-12T05:16:18.080 に答える