Skip to content
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

DateTime.Parse does not handle string that conform to RFC 3339 #1485

Open
CoryCharlton opened this issue May 15, 2024 · 2 comments
Open

DateTime.Parse does not handle string that conform to RFC 3339 #1485

CoryCharlton opened this issue May 15, 2024 · 2 comments

Comments

@CoryCharlton
Copy link
Member

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.

@nfbot nfbot changed the title DateTime.Parse does not handle string that conform to RFC 3339. DateTime.Parse does not handle string that conform to RFC 3339 May 15, 2024
@networkfusion
Copy link
Member

networkfusion commented May 16, 2024

My common workaround is .ToString("o")

e.g. you can use Debug.WriteLine($"as ISO date: {DateTime.FromUnixTimeSeconds(shadow.timestamp).ToString("o")}");

@CoryCharlton
Copy link
Member Author

My common workaround is .ToString("o")

e.g. you can use Debug.WriteLine($"as ISO date: {DateTime.FromUnixTimeSeconds(shadow.timestamp).ToString("o")}");

My issue is that the strings I need to parse are coming from an API I don't have control over.

My current workaround is some IndexOf/Substring hacking to find the fractional seconds part and pad/trim it to 7 digits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants