diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs index 1fc31c287a..b6f8834f6b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs @@ -2812,7 +2812,7 @@ int length /*DTOst*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , X , },/*DateTimeOffset*/ #if NET /*DOnly*/{ _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, X , _ , X , _ , },/*DateOnly*/ -/*TOnly*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , X , _ , _ , },/*TimeOnly*/ +/*TOnly*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , X , _ , _ , },/*TimeOnly*/ #endif /*Strm */{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Stream*/ /*TxRdr*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*TextReader*/ diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs index d8c904f1e0..7739bf70d7 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -7747,7 +7747,16 @@ internal Task WriteSqlVariantValue(object value, int length, int offset, TdsPars case TdsEnums.SQLTIME: stateObj.WriteByte(mt.Scale); //propbytes: scale - WriteTime((TimeSpan)value, mt.Scale, length, stateObj); +#if NET + if (value is TimeOnly timeOnly) + { + WriteTime(timeOnly.ToTimeSpan(), mt.Scale, length, stateObj); + } + else +#endif + { + WriteTime((TimeSpan)value, mt.Scale, length, stateObj); + } break; case TdsEnums.SQLDATETIMEOFFSET: @@ -7923,7 +7932,16 @@ internal Task WriteSqlVariantDataRowValue(object value, TdsParserStateObject sta case TdsEnums.SQLTIME: WriteSqlVariantHeader(8, metatype.TDSType, metatype.PropBytes, stateObj); stateObj.WriteByte(metatype.Scale); //propbytes: scale - WriteTime((TimeSpan)value, metatype.Scale, 5, stateObj); +#if NET + if (value is TimeOnly timeOnly) + { + WriteTime(timeOnly.ToTimeSpan(), metatype.Scale, 5, stateObj); + } + else +#endif + { + WriteTime((TimeSpan)value, metatype.Scale, 5, stateObj); + } break; case TdsEnums.SQLDATETIMEOFFSET: diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/DateTimeVariantTests.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/DateTimeVariantTests.cs index e968295b5a..3c49e1328a 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/DateTimeVariantTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/DateTimeVariantTests.cs @@ -412,6 +412,10 @@ public void TestSqlDataReader_TVP_Type( { value = ((DateOnly)paramValue).ToString(); } + else if (paramValue.GetType() == typeof(TimeOnly)) + { + value = ((TimeOnly)paramValue).ToString("O"); + } #endif else { @@ -487,6 +491,10 @@ public void TestSqlDataReader_TVP_Variant( { value = ((DateOnly)paramValue).ToString(); } + else if (paramValue.GetType() == typeof(TimeOnly)) + { + value = ((TimeOnly)paramValue).ToString("O"); + } #endif else { @@ -559,6 +567,10 @@ public void TestSimpleDataReader_Type( { value = ((DateOnly)paramValue).ToString(); } + else if (paramValue.GetType() == typeof(TimeOnly)) + { + value = ((TimeOnly)paramValue).ToString("O"); + } #endif else { @@ -616,6 +628,10 @@ public void TestSimpleDataReader_Variant( { value = ((DateOnly)paramValue).ToString(); } + else if (paramValue.GetType() == typeof(TimeOnly)) + { + value = ((TimeOnly)paramValue).ToString("O"); + } #endif else { @@ -674,6 +690,10 @@ public void SqlBulkCopySqlDataReader_Type( { value = ((DateOnly)paramValue).ToString(); } + else if (paramValue.GetType() == typeof(TimeOnly)) + { + value = ((TimeOnly)paramValue).ToString("O"); + } #endif else { @@ -747,6 +767,10 @@ public void SqlBulkCopySqlDataReader_Variant( { value = ((DateOnly)paramValue).ToString(); } + else if (paramValue.GetType() == typeof(TimeOnly)) + { + value = ((TimeOnly)paramValue).ToString("O"); + } #endif else { @@ -1223,6 +1247,53 @@ public static IEnumerable GetParameterCombinations() {TestVariations.SqlBulkCopyDataTable_Variant, "datetime"}, {TestVariations.SqlBulkCopyDataRow_Variant, "datetime"} }}; + #if NET + yield return new object[] { TimeOnly.MinValue, "time", + new Dictionary(), + new Dictionary() + { + { TestVariations.TestSimpleParameter_Type, TimeSpan.Zero }, + { TestVariations.TestSimpleParameter_Variant, TimeSpan.Zero }, + { TestVariations.TestSqlDataRecordParameterToTVP_Type, TimeSpan.Zero }, + { TestVariations.TestSqlDataRecordParameterToTVP_Variant, TimeSpan.Zero }, + { TestVariations.TestSqlDataReaderParameterToTVP_Type, TimeSpan.Zero }, + { TestVariations.TestSqlDataReaderParameterToTVP_Variant, TimeSpan.Zero }, + { TestVariations.TestSqlDataReader_TVP_Type, TimeSpan.Zero }, + { TestVariations.TestSqlDataReader_TVP_Variant, TimeSpan.Zero }, + { TestVariations.TestSimpleDataReader_Type, TimeSpan.Zero }, + { TestVariations.TestSimpleDataReader_Variant, TimeSpan.Zero }, + { TestVariations.SqlBulkCopySqlDataReader_Type, TimeSpan.Zero }, + { TestVariations.SqlBulkCopySqlDataReader_Variant, TimeSpan.Zero }, + { TestVariations.SqlBulkCopyDataTable_Type, TimeSpan.Zero }, + { TestVariations.SqlBulkCopyDataTable_Variant, TimeSpan.Zero }, + { TestVariations.SqlBulkCopyDataRow_Type, TimeSpan.Zero }, + { TestVariations.SqlBulkCopyDataRow_Variant, TimeSpan.Zero } + }, + new Dictionary()}; + yield return new object[] { TimeOnly.MaxValue, "time", + new Dictionary(), + new Dictionary() + { + { TestVariations.TestSimpleParameter_Type, new TimeSpan(863999999999) }, + { TestVariations.TestSimpleParameter_Variant, new TimeSpan(863999999999) }, + { TestVariations.TestSqlDataRecordParameterToTVP_Type, new TimeSpan(863999999999) }, + { TestVariations.TestSqlDataRecordParameterToTVP_Variant, new TimeSpan(863999999999) }, + { TestVariations.TestSqlDataReaderParameterToTVP_Type, new TimeSpan(863999999999) }, + { TestVariations.TestSqlDataReaderParameterToTVP_Variant, new TimeSpan(863999999999) }, + { TestVariations.TestSqlDataReader_TVP_Type, new TimeSpan(863999999999) }, + { TestVariations.TestSqlDataReader_TVP_Variant, new TimeSpan(863999999999) }, + { TestVariations.TestSimpleDataReader_Type, new TimeSpan(863999999999) }, + { TestVariations.TestSimpleDataReader_Variant, new TimeSpan(863999999999) }, + { TestVariations.SqlBulkCopySqlDataReader_Type, new TimeSpan(863999999999) }, + { TestVariations.SqlBulkCopySqlDataReader_Variant, new TimeSpan(863999999999) }, + { TestVariations.SqlBulkCopyDataTable_Type, new TimeSpan(863999999999) }, + { TestVariations.SqlBulkCopyDataTable_Variant, new TimeSpan(863999999999) }, + { TestVariations.SqlBulkCopyDataRow_Type, new TimeSpan(863999999999) }, + { TestVariations.SqlBulkCopyDataRow_Variant, new TimeSpan(863999999999) } + }, + new Dictionary() + }; + #endif yield return new object[] { TimeSpan.MinValue, "time", new Dictionary { { TestVariations.TestSimpleParameter_Type, TimeOverflow }, @@ -1244,6 +1315,10 @@ public static IEnumerable GetParameterCombinations() {TestVariations.TestSqlDataRecordParameterToTVP_Variant, TimeSpan.Zero}, }, new Dictionary()}; + yield return new object[] { TimeSpan.FromSeconds(1.0), "time", + new Dictionary(), + new Dictionary(), + new Dictionary()}; yield return new object[] { TimeSpan.MaxValue, "time", new Dictionary { { TestVariations.TestSimpleParameter_Type, TimeOverflow },