1

毎晩午前3時から午前5時の間に実行されるWindowsサービスがあります。ジョブが実行されると、次のようになります。

var endDate = DateTime.Today.ToUniversalTime(); // Set to midnight
var startDate = endDate.AddDays(-1);

夜間に実行されるクエリは、次のようになります(すべての日付は現在UTCとして保存されています):

SELECT * FROM Table WHERE CreatedAt BETWEEN startDate AND endDate

これは問題なく機能し、基本的にはジョブが実行される前日のすべてのデータを取得します。現在、ユーザーがボタンをクリックして夜間に処理されるデータ数を確認するUIパーツを開発しています。

私が遭遇している問題は、ユーザーが通常の営業時間中に仕事をしていて、そのボタンをクリックすると、カウントが1日ずれることです。カウントは、現地時間が午後8時EST(サーバーは東海岸にあります)以降の場合にのみ正しく表示されます。これは、UTC時間の午前0時以降になるためです。

私はこれを次のようなもので解決しようとしました:

var now = DateTime.Now;
var midnight = DateTime.Today.ToUniversalTime();

var endDate = (now.Day == midnight.Day) ? midnight.AddDays(1) : midnight;
var startDate = endDate.AddDays(-1);

ただし、これは1日の一部の時間帯にのみ機能するため、正しくありません。現地時間の深夜0時以降にボタンをクリックすると、再び1日オフになります。

この問題を解決するためにDateTimeオブジェクトを使用する賢い方法はありますか?

4

1 に答える 1

0

UIで現地時間をUTCに変換できます。または単にを使用しますDateTime.UtcNow。あなたがそれを呼び出すToUniversalTime場合にのみ機能するので注意する必要があります:DateTimeKind==DateTimeKind.Local

var localTimeUtc = TimeZoneInfo.ConvertTimeToUtc(
  DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local));

//or (much easier)
var localTimeUtc = DateTime.UtcNow;

その後:

var utcMidnight = localTimeUtc.Date;
var yesterdayUtcMidnight = midnight.AddDays(-1);

現在utcMidnightyesterdayUtcMidnightUTC時間で「昨日」のすべてをカバーします。

2つ目の注意点として、Windowsサービスは昨日のUTCまたは昨日のローカルからのデータを処理することを目的としていますか?データベース内の時刻がUTCの場合、サービスコードは機能するはずですが、現地時間(おそらくデフォルトではGetDate()?)として入力されている場合、処理用のコードは機能しません。

于 2012-04-23T22:15:45.813 に答える