-
-
Notifications
You must be signed in to change notification settings - Fork 12
Description
I received the following error while trying to parse through a L5x that included a Flex 5000 Adapter:
Unhandled exception. System.FormatException: String '1970-01-01-00:17:25.505782920Z' was not recognized as a valid DateTime.
at System.DateTime.ParseExact(String s, String format, IFormatProvider provider)
at L5Sharp.Core.Radix.DateTimeNsRadix.ParseValue(String input)
at L5Sharp.Core.LINT.Parse(String value)
at L5Sharp.Core.AtomicData.Parse(String name, String value)
at L5Sharp.Core.LogixSerializer.DeserializeAtomic(XElement element)
at L5Sharp.Core.LogixSerializer.Deserialize(XElement element)
at L5Sharp.Core.LogixSerializer.Deserialize[TElement](XElement element)
at L5Sharp.Core.Member.GetData()
at L5Sharp.Core.Member.get_Value()
at L5Sharp.Core.Tag.get_Value()
at L5Sharp.Core.Tag.Members()
at L5Sharp.Core.Tag.Members()
at L5Sharp.Core.Tag.TagNames()
The Specific line of the L5X that was getting stuck was under the Flex 5000 module at :
<DataValueMember Name="LocalClockOffsetTimestamp" DataType="LINT" Radix="Date/Time (ns)" Value="LDT#1970-01-01-00:17:25.505_782_920Z" />
I tracked it down to the DateTimeNsRadix Class, specifically to the format being specified in the DateExact Parse currently at line 717 of: src\L5Sharp.Core\Enums\Radix.cs
var time = System.DateTime.ParseExact(value, "yyyy-MM-dd-HH:mm:ss.fffffff00(UTCzzz)",
I believe this is an invalid parse format and more specifically System.DateTime can only go to 7 digits of precision instead of 9.
I also dont believe (UTCzzz) is needed either and that the "Z" suffix needs to be dealt with also (the same as is done in the DateTimeRadix class. )
I propose the following fix:
public override AtomicData ParseValue(string input)
{
ValidateFormat(input);
var value = input.Replace(Specifier, string.Empty)
.Replace(Separator, string.Empty)
.Replace(Suffix, string.Empty);
value = Regex.Replace(value, @"\.(\d{7})\d{2}", @".$1");
var time = System.DateTime.ParseExact(value, "yyyy-MM-dd-HH:mm:ss.fffffff",
CultureInfo.InvariantCulture).ToUniversalTime();
var timestamp = (time.Ticks - UnixEpoch.Ticks) * 100;
return new LINT(timestamp);
You'll also need to add the following to the to the DateTimeNsRadix Class :
private const string Suffix = "Z";
A few resons I post it as an issue instead of a Pull Request:
-
The solution I proposed will lose 2 digits of precision. For my purposes this is acceptable, but will need a more complete solution if you wish to keep the 9 digits of precision. This is the main discussion point.
-
I wasnt sure how you'd like to rev this. I'd propose 5.3.1.
-
I believe with the above fix, this issue can be closed and it should also resolve any issues that were described in Issue [Bug] Missing support to DT/LDT Atomic type #33 as I believe the DT/LDT types have been incorporated since that issue was opened.
Thank you for the consideration and for such a great project!