`DateTime.Parse` does not handle string that conform to RFC 3339
#1,485 opened on May 15, 2024
Repository metrics
- Stars
- (936 stars)
- PR merge metrics
- (PR metrics pending)
Description
Library/API/IoT binding
nanoFramework.CoreLibrary
Visual Studio version
No response
.NET nanoFramework extension version
No response
Target name(s)
No response
Firmware version
No response
Device capabilities
No response
Description
RFC 3339 does not specify the number of digits for the fractional second portion but a common practice is to use three digits so the fractional second portion relates to whole milliseconds:
yyyy-MM-dd'T'HH:mm:ss.fffK (or yyyy-MM-dd'T'HH:mm:ss.fffZ in NF since 'K' isn't supported and all DateTime are assumed to be UTC)
Ex: 2024-05-15T04:20:05.069Z
Unfortunately the DateTime.Parse implementation in NF is currently only supporting the ISO 8601 "round trip time" format which requires that the fractional second portion contain 7 digits (yyyy-MM-ddTHH:mm:ss.fffffff) code.
This causes the example string above to parse with '0' milliseconds and '69' "extra" ticks. The issue is here because the code assumes the string represents a 7 digit number '0000069' when the correct 7 digit number is '0690000'
How to reproduce
See sample code below.
Expected behaviour
No response
Screenshots
No response
Sample project or code
var dateTime1 = new DateTime(2024, 5, 15, 4, 20, 5, 69);
var dateTimeString = dateTime1.ToString("yyyy-MM-dd'T'HH:mm:ss.fffZ");
var dateTime2 = DateTime.Parse("2024-05-15T04:20:05.069Z");
var dateTime3 = DateTime.Parse("2024-05-15T04:20:05.0690000Z");
Console.WriteLine($"dateTime1: {dateTime1.Ticks} - {dateTime1.Hour}:{dateTime1.Minute}:{dateTime1.Second}.{dateTime1.Millisecond}");
Console.WriteLine($"dateTime2: {dateTime2.Ticks} - {dateTime2.Hour}:{dateTime2.Minute}:{dateTime2.Second}.{dateTime2.Millisecond}");
Console.WriteLine($"dateTime3: {dateTime3.Ticks} - {dateTime3.Hour}:{dateTime3.Minute}:{dateTime3.Second}.{dateTime3.Millisecond}");
Console.WriteLine($"dateTimeString: {dateTimeString}");
Output:
dateTime1: 638513436050690000 - 4:20:5.69
dateTime2: 638513436050000069 - 4:20:5.0
dateTime3: 638513436050690000 - 4:20:5.69
dateTimeString: 2024-05-15T04:20:05.069Z
Aditional information
I looked at the code a bit and I don't have a good solution at the moment.