diff --git a/src/MySqlConnector/MySql.Data.Types/MySqlDateTime.cs b/src/MySqlConnector/MySql.Data.Types/MySqlDateTime.cs index 5f9777227..c0eb3a80f 100644 --- a/src/MySqlConnector/MySql.Data.Types/MySqlDateTime.cs +++ b/src/MySqlConnector/MySql.Data.Types/MySqlDateTime.cs @@ -2,7 +2,7 @@ namespace MySql.Data.Types { - public struct MySqlDateTime : IComparable + public struct MySqlDateTime : IComparable, IConvertible { public MySqlDateTime(int year, int month, int day, int hour, int minute, int second, int microsecond) { @@ -86,5 +86,28 @@ public int Millisecond return 1; return Microsecond.CompareTo(other.Microsecond); } + + DateTime IConvertible.ToDateTime(IFormatProvider provider) => IsValidDateTime ? GetDateTime() : throw new InvalidCastException(); + string IConvertible.ToString(IFormatProvider provider) => IsValidDateTime ? GetDateTime().ToString(provider) : "0000-00-00"; + + object IConvertible.ToType(Type conversionType, IFormatProvider provider) => + conversionType == typeof(DateTime) ? (object) GetDateTime() : + conversionType == typeof(string) ? ((IConvertible) this).ToString(provider) : + throw new InvalidCastException(); + + TypeCode IConvertible.GetTypeCode() => TypeCode.Object; + bool IConvertible.ToBoolean(IFormatProvider provider) => throw new InvalidCastException(); + char IConvertible.ToChar(IFormatProvider provider) => throw new InvalidCastException(); + sbyte IConvertible.ToSByte(IFormatProvider provider) => throw new InvalidCastException(); + byte IConvertible.ToByte(IFormatProvider provider) => throw new InvalidCastException(); + short IConvertible.ToInt16(IFormatProvider provider) => throw new InvalidCastException(); + ushort IConvertible.ToUInt16(IFormatProvider provider) => throw new InvalidCastException(); + int IConvertible.ToInt32(IFormatProvider provider) => throw new InvalidCastException(); + uint IConvertible.ToUInt32(IFormatProvider provider) => throw new InvalidCastException(); + long IConvertible.ToInt64(IFormatProvider provider) => throw new InvalidCastException(); + ulong IConvertible.ToUInt64(IFormatProvider provider) => throw new InvalidCastException(); + float IConvertible.ToSingle(IFormatProvider provider) => throw new InvalidCastException(); + double IConvertible.ToDouble(IFormatProvider provider) => throw new InvalidCastException(); + decimal IConvertible.ToDecimal(IFormatProvider provider) => throw new InvalidCastException(); } } diff --git a/tests/MySqlConnector.Tests/MySqlDateTimeTests.cs b/tests/MySqlConnector.Tests/MySqlDateTimeTests.cs index 6ba65137c..f0391b33b 100644 --- a/tests/MySqlConnector.Tests/MySqlDateTimeTests.cs +++ b/tests/MySqlConnector.Tests/MySqlDateTimeTests.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using MySql.Data.Types; using Xunit; @@ -30,7 +31,7 @@ public void NonZeroMySqlDateTimeIsValidDateTime() [Fact] public void CreateFromDateTime() { - var msdt = new MySqlDateTime(new DateTime(2018, 6, 9, 12, 34, 56, 123).AddTicks(4560)); + var msdt = new MySqlDateTime(s_dateTime); Assert.True(msdt.IsValidDateTime); Assert.Equal(2018, msdt.Year); Assert.Equal(6, msdt.Month); @@ -45,10 +46,10 @@ public void CreateFromDateTime() [Fact] public void GetDateTime() { - var msdt = new MySqlDateTime(2018, 6, 9, 12, 34, 56, 123456); + var msdt = s_mySqlDateTime; Assert.True(msdt.IsValidDateTime); var dt = msdt.GetDateTime(); - Assert.Equal(new DateTime(2018, 6, 9, 12, 34, 56, 123).AddTicks(4560), dt); + Assert.Equal(s_dateTime, dt); } [Fact] @@ -67,5 +68,81 @@ public void SetMicrosecond() msdt.Microsecond = 123456; Assert.Equal(123, msdt.Millisecond); } + + [Fact] + public void ConvertibleToDateTime() + { + IConvertible convertible = s_mySqlDateTime; + var dt = convertible.ToDateTime(CultureInfo.InvariantCulture); + Assert.Equal(s_dateTime, dt); + } + + [Fact] + public void ConvertToDateTime() + { + object obj = s_mySqlDateTime; + var dt = Convert.ToDateTime(obj); + Assert.Equal(s_dateTime, dt); + } + + [Fact] + public void ChangeTypeToDateTime() + { + object obj = s_mySqlDateTime; + var dt = Convert.ChangeType(obj, TypeCode.DateTime); + Assert.Equal(s_dateTime, dt); + } + + [Fact] + public void NotConvertibleToDateTime() + { + IConvertible convertible = new MySqlDateTime(); +#if !BASELINE + Assert.Throws(() => convertible.ToDateTime(CultureInfo.InvariantCulture)); +#else + Assert.Throws(() => convertible.ToDateTime(CultureInfo.InvariantCulture)); +#endif + } + + [Fact] + public void NotConvertToDateTime() + { + object obj = new MySqlDateTime(); +#if !BASELINE + Assert.Throws(() => Convert.ToDateTime(obj)); +#else + Assert.Throws(() => Convert.ToDateTime(obj)); +#endif + } + + [Fact] + public void NotChangeTypeToDateTime() + { + object obj = new MySqlDateTime(); +#if !BASELINE + Assert.Throws(() => Convert.ChangeType(obj, TypeCode.DateTime)); +#else + Assert.Throws(() => Convert.ChangeType(obj, TypeCode.DateTime)); +#endif + } + +#if !BASELINE + [Fact] + public void ValidDateTimeConvertibleToString() + { + IConvertible convertible = s_mySqlDateTime; + Assert.Equal("06/09/2018 12:34:56", convertible.ToString(CultureInfo.InvariantCulture)); + } + + [Fact] + public void InvalidDateTimeConvertibleToString() + { + IConvertible convertible = new MySqlDateTime(); + Assert.Equal("0000-00-00", convertible.ToString(CultureInfo.InvariantCulture)); + } +#endif + + static readonly MySqlDateTime s_mySqlDateTime = new MySqlDateTime(2018, 6, 9, 12, 34, 56, 123456); + static readonly DateTime s_dateTime = new DateTime(2018, 6, 9, 12, 34, 56, 123).AddTicks(4560); } }