を私は特にインクルードの一部をオフセットしますが、タイムゾーンで混乱していると信じています。
MongoDbは常にUTC時刻で日付を保存します。
MongoDBの日付時刻を見ると、あなたのローカルタイムゾーンからのオフセットを常に考慮する必要があります。
あなたは常にローカルタイムゾーンで日付を送信します。 Mongo C#ドライバは、持続する前にローカルからUTCに時間を変更します。例えば
あなたがあるUTCからのオフセット何かISODate("2017-04-05T20:21:23.234Z")
すなわちローカルタイムが表示されますDB内のドキュメントを見たとき、私はCreatedOn = 2017-04-05 15:21:23.234
(ローカルタイムゾーン(アメリカ/シカゴ))が、 で文書を保存します-5時間。
[BsonDateTimeOptions(Kind = DateTimeKind.Local)]
は、BSONをPOCOに戻すときにUTCから現地時間に変換するようにドライバに指示します。
ここで動作を説明するテストケースです。
コード:
class Program
{
static void Main(string[] args)
{
var mongo = new MongoClient("mongodb://localhost:27017/test");
var db = mongo.GetDatabase("test");
db.DropCollection("students");
db.CreateCollection("students");
var collection = db.GetCollection<Student>("students");
var today = DateTime.Now; //2017-04-05 15:21:23.234
var yesterday = today.AddDays(-1);//2017-04-04 15:21:23.234
// Create 2 documents (yesterday & today)
collection.InsertMany(new[]
{
new Student{Description = "today", CreatedOn = today},
new Student{Description = "yesterday", CreatedOn = yesterday},
}
);
var filterBuilder1 = Builders<Student>.Filter;
var filter1 = filterBuilder1.Eq(x => x.CreatedOn, today);
List<Student> searchResult1 = collection.Find(filter1).ToList();
Console.Write(searchResult1.Count == 1);
var filterBuilder2 = Builders<Student>.Filter;
var filter2 = filterBuilder2.Eq(x => x.CreatedOn, yesterday);
List<Student> searchResult2 = collection.Find(filter2).ToList();
Console.Write(searchResult2.Count == 1);
}
}
public class Student
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
[BsonDateTimeOptions(Kind = DateTimeKind.Local)]
public DateTime CreatedOn { get; set; }
public string Description { get; set; }
}
コレクション:(モンゴシェルを通して見た)
{
"_id" : ObjectId("58e559c76d3a9d2cb0449d84"),
"CreatedOn" : ISODate("2017-04-04T20:21:23.234Z"),
"Description" : "yesterday"
}
{
"_id" : ObjectId("58e559c76d3a9d2cb0449d85"),
"CreatedOn" : ISODate("2017-04-05T20:21:23.234Z"),
"Description" : "today"
}
更新:
"CreatedOn": ISODate("2017-03-31T20:27:12.914+05:00")
あなたの比較が働いていない理由は
var start = new DateTime(2017, 03, 31);
var end = new DateTime(2017, 03, 31);
これはISODate("2017-03-31T00:00:00.000+05:00")
よりISODate("2017-03-31T00:00:00.000+05:00")
より$gte
と$lte
などとしてサーバーに送信取得し、それが上記のエントリを見つけるdoesntのです。
today
日付を照会する正しい方法は
var start = new DateTime(2017, 03, 31);
var end = new DateTime(2017, 04, 01);
ことと
var filter = filterBuilder.Gte(x => x.CreatedOn, start) &
filterBuilder.Lt(x => x.CreatedOn, end);
にあなたのフィルタを更新しますだから今、あなたの範囲のクエリがISODate("2017-04-01T00:00:00.000+05:00")
よりISODate("2017-03-31T00:00:00.000+05:00")
より$gte
と$lt
としてサーバーに送信されますあなたは今日のすべての試合を見つけることができるはずです。
アップデート2
変更00:00:00に時間部分を設定した日時を格納するためのデータベースを。これによりdbからの方程式の時間部分が削除され、古い範囲のクエリはすべての場合にうまく機能します。
は、あなたの保存方法は、あなたが戻って古いフィルタ定義に行くことができます
を使用するように変更します
。
var start = new DateTime(2017, 03, 31);
var end = new DateTime(2017, 03, 31);
ような何かと
var filter = filterBuilder.Gte(x => x.CreatedOn, start) &
filterBuilder.Lte(x => x.CreatedOn, end);
にあなたのフィルタを更新だから今、あなたの範囲のクエリがISODate("2017-03-31T00:00:00.000+05:00")
よりISODate("2017-03-31T00:00:00.000+05:00")
より$gte
と$lte
としてサーバーに送信され、あなたはすべてを見つけることができるはずです今日は一致します。
更新3 - 日付のみの比較BsonDocument
を使用しています。
ここでの考え方は、サーバーのUTC日付へ+5:00
をあるタイムゾーンのオフセットを追加し、同じフォーマットで入力された文字列の日付の比較が続く$dateToSting
演算子を使用して文字列yyyy-MM-dd
形式に計算された日時を変換することです。
これはあなたのタイムゾーンでは機能しますが、はDSTのタイムゾーンを監視するには機能しません。
モンゴバージョン3.4
あなたは比較の後、最終的な応答からCreatedOnDate
を削除するには、既存のすべてのプロパティと最後$project
を維持しながら、新しいフィールドを追加しCreatedOnDate
$addFields
のステージを使用することができます。
シェル問合せ:
{
"$addFields": {
"CreatedOnDate": {
"$dateToString": {
"format": "%Y-%m-%d",
"date": {
"$add": ["$CreatedOn", 18000000]
}
}
}
}
}, {
"$match": {
"CreatedOnDate": {
"$gte": "2017-03-31",
"$lte": "2017-03-31"
}
}
}, {
"$project": {
"CreatedOnDate": 0
}
}
C#コード:同上
var start = new DateTime(2017, 03, 31);
var end = new DateTime(2017, 03, 31);
var addFields = BsonDocument.Parse("{$addFields: { CreatedOnDate: { $dateToString: { format: '%Y-%m-%d', date: {$add: ['$CreatedOn', 18000000] }} }} }");
var match = new BsonDocument("CreatedOnDate", new BsonDocument("$gte", start.ToString("yyyy-MM-dd")).Add("$lte", end.ToString("yyyy-MM-dd")));
var project = new BsonDocument
{
{ "CreatedOnDate", 0 }
};
var pipeline = collection.Aggregate().AppendStage<BsonDocument>(addFields)
.Match(match)
.Project(project);
var list = pipeline.ToList();
List<Student> searchResult = list.Select(doc => BsonSerializer.Deserialize<Student>(doc)).ToList();
モンゴバージョン= 3.2
が、このパイプラインが$project
を使用していますので、あなたはすべて追加する必要がありますあなたが最終的な応答で保持したいフィールド。
シェル問合せ:
{
"$project": {
"CreatedOn": 1,
"Description": 1,
"CreatedOnDate": {
"$dateToString": {
"format": "%Y-%m-%d",
"date": {
"$add": ["$CreatedOn", 18000000]
}
}
}
}
}, {
"$match": {
"CreatedOnDate": {
"$gte": "2017-03-31",
"$lte": "2017-03-31"
}
}
}, {
"$project": {
"CreatedOn": 1,
"Description": 1
}
}
C#コード:
var start = new DateTime(2017, 03, 31);
var end = new DateTime(2017, 03, 31);
var project1 = new BsonDocument
{
{ "CreatedOn", 1 },
{ "Description", 1 },
{ "CreatedOnDate", new BsonDocument("$dateToString", new BsonDocument("format", "%Y-%m-%d")
.Add("date", new BsonDocument("$add", new BsonArray(new object[] { "$CreatedOn", 5 * 60 * 60 * 1000 }))))
}
};
var match = new BsonDocument("CreatedOnDate", new BsonDocument("$gte", start.ToString("yyyy-MM-dd")).Add("$lte", end.ToString("yyyy-MM-dd")));
var project2 = new BsonDocument
{
{ "CreatedOn", 1 },
{ "Description", 1 }
};
var pipeline = collection.Aggregate()
.Project(project1)
.Match(match)
.Project(project2);
var list = pipeline.ToList();
List<Student> searchResult = list.Select(doc => BsonSerializer.Deserialize<Student>(doc)).ToList();
更新4 - 昼光の削減と連動日のみの比較。
モンゴバージョン= 3.6
すべてのアカウントに日光省変化の世話をする必要がありますタイムゾーンの代わりに、固定オフセットがかかります$dateToString
を期待して同じままです。
シェルアップデート:
{
"$addFields": {
"CreatedOnDate": {
"$dateToString": {
"format": "%Y-%m-%d",
"date": "$CreatedOn",
"timezone": "America/New_York"
}
}
}
}
C#のアップデート:
var addFields = BsonDocument.Parse("{$addFields: { CreatedOnDate: { $dateToString: { format: '%Y-%m-%d', date: "$CreatedOn", "timezone": "America/New_York"} }} }");
はあなたが返すように現在の日のためのクエリを期待しているあなたのコレクションからのサンプル文書を追加することはできますか? – Veeram
私はDateTime.Nowをデータベースに保存しています。私の編集した質問を参照してください。 –
今日の例のThanls @Veeram私はAddDaysメソッドを使うことができますが、他の方法については、何らかの汎用ソリューションが必要です。 –