2つのアプリケーションがあります。クライアントアプリとサーバーアプリ。
クライアントアプリは、リクエストの本文にが含まれているサーバーにHTTPリクエストを送信しますDateTime
。
私が受け取ったサーバーでDateTime
、それをに変換Ticks
してSQLiteデータベースに保存します。(なぜティックなのかについて議論することもできますが、それがこのアプリケーションのビルド方法です。)
ここまでは順調ですね。
少し後(数分)に、サーバーアプリケーションはデータベースに対してクエリを実行し、過去30分間のすべてのレコードをクエリしようとします。
コードでは、現在のDateTime
マイナス30分を取得するために次のようなことを行います。
DateTimeOffset.Now.AddMinutes(-30).Ticks;
何らかの理由で、この数は新しく作成されたレコードのタイムスタンプよりも大きくなります。
私はおそらく何かが足りないのですが、私はそれを見ていません...
これが私の問題を完全に模倣するコードです。(投稿の下部にある作業デモへのリンク)
public static void Main()
{
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Client app
////////////////////////////////////////////////////////////////////////////////////////////////////////////
var clientTimestamp = DateTimeOffset.Now.DateTime;
var jsonDateTime = clientTimestamp.ToString("yyyy-MM-ddThh:mm:ss.fffZ");
// Then, the client app sends data as JSON to the server app...
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Server app
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Mimick as if we received a json string with a DateTime in it. Parse that back to a real DateTime object.
// This is also the value that will be stored in the database
var serverDateTime = DateTime.Parse(jsonDateTime);
Console.WriteLine("Ticks serverDateTime: " + serverDateTime.Ticks.ToString());
// A minute or so later, a recurring job checks the database for newly added records in the range of: 30 minutes ago till now.
// Create a new DateTime Now minus 30 minutes... Both Ticks values below are greater than the jsonDateTime ticks?
// DateTimeOffset:
// This value is larger, even with the minus -10 minutes?
var nowDateTimeOffset = DateTimeOffset.Now.AddMinutes(-10).Ticks.ToString();
Console.WriteLine("Ticks nowDateTime -10 minutes: " + nowDateTimeOffset);
// DateTime
// This value is larger, even with the minus -10 minutes?
var nowDateTime = DateTimeOffset.Now.AddMinutes(-10).Ticks.ToString();
Console.WriteLine("Ticks nowDateTime -10 minutes: " + nowDateTime);
}
これがデモです:https://dotnetfiddle.net/58Un0p
この場合、問題はDateTimeの形式にあるようです。
"yyyy-MM-ddThh:mm:ss.fffZ" // lower hh
一方、次のようになります。
"yyyy-MM-ddTHH:mm:ss.fffZ" // upper HH
hh
24時間(HH
)形式ではなく12時間()形式を使用すると、50%の確率で12時間の差が生じます。
ハンスがコメントで述べているように、UTCを使用してDateTime値を比較していることを確認する必要があります。DateTime.Parse
デフォルトでは、DateTimeの種類はに設定されていますDateTimeKind.Local
。クライアントはUTCDateTimeを送信していますか?
クライアントのタイムスタンプを更新して、UTCDateTimeをToUniversalTime
次のように送信します。
var clientTimestamp = DateTimeOffset.Now.ToUniversalTime();
代わりにDateTime.Parse
考えるDateTime.ParseExact
とAdjustToUniversal
:
// convert the date to UTC before saving to database
var utcServerDate = DateTime.ParseExact(jsonDateTime, "yyyy-MM-ddTHH:mm:ss.fffZ",
CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
そして、DateTimeOffset.Now
値の使用を比較するときUtcTicks
:
var nowDateTimeOffset = DateTimeOffset.Now.AddMinutes(-30).UtcTicks;
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加