diff --git a/src/FirebirdSql.Data.FirebirdClient.Tests/FbZonedTimeTypeTests.cs b/src/FirebirdSql.Data.FirebirdClient.Tests/FbZonedTimeTypeTests.cs index c0309b389..959c2a579 100644 --- a/src/FirebirdSql.Data.FirebirdClient.Tests/FbZonedTimeTypeTests.cs +++ b/src/FirebirdSql.Data.FirebirdClient.Tests/FbZonedTimeTypeTests.cs @@ -46,4 +46,12 @@ public void EqualityFalse(FbZonedTime expected, FbZonedTime actual) { Assert.AreNotEqual(expected, actual); } + + [Test] + public void ConvertToTimeSpanShouldNotThrow() + { + var fbZonedTime = new FbZonedTime(TimeSpan.FromMinutes(142), "UTC"); + + Assert.DoesNotThrow(() => Convert.ChangeType(fbZonedTime, typeof(TimeSpan))); + } } diff --git a/src/FirebirdSql.Data.FirebirdClient/Types/FbZonedTime.cs b/src/FirebirdSql.Data.FirebirdClient/Types/FbZonedTime.cs index 560038544..476368933 100644 --- a/src/FirebirdSql.Data.FirebirdClient/Types/FbZonedTime.cs +++ b/src/FirebirdSql.Data.FirebirdClient/Types/FbZonedTime.cs @@ -21,7 +21,7 @@ namespace FirebirdSql.Data.Types; [StructLayout(LayoutKind.Auto)] -public readonly struct FbZonedTime : IEquatable +public readonly struct FbZonedTime : IEquatable, IConvertible { public TimeSpan Time { get; } public string TimeZone { get; } @@ -70,8 +70,47 @@ public override int GetHashCode() } } - public bool Equals(FbZonedTime other) => Time.Equals(other.Time) && TimeZone.Equals(other.TimeZone, StringComparison.OrdinalIgnoreCase); - + public bool Equals(FbZonedTime other) => Time.Equals(other.Time) && TimeZone.Equals(other.TimeZone, StringComparison.OrdinalIgnoreCase); + + TypeCode IConvertible.GetTypeCode() => TypeCode.Object; + + string IConvertible.ToString(IFormatProvider provider) => ToString(); + + object IConvertible.ToType(Type conversionType, IFormatProvider provider) + => ReferenceEquals(conversionType, typeof(FbZonedTime)) + ? this + : ReferenceEquals(conversionType, typeof(TimeSpan)) + ? Time + : throw new InvalidCastException(conversionType?.FullName); + + bool IConvertible.ToBoolean(IFormatProvider provider) => throw new InvalidCastException(nameof(Boolean)); + + byte IConvertible.ToByte(IFormatProvider provider) => throw new InvalidCastException(nameof(Byte)); + + char IConvertible.ToChar(IFormatProvider provider) => throw new InvalidCastException(nameof(Char)); + + DateTime IConvertible.ToDateTime(IFormatProvider provider) => throw new InvalidCastException(nameof(DateTime)); + + decimal IConvertible.ToDecimal(IFormatProvider provider) => throw new InvalidCastException(nameof(Decimal)); + + double IConvertible.ToDouble(IFormatProvider provider) => throw new InvalidCastException(nameof(Double)); + + short IConvertible.ToInt16(IFormatProvider provider) => throw new InvalidCastException(nameof(Int16)); + + int IConvertible.ToInt32(IFormatProvider provider) => throw new InvalidCastException(nameof(Int32)); + + long IConvertible.ToInt64(IFormatProvider provider) => throw new InvalidCastException(nameof(Int64)); + + sbyte IConvertible.ToSByte(IFormatProvider provider) => throw new InvalidCastException(nameof(SByte)); + + float IConvertible.ToSingle(IFormatProvider provider) => throw new InvalidCastException(nameof(Single)); + + ushort IConvertible.ToUInt16(IFormatProvider provider) => throw new InvalidCastException(nameof(UInt16)); + + uint IConvertible.ToUInt32(IFormatProvider provider) => throw new InvalidCastException(nameof(UInt32)); + + ulong IConvertible.ToUInt64(IFormatProvider provider) => throw new InvalidCastException(nameof(UInt64)); + public static bool operator ==(FbZonedTime lhs, FbZonedTime rhs) => lhs.Equals(rhs); public static bool operator !=(FbZonedTime lhs, FbZonedTime rhs) => lhs.Equals(rhs);