diff --git a/Directory.Packages.props b/Directory.Packages.props
index cf90f96..41cd5cf 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -14,7 +14,7 @@
-
+
diff --git a/src/AltaSoft.DomainPrimitives/ToXmlStringExt.cs b/src/AltaSoft.DomainPrimitives/ToXmlStringExt.cs
index d3024cb..38236bd 100644
--- a/src/AltaSoft.DomainPrimitives/ToXmlStringExt.cs
+++ b/src/AltaSoft.DomainPrimitives/ToXmlStringExt.cs
@@ -31,12 +31,27 @@ public static class ToXmlStringExt
public static string ToXmlString(this DateOnly value) => value.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
///
- /// Converts a value to its XML string representation in the format "HH:mm:ss".
+ /// Converts a value to its XML string representation in the format "HH:mm:sszzz",
+ /// where the time zone offset reflects the current local offset from UTC.
///
/// The TimeOnly value to convert.
/// The XML string representation of the TimeOnly value.
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static string ToXmlString(this TimeOnly value) => value.ToString("HH:mm:ss", CultureInfo.InvariantCulture);
+ public static string ToXmlString(this TimeOnly value)
+ {
+ // We avoid constructing a local DateTime for an arbitrary date to prevent
+ // possible exceptions on DST transition days (invalid or ambiguous local times).
+ var timePart = value.ToString("HH:mm:ss", CultureInfo.InvariantCulture);
+
+ // Derive the current local offset from UTC in a DST-safe way using the current instant.
+ var offset = TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow);
+ var offsetSign = offset < TimeSpan.Zero ? "-" : "+";
+ var absoluteOffset = offset.Duration();
+ var offsetPart = absoluteOffset.ToString(@"hh\:mm", CultureInfo.InvariantCulture);
+
+ return $"{timePart}{offsetSign}{offsetPart}";
+ }
///
/// Converts a value to its XML string representation
diff --git a/tests/AltaSoft.DomainPrimitives.XmlDataTypes.Tests/ToXmlStringExtTests.cs b/tests/AltaSoft.DomainPrimitives.XmlDataTypes.Tests/ToXmlStringExtTests.cs
index eef5e8d..abe5315 100644
--- a/tests/AltaSoft.DomainPrimitives.XmlDataTypes.Tests/ToXmlStringExtTests.cs
+++ b/tests/AltaSoft.DomainPrimitives.XmlDataTypes.Tests/ToXmlStringExtTests.cs
@@ -24,7 +24,15 @@ public void TimeOnly_ToXmlString_ReturnsExpectedFormat()
{
var t = new TimeOnly(13, 45, 30);
var xml = t.ToXmlString();
- Assert.Equal("13:45:30", xml);
+
+ // Validate the overall shape: time followed by a timezone offset
+ Assert.Matches(@"^13:45:30[+-]\d{2}:\d{2}$", xml);
+
+ // Validate the offset suffix matches the actual current local offset
+ var offset = TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow);
+ var offsetSign = offset < TimeSpan.Zero ? "-" : "+";
+ var expectedOffsetSuffix = $"{offsetSign}{offset.Duration():hh\\:mm}";
+ Assert.EndsWith(expectedOffsetSuffix, xml);
}
[Fact]