-
Notifications
You must be signed in to change notification settings - Fork 1.3k
CSHARP-3268: Investigate Military Time Failures #1687
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
src/MongoDB.Bson/IO/JsonReader.cs
Outdated
@@ -1373,7 +1373,7 @@ private DateTime ParseJavaScriptDateTimeString(string dateTimeString) | |||
{ | |||
// if DateTime.TryParse succeeds we're done, otherwise assume it's an RFC 822 formatted DateTime string | |||
DateTime dateTime; | |||
if (DateTime.TryParse(dateTimeString, out dateTime)) | |||
if (!dateTimeString.EndsWith("A") && DateTime.TryParse(dateTimeString, out dateTime)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason DateTime.TryParse
returns true
for time zone A
but who knows what it thinks the A
means.
If the string ends in A
then we should use our own parsing method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any chance there might be a collision with some other format ending with "A"?
Also there is not handling for "Z", is it a known abbreviation for UTC?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the existing test data nothing else ends with "A". But you are right, there might be a timezone abbreviation we don't know about that ends in A.
We could use a regular expression:
if (!Regex.Matches(dateString, "[0-9 ]A$") && ...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a test case for Z
. I think it is a standard abbreviation for UTC and is handled by DateTime.TryParse
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, just wanted to confirm that Z is for UTC.
Looking at .net code, seems that A is related to Era (AD is also valid).
What worries me is that "Mon, 10 Oct 2011 11:22:33 A" is parsed to a certain value in .NET, and we'll be overriding that. If going with this change we need to convince ourselves that this is the right thing to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also how will this "Mon, 10 Oct 2011 11:22:33 AD" get parsed?
case "W": offset = TimeSpan.FromHours(10); break; | ||
case "X": offset = TimeSpan.FromHours(11); break; | ||
case "Y": offset = TimeSpan.FromHours(12); break; | ||
case "A": offset = TimeSpan.FromHours(1); break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sign of all the offsets for A
to Y
was backwards.
|
||
private Test[] _tests = new Test[] | ||
{ | ||
public static object[][] TestParseDatesData => [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Convert to supply data to a Theory
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, just a question about "A" and "Z" abbreviations.
src/MongoDB.Bson/IO/JsonReader.cs
Outdated
@@ -1373,7 +1373,7 @@ private DateTime ParseJavaScriptDateTimeString(string dateTimeString) | |||
{ | |||
// if DateTime.TryParse succeeds we're done, otherwise assume it's an RFC 822 formatted DateTime string | |||
DateTime dateTime; | |||
if (DateTime.TryParse(dateTimeString, out dateTime)) | |||
if (!dateTimeString.EndsWith("A") && DateTime.TryParse(dateTimeString, out dateTime)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any chance there might be a collision with some other format ending with "A"?
Also there is not handling for "Z", is it a known abbreviation for UTC?
src/MongoDB.Bson/IO/JsonReader.cs
Outdated
@@ -1373,7 +1373,7 @@ private DateTime ParseJavaScriptDateTimeString(string dateTimeString) | |||
{ | |||
// if DateTime.TryParse succeeds we're done, otherwise assume it's an RFC 822 formatted DateTime string | |||
DateTime dateTime; | |||
if (DateTime.TryParse(dateTimeString, out dateTime)) | |||
if (!dateTimeString.EndsWith("A") && DateTime.TryParse(dateTimeString, out dateTime)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the existing test data nothing else ends with "A". But you are right, there might be a timezone abbreviation we don't know about that ends in A.
We could use a regular expression:
if (!Regex.Matches(dateString, "[0-9 ]A$") && ...)
src/MongoDB.Bson/IO/JsonReader.cs
Outdated
@@ -1373,7 +1373,7 @@ private DateTime ParseJavaScriptDateTimeString(string dateTimeString) | |||
{ | |||
// if DateTime.TryParse succeeds we're done, otherwise assume it's an RFC 822 formatted DateTime string | |||
DateTime dateTime; | |||
if (DateTime.TryParse(dateTimeString, out dateTime)) | |||
if (!dateTimeString.EndsWith("A") && DateTime.TryParse(dateTimeString, out dateTime)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a test case for Z
. I think it is a standard abbreviation for UTC and is handled by DateTime.TryParse
.
case "V": offset = TimeSpan.FromHours(-9); break; | ||
case "W": offset = TimeSpan.FromHours(-10); break; | ||
case "X": offset = TimeSpan.FromHours(-11); break; | ||
case "Y": offset = TimeSpan.FromHours(-12); break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean that we should add a case for "Z" here?
I don't see how we would ever reach here with a "Z" because DateTime.TryParse
would have already handled it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Follow up on A (and AD) "timezones".
src/MongoDB.Bson/IO/JsonReader.cs
Outdated
@@ -1373,7 +1373,7 @@ private DateTime ParseJavaScriptDateTimeString(string dateTimeString) | |||
{ | |||
// if DateTime.TryParse succeeds we're done, otherwise assume it's an RFC 822 formatted DateTime string | |||
DateTime dateTime; | |||
if (DateTime.TryParse(dateTimeString, out dateTime)) | |||
if (!dateTimeString.EndsWith("A") && DateTime.TryParse(dateTimeString, out dateTime)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also how will this "Mon, 10 Oct 2011 11:22:33 AD" get parsed?
…arse and use our own parsing.
if (DateTime.TryParse(dateTimeString, out dateTime)) | ||
|
||
// DateTime.Parse doesn't understand military time zones, so don't call it when a military time zone is present | ||
if (!Regex.IsMatch(dateTimeString, " [A-Y]$") && DateTime.TryParse(dateTimeString, out dateTime)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's my suggestion:
Either we support military time zones or we don't. And if we do support them, then we need to support ALL military time zones reliably.
Since DateTime.TryParse
does not understand military time zones, use a regex to detect the presence of a military time zone and do NOT call DateTime.TryParse
in that case. The reason to NOT call DateTime.TryParse
is that DateTime.TryParse
gets confused by SOME military time zones and interprets them as something else.
I'm not sure why we call DateTime.TryParse
at all here... since we have our own parsing for RFC 822 format date strings. I guess the idea here is to be "lenient" in what we accept, and that we will parse anything that DateTime.TryParse
understands and fall back to our own RFC 822 datetime parser for anything DateTime.TryParse
does not understand.
No description provided.