Skip to content

#LDT System.FormatException - Not recognized as a valid DateTime #63

@revta

Description

@revta

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:

  1. 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.

  2. I wasnt sure how you'd like to rev this. I'd propose 5.3.1.

  3. 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!

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions