mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 01:25:40 -05:00
Fix datetimeoffset formatting (#1823)
This commit is contained in:
@@ -81,7 +81,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
{typeof(float), (o, id, col) => ReadSingle(o, id)},
|
||||
{typeof(decimal), (o, id, col) => ReadDecimal(o, id)},
|
||||
{typeof(DateTime), ReadDateTime},
|
||||
{typeof(DateTimeOffset), (o, id, col) => ReadDateTimeOffset(o, id)},
|
||||
{typeof(DateTimeOffset), ReadDateTimeOffset},
|
||||
{typeof(TimeSpan), (o, id, col) => ReadTimeSpan(o, id)},
|
||||
{typeof(byte[]), (o, id, col) => ReadBytes(o, id)},
|
||||
{typeof(Guid), (o, id, col) => ReadGuid(o, id)},
|
||||
@@ -454,8 +454,9 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
/// </summary>
|
||||
/// <param name="offset">Offset into the file to read the DateTimeOffset from</param>
|
||||
/// <param name="rowId">Internal ID of the row that will be stored in the cell</param>
|
||||
/// <param name="col">Column metadata, used for determining what precision to output</param>
|
||||
/// <returns>A DateTimeOffset</returns>
|
||||
internal FileStreamReadResult ReadDateTimeOffset(long offset, long rowId)
|
||||
internal FileStreamReadResult ReadDateTimeOffset(long offset, long rowId, DbColumnWrapper col)
|
||||
{
|
||||
// DateTimeOffset is represented by DateTime.Ticks followed by TimeSpan.Ticks
|
||||
// both as Int64 values
|
||||
@@ -466,8 +467,14 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage
|
||||
return new DateTimeOffset(new DateTime(dtTicks), new TimeSpan(dtOffset));
|
||||
}, null, dt =>
|
||||
{
|
||||
string formatString = $"{DateFormatString} {TimeFormatString}.fffffff zzz";
|
||||
|
||||
int scale = Math.Min(col.NumericScale ?? 7, 7);
|
||||
string formatString = $"{DateFormatString} {TimeFormatString}";
|
||||
if (scale > 0)
|
||||
{
|
||||
string millisecondString = new string('f', scale);
|
||||
formatString += $".{millisecondString}";
|
||||
}
|
||||
formatString += " zzz";
|
||||
return dt.ToString(formatString);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -68,6 +68,8 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.QueryExecution
|
||||
public async Task DateTimeOffsetTest()
|
||||
{
|
||||
await ExecuteAndVerifyResult("SELECT CAST('2020-01-01' AS DATETIMEOFFSET)", "2020-01-01 00:00:00.0000000 +00:00");
|
||||
await ExecuteAndVerifyResult("SELECT CAST('2020-01-01' AS DATETIMEOFFSET(6))", "2020-01-01 00:00:00.000000 +00:00");
|
||||
await ExecuteAndVerifyResult("SELECT CAST('2020-01-01' AS DATETIMEOFFSET(0))", "2020-01-01 00:00:00 +00:00");
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -432,14 +432,39 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
||||
{
|
||||
DateTimeOffset.Now, DateTimeOffset.UtcNow, DateTimeOffset.MinValue, DateTimeOffset.MaxValue
|
||||
};
|
||||
|
||||
// Setup: Create a DATETIMEOFFSET column
|
||||
DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn { DataTypeName = "datetimeoffset", NumericScale = 6 });
|
||||
|
||||
foreach (DateTimeOffset value in testValues)
|
||||
{
|
||||
string displayValue = VerifyReadWrite(sizeof(long)*2 + 1, value, (writer, val) => writer.WriteDateTimeOffset(val),
|
||||
(reader, rowId) => reader.ReadDateTimeOffset(0, rowId));
|
||||
(reader, rowId) => reader.ReadDateTimeOffset(0, rowId, col));
|
||||
|
||||
// Make sure the display value has a time string with 7 milliseconds and a time zone
|
||||
Assert.True(Regex.IsMatch(displayValue, @"^[\d]{4}-[\d]{2}-[\d]{2} [\d]{2}:[\d]{2}:[\d]{2}\.[\d]{7} [+-][01][\d]:[\d]{2}$"));
|
||||
// Make sure the display value has a time string with 6 milliseconds and a time zone
|
||||
Assert.True(Regex.IsMatch(displayValue, @"^[\d]{4}-[\d]{2}-[\d]{2} [\d]{2}:[\d]{2}:[\d]{2}\.[\d]{6} [+-][01][\d]:[\d]{2}$"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DateTimeOffsetZeroScaleTest()
|
||||
{
|
||||
// Setup: Create some test values
|
||||
DateTimeOffset[] testValues =
|
||||
{
|
||||
DateTimeOffset.Now, DateTimeOffset.UtcNow, DateTimeOffset.MinValue, DateTimeOffset.MaxValue
|
||||
};
|
||||
|
||||
// Setup: Create a DATETIMEOFFSET column
|
||||
DbColumnWrapper col = new DbColumnWrapper(new TestDbColumn { DataTypeName = "datetimeoffset", NumericScale = 0 });
|
||||
|
||||
foreach (DateTimeOffset value in testValues)
|
||||
{
|
||||
string displayValue = VerifyReadWrite(sizeof(long) * 2 + 1, value, (writer, val) => writer.WriteDateTimeOffset(val),
|
||||
(reader, rowId) => reader.ReadDateTimeOffset(0, rowId, col));
|
||||
|
||||
// Make sure the display value has a time string with no millisecond and a time zone
|
||||
Assert.True(Regex.IsMatch(displayValue, @"^[\d]{4}-[\d]{2}-[\d]{2} [\d]{2}:[\d]{2}:[\d]{2} [+-][01][\d]:[\d]{2}$"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user