Skip to content

Commit 1eca0fa

Browse files
author
rstam
committed
CSHARP-963: Support $date with ISO8601 string in extended JSON.
1 parent 26eb05d commit 1eca0fa

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

MongoDB.Bson/IO/JsonReader.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -923,13 +923,30 @@ private BsonValue ParseDateTimeExtendedJson()
923923
{
924924
VerifyToken(":");
925925
var valueToken = PopToken();
926-
if (valueToken.Type != JsonTokenType.Int32 && valueToken.Type != JsonTokenType.Int64)
926+
927+
long millisecondsSinceEpoch;
928+
if (valueToken.Type == JsonTokenType.Int32 || valueToken.Type == JsonTokenType.Int64)
927929
{
928-
var message = string.Format("JSON reader expected an integer but found '{0}'.", valueToken.Lexeme);
930+
millisecondsSinceEpoch = valueToken.Int64Value;
931+
}
932+
else if (valueToken.Type == JsonTokenType.String)
933+
{
934+
DateTime dateTime;
935+
if (!DateTime.TryParse(valueToken.StringValue, out dateTime))
936+
{
937+
var message = string.Format("Invalid $date string: '{0}'.", valueToken.StringValue);
938+
throw new FileFormatException(message);
939+
}
940+
millisecondsSinceEpoch = BsonUtils.ToMillisecondsSinceEpoch(dateTime);
941+
}
942+
else
943+
{
944+
var message = string.Format("JSON reader expected an integer or an ISO 8601 string for $date but found a '{0}'.", valueToken.Lexeme);
929945
throw new FileFormatException(message);
930946
}
947+
931948
VerifyToken("}");
932-
return new BsonDateTime(valueToken.Int64Value);
949+
return new BsonDateTime(millisecondsSinceEpoch);
933950
}
934951

935952
private BsonValue ParseDateTimeConstructor(bool withNew)

MongoDB.BsonUnitTests/IO/JsonReaderTests.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,21 @@ public void TestDateTimeStrict()
223223
Assert.AreEqual(json, BsonSerializer.Deserialize<DateTime>(new StringReader(json)).ToJson(jsonSettings));
224224
}
225225

226+
[Test]
227+
public void TestDateTimeStrictIso8601()
228+
{
229+
var json = "{ \"$date\" : \"1970-01-01T00:00:00Z\" }";
230+
using (_bsonReader = BsonReader.Create(json))
231+
{
232+
Assert.AreEqual(BsonType.DateTime, _bsonReader.ReadBsonType());
233+
Assert.AreEqual(0, _bsonReader.ReadDateTime());
234+
Assert.AreEqual(BsonReaderState.Done, _bsonReader.State);
235+
}
236+
var expected = "{ \"$date\" : 0 }"; // it's still not ISO8601 on the way out
237+
var jsonSettings = new JsonWriterSettings { OutputMode = JsonOutputMode.Strict };
238+
Assert.AreEqual(expected, BsonSerializer.Deserialize<DateTime>(new StringReader(json)).ToJson(jsonSettings));
239+
}
240+
226241
[Test]
227242
public void TestDateTimeTengen()
228243
{

0 commit comments

Comments
 (0)