From ccdba6ba8d11b33ebe8fecdb8be5ed4f2ada427d Mon Sep 17 00:00:00 2001 From: Grant Birchmeier Date: Thu, 16 Apr 2026 13:43:24 -0500 Subject: [PATCH] deprecate DateTimeConverter.ParseToTimeOnly #1014 --- QuickFIXn/DataDictionary/DataDictionary.cs | 2 +- QuickFIXn/Fields/Converters/DateTimeConverter.cs | 11 +++++++---- QuickFIXn/Message/FieldMap.cs | 4 +++- RELEASE_NOTES.md | 1 + UnitTests/Fields/Converters/DateTimeConverterTests.cs | 10 +++++----- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/QuickFIXn/DataDictionary/DataDictionary.cs b/QuickFIXn/DataDictionary/DataDictionary.cs index 8361ba85e..e420f9db5 100644 --- a/QuickFIXn/DataDictionary/DataDictionary.cs +++ b/QuickFIXn/DataDictionary/DataDictionary.cs @@ -305,7 +305,7 @@ public void CheckValidFormat(IField field) else if (type == typeof(DateOnlyField)) Fields.Converters.DateTimeConverter.ParseToDateOnly(field.ToString()); else if (type == typeof(TimeOnlyField)) - Fields.Converters.DateTimeConverter.ParseToTimeOnly(field.ToString()); + Fields.Converters.DateTimeConverter.InternalParseToTimeOnly(field.ToString()); } catch (FieldConvertError e) { diff --git a/QuickFIXn/Fields/Converters/DateTimeConverter.cs b/QuickFIXn/Fields/Converters/DateTimeConverter.cs index ecffb0dc7..11b431a0b 100644 --- a/QuickFIXn/Fields/Converters/DateTimeConverter.cs +++ b/QuickFIXn/Fields/Converters/DateTimeConverter.cs @@ -245,9 +245,10 @@ public static TimeOnly ParseToTimeOnly(ReadOnlySpan str, out TimeSpan? off return time; } - + /// - /// Converts the specified string to a . + /// Converts the specified string to a WHERE ONLY THE TIME PARTS ARE MEANINGFUL. + /// (The date parts of the return value will always be set to 1980-01-01, DateTime.Kind==Unspecified.) /// The string must be in the format "HH:mm:ss" optionally followed by fractional seconds /// and then optionally followed by UTC offset information. /// @@ -268,8 +269,7 @@ public static TimeOnly ParseToTimeOnly(ReadOnlySpan str, out TimeSpan? off /// Consider calling the latter for flexibility. /// /// The conversion cannot be performed successfully. - public static DateTime ParseToTimeOnly(string str) => new DateOnly(1980, 1, 1).ToDateTime(ParseToTimeOnly(str, out _)); - // (^^Yes, it intentionally does return a DateTime. For now.) + internal static DateTime InternalParseToTimeOnly(string str) => new DateOnly(1980, 1, 1).ToDateTime(ParseToTimeOnly(str, out _)); /// /// For the given , read consecutive ASCII digits @@ -621,4 +621,7 @@ public static string ConvertTimeOnly(DateTime dt, bool includeMilliseconds = tru ? ToFIXTimeOnly(dt, TimeStampPrecision.Millisecond) : ToFIXTimeOnly(dt, TimeStampPrecision.Second); } + + [Obsolete("Don't use this function, it probably doesn't do what you think it does. Will be removed in v1.16.")] + public static DateTime ParseToTimeOnly(string str) => InternalParseToTimeOnly(str); } diff --git a/QuickFIXn/Message/FieldMap.cs b/QuickFIXn/Message/FieldMap.cs index f7027e728..9b11e1a04 100644 --- a/QuickFIXn/Message/FieldMap.cs +++ b/QuickFIXn/Message/FieldMap.cs @@ -385,6 +385,8 @@ public DateTime GetDateOnly(int tag) /// /// Gets the TimeOnly value of a field + /// as a DateTime WHERE ONLY THE TIME PARTS ARE MEANINGFUL. + /// (The date parts of the return value will always be set to 1980-01-01, DateTime.Kind==Unspecified.) /// /// the FIX tag /// the DateTime value @@ -397,7 +399,7 @@ public DateTime GetTimeOnly(int tag) if (fld is FieldBase dateTimeField) return new DateTime(1980, 01, 01).Add(dateTimeField.Value.TimeOfDay); - return DateTimeConverter.ParseToTimeOnly(fld.ToString()); + return DateTimeConverter.InternalParseToTimeOnly(fld.ToString()); } /// diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 2d8c93a07..f0fb39712 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -37,6 +37,7 @@ What's New * #562 - deprecate Message.IsHeaderField without transport DD param (gbirchmeier) * #949 - new settings RedactFieldsInLogs & RedactionLogText (gbirchmeier) * #983 - new MessageFactoryNotFound exception provides better feedback (gbirchmeier) +* #1014 - deprecate DateTimeConverter.ParseToTimeOnly (gbirchmeier) ### v1.14.0 diff --git a/UnitTests/Fields/Converters/DateTimeConverterTests.cs b/UnitTests/Fields/Converters/DateTimeConverterTests.cs index 7ebcdcfce..240fa91db 100644 --- a/UnitTests/Fields/Converters/DateTimeConverterTests.cs +++ b/UnitTests/Fields/Converters/DateTimeConverterTests.cs @@ -103,17 +103,17 @@ public void ParseToTimeOnlyTest_ReturnsDateTime() { var targetTicks = new DateTime(1980, 1, 1, 4, 22, 1, 0, DateTimeKind.Utc).Ticks; Assert.That(targetTicks, Is.EqualTo(624511453210000000)); // for human reader reference - DateTime rv = DateTimeConverter.ParseToTimeOnly("04:22:01"); + DateTime rv = DateTimeConverter.InternalParseToTimeOnly("04:22:01"); Assert.That(rv.Ticks, Is.EqualTo(targetTicks)); - Assert.That(DateTimeConverter.ParseToTimeOnly("04:22:01.123").Ticks, Is.EqualTo(targetTicks + 1230000)); - Assert.That(DateTimeConverter.ParseToTimeOnly("04:22:01.123456").Ticks, Is.EqualTo(targetTicks + 1234560)); + Assert.That(DateTimeConverter.InternalParseToTimeOnly("04:22:01.123").Ticks, Is.EqualTo(targetTicks + 1230000)); + Assert.That(DateTimeConverter.InternalParseToTimeOnly("04:22:01.123456").Ticks, Is.EqualTo(targetTicks + 1234560)); } [Test] public void ParseToTimeOnlyTest_Exceptions() { - Assert.Throws(typeof(FieldConvertError), delegate { DateTimeConverter.ParseToTimeOnly(""); }); - Assert.Throws(typeof(FieldConvertError), delegate { DateTimeConverter.ParseToTimeOnly("20021201-11:03:00"); }); + Assert.Throws(typeof(FieldConvertError), delegate { DateTimeConverter.InternalParseToTimeOnly(""); }); + Assert.Throws(typeof(FieldConvertError), delegate { DateTimeConverter.InternalParseToTimeOnly("20021201-11:03:00"); }); } [Test]