Skip to content

Commit c5b9fb9

Browse files
authored
Fix FbZonedDateTime invalid cast (#1194)
1 parent 795b51b commit c5b9fb9

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

src/FirebirdSql.Data.FirebirdClient.Tests/FbZonedDateTimeTypeTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ public void EqualityFalse(FbZonedDateTime expected, FbZonedDateTime actual)
4747
Assert.AreNotEqual(expected, actual);
4848
}
4949

50+
[Test]
51+
public void ConvertToDateTimeShouldNotThrow()
52+
{
53+
var fbZonedDateTime = new FbZonedDateTime(new DateTime(2020, 12, 4, 10, 38, 0, DateTimeKind.Utc), "UTC");
54+
55+
Assert.DoesNotThrow(() => Convert.ChangeType(fbZonedDateTime, typeof(DateTime)));
56+
}
57+
5058
public void DateTimeShouldBeUtc()
5159
{
5260
Assert.Throws<ArgumentException>(() =>

src/FirebirdSql.Data.FirebirdClient/Types/FbZonedDateTime.cs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
namespace FirebirdSql.Data.Types;
2222

2323
[StructLayout(LayoutKind.Auto)]
24-
public readonly struct FbZonedDateTime : IEquatable<FbZonedDateTime>
24+
public readonly struct FbZonedDateTime : IEquatable<FbZonedDateTime>, IConvertible
2525
{
2626
public DateTime DateTime { get; }
2727
public string TimeZone { get; }
@@ -72,8 +72,43 @@ public override int GetHashCode()
7272
}
7373
}
7474

75-
public bool Equals(FbZonedDateTime other) => DateTime.Equals(other.DateTime) && TimeZone.Equals(other.TimeZone, StringComparison.OrdinalIgnoreCase);
76-
75+
public bool Equals(FbZonedDateTime other) => DateTime.Equals(other.DateTime) && TimeZone.Equals(other.TimeZone, StringComparison.OrdinalIgnoreCase);
76+
77+
TypeCode IConvertible.GetTypeCode() => TypeCode.Object;
78+
79+
DateTime IConvertible.ToDateTime(IFormatProvider provider) => DateTime;
80+
81+
string IConvertible.ToString(IFormatProvider provider) => ToString();
82+
83+
object IConvertible.ToType(Type conversionType, IFormatProvider provider)
84+
=> ReferenceEquals(conversionType, typeof(FbZonedDateTime)) ? this : throw new InvalidCastException(conversionType?.FullName);
85+
86+
bool IConvertible.ToBoolean(IFormatProvider provider) => throw new InvalidCastException(nameof(Boolean));
87+
88+
byte IConvertible.ToByte(IFormatProvider provider) => throw new InvalidCastException(nameof(Byte));
89+
90+
char IConvertible.ToChar(IFormatProvider provider) => throw new InvalidCastException(nameof(Char));
91+
92+
decimal IConvertible.ToDecimal(IFormatProvider provider) => throw new InvalidCastException(nameof(Decimal));
93+
94+
double IConvertible.ToDouble(IFormatProvider provider) => throw new InvalidCastException(nameof(Double));
95+
96+
short IConvertible.ToInt16(IFormatProvider provider) => throw new InvalidCastException(nameof(Int16));
97+
98+
int IConvertible.ToInt32(IFormatProvider provider) => throw new InvalidCastException(nameof(Int32));
99+
100+
long IConvertible.ToInt64(IFormatProvider provider) => throw new InvalidCastException(nameof(Int64));
101+
102+
sbyte IConvertible.ToSByte(IFormatProvider provider) => throw new InvalidCastException(nameof(SByte));
103+
104+
float IConvertible.ToSingle(IFormatProvider provider) => throw new InvalidCastException(nameof(Single));
105+
106+
ushort IConvertible.ToUInt16(IFormatProvider provider) => throw new InvalidCastException(nameof(UInt16));
107+
108+
uint IConvertible.ToUInt32(IFormatProvider provider) => throw new InvalidCastException(nameof(UInt32));
109+
110+
ulong IConvertible.ToUInt64(IFormatProvider provider) => throw new InvalidCastException(nameof(UInt64));
111+
77112
public static bool operator ==(FbZonedDateTime lhs, FbZonedDateTime rhs) => lhs.Equals(rhs);
78113

79114
public static bool operator !=(FbZonedDateTime lhs, FbZonedDateTime rhs) => lhs.Equals(rhs);

0 commit comments

Comments
 (0)