我正在尝试TimeSpan
在SQL Server 2008 R2中存储.Net 。
EF Code First似乎建议将其存储为Time(7)
SQL。
但是,TimeSpan
在.Net中可以处理的时间超过24小时。
TimeSpan
在SQL Server中处理.Net的最佳方法是什么?
我正在尝试TimeSpan
在SQL Server 2008 R2中存储.Net 。
EF Code First似乎建议将其存储为Time(7)
SQL。
但是,TimeSpan
在.Net中可以处理的时间超过24小时。
TimeSpan
在SQL Server中处理.Net的最佳方法是什么?
Answers:
我将其存储在数据库中,BIGINT
并存储了报价的数量(例如TimeSpan.Ticks属性)。
这样,如果我想在检索时获得一个TimeSpan对象,则可以执行TimeSpan.FromTicks(value),这很容易。
SELECT CAST(DATEADD(MILLISECOND, @Ticks/CAST(10000 AS BIGINT), '1900-01-01') AS TIME)
。该'1900-01-01'
日期并不重要,当然,这只是在需要的第三个变量DATEADD(...)
函数。请记住,一跳有100纳秒,但是如果使用,DATEADD(NANOSECOND...
您很可能会溢出,因此使用毫秒。还请记住,应TimeSpan.TicksPerMillisecond
确保使用C#(应为10000)检查此事实。
谢谢你的建议。由于SQL Server中没有等效项。我仅创建了第二个字段,即可将TimeSpan转换为刻度,并将其存储在数据库中。然后,我阻止存储TimeSpan
public Int64 ValidityPeriodTicks { get; set; }
[NotMapped]
public TimeSpan ValidityPeriod
{
get { return TimeSpan.FromTicks(ValidityPeriodTicks); }
set { ValidityPeriodTicks = value.Ticks; }
}
如果您不必存储超过24小时,则只需存储时间,因为SQL Server 2008和更高版本的映射是
time (SQL Server) <-> TimeSpan(.NET)
如果您只需要存储24小时或更短的时间,则无需转换。
来源:http : //msdn.microsoft.com/en-us/library/cc716729(v=vs.110).aspx
但是,如果您要存储24小时以上,则需要将其存储在刻度中,检索数据,然后转换为TimeSpan。例如
int timeData = yourContext.yourTable.FirstOrDefault();
TimeSpan ts = TimeSpan.FromMilliseconds(timeData);
Time
类型不是用来表示持续时间,而是DateTime值的Time部分;这是一个糟糕的选择TimeSpan
。
我知道这是一个老问题,但是我想确保注意了其他两个选项。
由于您不能在time sql数据类型字段中存储超过24小时的TimeSpan;还有其他一些选择。
使用varchar(xx)存储TimeSpan的ToString。这样做的好处是不必将精度放入数据类型或计算中(秒数与毫秒数,天数与两周数),您所需要做的就是使用TimeSpan.Parse / TryParse。这就是我要做的。
使用第二个日期(datetime或datetimeoffset)来存储第一个日期+时间跨度的结果。从数据库中读取数据是TimeSpan x = SecondDate-FirstDate的问题。使用此选项将保护您,防止其他非.NET数据访问库访问相同的数据但不了解TimeSpans。如果您有这样的环境。
为了与可能生成时间跨度(计算2倍或日期时间的差)的最可能来源保持一致,您可能希望将.NET存储TimeSpan
为SQL Server DateTime
类型。
这是因为在SQL Server中,2差DateTime
的(Cast
对Float
的,然后Cast
回DateTime
)是一个简单的DateTime
相对于1月1日,1900实施例。+0.1秒的差异是1900年1月1日00:00:00.100,-0.1秒的差异是1899年12月31日23:59:59.900。
要将.NET转换为TimeSpan
SQL Server DateTime
类型,首先需要将其DateTime
添加到DateTime
1900年1月1日,将其转换为.NET 类型。当然,当您从SQL Server将其读取到.NET时,首先将其读取为.NET DateTime
,然后从中减去1900年1月1日,将其转换为.NETTimeSpan
。
对于使用时间跨度从SQL Server DateTime
以及在SQL Server 中生成时间跨度(即通过T-SQL)并且SQL Server在2016年之前的用例,根据您的范围和精度要求,存储它们可能不切实际。以毫秒为单位(更不用说Ticks
)了,因为Int
Type返回的是DateDiff
(vs. BigInt
SS 2016+DateDiff_Big
在大约24天的毫秒和大约67岁的时间内,溢出。秒。而此解决方案将处理时间跨度,精度从-147到+8,099 yrs低至0.1秒。
警告:
仅当相对于1900年1月1日的差异导致值在SQL Server DateTime
类型范围内(1753年1月1日至9999年12月31日,又称-147至+8,099年)时,此方法才有效。.NET TimeSpan
方面,我们不必担心太多,因为它可以容纳〜29 k至+29 k年。我没有提到SQL Server DateTime2
类型(其不利的一面是它的范围比SQL Server大得多DateTime
),因为:a)无法通过简单的形式将其转换为数字,Cast
并且b)DateTime
的范围应足够适用于绝大多数用例。
SQL服务器 DateTime
通过计算差异Cast
来- - Float
-和-背法似乎并不准确超越0.1秒。
有多种方法可以在数据库中显示时间跨度。
时间
从SQL Server 2008开始支持此数据类型,这是存储的首选方式TimeSpan
。不需要映射。它也适用于SQL代码。
public TimeSpan ValidityPeriod { get; set; }
但是,如原始问题中所述,此数据类型被限制为24小时。
日期时间偏移
该datetimeoffset
数据类型直接映射到System.DateTimeOffset
。它用于表示datetime
/ datetime2
与UTC 之间的偏移量,但也可以将其用于TimeSpan
。
但是,由于数据类型建议使用非常特定的语义,因此您还应该考虑其他选项。
datetime / datetime2
一种方法可能是使用datetime
or datetime2
类型。这是在需要直接处理数据库中值的情况下的最佳选择。用于视图,存储过程或报告。缺点是您需要DateTime(1900,01,01,00,00,00)
从日期中减去值,以获取业务逻辑中的时间跨度。
public DateTime ValidityPeriod { get; set; }
[NotMapped]
public TimeSpan ValidityPeriodTimeSpan
{
get { return ValidityPeriod - DateTime(1900,01,01,00,00,00); }
set { ValidityPeriod = DateTime(1900,01,01,00,00,00) + value; }
}
比金特
另一种方法可能是将TimeSpan转换为刻度并使用bigint
数据类型。但是,这种方法的缺点是在SQL查询中使用起来很麻烦。
public long ValidityPeriod { get; set; }
[NotMapped]
public TimeSpan ValidityPeriodTimeSpan
{
get { return TimeSpan.FromTicks(ValidityPeriod); }
set { ValidityPeriod = value.Ticks; }
}
varchar(N)
这对于值应该为人类可读的情况是最好的。您还可以通过使用CONVERT(datetime, ValidityPeriod)
函数在SQL查询中使用此格式。根据所需的精度,您将需要8到25个字符。
public string ValidityPeriod { get; set; }
[NotMapped]
public TimeSpan ValidityPeriodTimeSpan
{
get { return TimeSpan.Parse(ValidityPeriod); }
set { ValidityPeriod = value.ToString("HH:mm:ss"); }
}
奖励:期限和持续时间
使用字符串,您还可以存储NodaTime数据类型,尤其是Duration
和Period
。第一个基本上与TimeSpan相同,而第二个方面则认为某些天和几个月比其他时间更长或更短(例如,一月为31天,二月为28或29;由于夏令时,某些天会更长或更短) )。在这种情况下,使用TimeSpan是错误的选择。
您可以使用以下代码转换期间:
using NodaTime;
using NodaTime.Serialization.JsonNet;
internal static class PeriodExtensions
{
public static Period ToPeriod(this string input)
{
var js = JsonSerializer.Create(new JsonSerializerSettings());
js.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
var quoted = string.Concat(@"""", input, @"""");
return js.Deserialize<Period>(new JsonTextReader(new StringReader(quoted)));
}
}
然后像
public string ValidityPeriod { get; set; }
[NotMapped]
public Period ValidityPeriodPeriod
{
get => ValidityPeriod.ToPeriod();
set => ValidityPeriod = value.ToString();
}
我真的很喜欢NodaTime
,它常常使我免于棘手的错误和很多头痛。这里的缺点是您真的不能在SQL查询中使用它,而需要在内存中进行计算。
CLR用户定义类型
您还可以选择使用自定义数据类型并TimeSpan
直接支持自定义类。有关详细信息,请参见CLR用户定义的类型。
此处的缺点是数据类型在SQL报表中可能表现不佳。此外,不支持某些版本的SQL Server(Azure,Linux,数据仓库)。
价值转换
从EntityFramework Core 2.1开始,您可以选择使用Value Conversions。
但是,使用此功能时,EF将无法转换许多查询转换为SQL,从而导致查询在内存中运行。可能会将大量数据传输到您的应用程序。
因此,至少到目前为止,最好不要使用它,而只需使用Automapper映射查询结果即可。
通常,我将TimeSpan存储为bigint,并使用前面建议的来自TimeSpan.Ticks属性的刻度进行填充。您还可以将TimeSpan存储为varchar(26),其中填充了TimeSpan.ToString()的输出。我编写的四个标量函数(ConvertFromTimeSpanString,ConvertToTimeSpanString,DateAddTicks,DateDiffTicks)对于在SQL端处理TimeSpan很有帮助,避免了会产生人为限制范围的hack。如果您可以将间隔存储在.NET TimeSpan中,则它也应与这些功能一起使用。此外,即使使用不包含.NET Framework的技术,该功能也允许您使用TimeSpans和100纳秒刻度。
DROP FUNCTION [dbo].[DateDiffTicks]
GO
DROP FUNCTION [dbo].[DateAddTicks]
GO
DROP FUNCTION [dbo].[ConvertToTimeSpanString]
GO
DROP FUNCTION [dbo].[ConvertFromTimeSpanString]
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
-- =============================================
-- Author: James Coe
-- Create date: 2011-05-23
-- Description: Converts from a varchar(26) TimeSpan string to a bigint containing the number of 100 nanosecond ticks.
-- =============================================
/*
[-][d.]hh:mm:ss[.fffffff]
"-"
A minus sign, which indicates a negative time interval. No sign is included for a positive time span.
"d"
The number of days in the time interval. This element is omitted if the time interval is less than one day.
"hh"
The number of hours in the time interval, ranging from 0 to 23.
"mm"
The number of minutes in the time interval, ranging from 0 to 59.
"ss"
The number of seconds in the time interval, ranging from 0 to 59.
"fffffff"
Fractional seconds in the time interval. This element is omitted if the time interval does not include
fractional seconds. If present, fractional seconds are always expressed using seven decimal digits.
*/
CREATE FUNCTION [dbo].[ConvertFromTimeSpanString] (@timeSpan varchar(26))
RETURNS bigint
AS
BEGIN
DECLARE @hourStart int
DECLARE @minuteStart int
DECLARE @secondStart int
DECLARE @ticks bigint
DECLARE @hours bigint
DECLARE @minutes bigint
DECLARE @seconds DECIMAL(9, 7)
SET @hourStart = CHARINDEX('.', @timeSpan) + 1
SET @minuteStart = CHARINDEX(':', @timeSpan) + 1
SET @secondStart = CHARINDEX(':', @timespan, @minuteStart) + 1
SET @ticks = 0
IF (@hourStart > 1 AND @hourStart < @minuteStart)
BEGIN
SET @ticks = CONVERT(bigint, LEFT(@timespan, @hourstart - 2)) * 864000000000
END
ELSE
BEGIN
SET @hourStart = 1
END
SET @hours = CONVERT(bigint, SUBSTRING(@timespan, @hourStart, @minuteStart - @hourStart - 1))
SET @minutes = CONVERT(bigint, SUBSTRING(@timespan, @minuteStart, @secondStart - @minuteStart - 1))
SET @seconds = CONVERT(DECIMAL(9, 7), SUBSTRING(@timespan, @secondStart, LEN(@timeSpan) - @secondStart + 1))
IF (@ticks < 0)
BEGIN
SET @ticks = @ticks - @hours * 36000000000
END
ELSE
BEGIN
SET @ticks = @ticks + @hours * 36000000000
END
IF (@ticks < 0)
BEGIN
SET @ticks = @ticks - @minutes * 600000000
END
ELSE
BEGIN
SET @ticks = @ticks + @minutes * 600000000
END
IF (@ticks < 0)
BEGIN
SET @ticks = @ticks - @seconds * 10000000.0
END
ELSE
BEGIN
SET @ticks = @ticks + @seconds * 10000000.0
END
RETURN @ticks
END
GO
-- =============================================
-- Author: James Coe
-- Create date: 2011-05-23
-- Description: Converts from a bigint containing the number of 100 nanosecond ticks to a varchar(26) TimeSpan string.
-- =============================================
/*
[-][d.]hh:mm:ss[.fffffff]
"-"
A minus sign, which indicates a negative time interval. No sign is included for a positive time span.
"d"
The number of days in the time interval. This element is omitted if the time interval is less than one day.
"hh"
The number of hours in the time interval, ranging from 0 to 23.
"mm"
The number of minutes in the time interval, ranging from 0 to 59.
"ss"
The number of seconds in the time interval, ranging from 0 to 59.
"fffffff"
Fractional seconds in the time interval. This element is omitted if the time interval does not include
fractional seconds. If present, fractional seconds are always expressed using seven decimal digits.
*/
CREATE FUNCTION [dbo].[ConvertToTimeSpanString] (@ticks bigint)
RETURNS varchar(26)
AS
BEGIN
DECLARE @timeSpanString varchar(26)
IF (@ticks < 0)
BEGIN
SET @timeSpanString = '-'
END
ELSE
BEGIN
SET @timeSpanString = ''
END
-- Days
DECLARE @days bigint
SET @days = FLOOR(ABS(@ticks / 864000000000.0))
IF (@days > 0)
BEGIN
SET @timeSpanString = @timeSpanString + CONVERT(varchar(26), @days) + '.'
END
SET @ticks = ABS(@ticks % 864000000000)
-- Hours
SET @timeSpanString = @timeSpanString + RIGHT('0' + CONVERT(varchar(26), FLOOR(@ticks / 36000000000.0)), 2) + ':'
SET @ticks = @ticks % 36000000000
-- Minutes
SET @timeSpanString = @timeSpanString + RIGHT('0' + CONVERT(varchar(26), FLOOR(@ticks / 600000000.0)), 2) + ':'
SET @ticks = @ticks % 600000000
-- Seconds
SET @timeSpanString = @timeSpanString + RIGHT('0' + CONVERT(varchar(26), FLOOR(@ticks / 10000000.0)), 2)
SET @ticks = @ticks % 10000000
-- Fractional Seconds
IF (@ticks > 0)
BEGIN
SET @timeSpanString = @timeSpanString + '.' + LEFT(CONVERT(varchar(26), @ticks) + '0000000', 7)
END
RETURN @timeSpanString
END
GO
-- =============================================
-- Author: James Coe
-- Create date: 2011-05-23
-- Description: Adds the specified number of 100 nanosecond ticks to a date.
-- =============================================
CREATE FUNCTION [dbo].[DateAddTicks] (
@ticks bigint
, @starting_date datetimeoffset
)
RETURNS datetimeoffset
AS
BEGIN
DECLARE @dateTimeResult datetimeoffset
IF (@ticks < 0)
BEGIN
-- Hours
SET @dateTimeResult = DATEADD(HOUR, CEILING(@ticks / 36000000000.0), @starting_date)
SET @ticks = @ticks % 36000000000
-- Seconds
SET @dateTimeResult = DATEADD(SECOND, CEILING(@ticks / 10000000.0), @dateTimeResult)
SET @ticks = @ticks % 10000000
-- Nanoseconds
SET @dateTimeResult = DATEADD(NANOSECOND, @ticks * 100, @dateTimeResult)
END
ELSE
BEGIN
-- Hours
SET @dateTimeResult = DATEADD(HOUR, FLOOR(@ticks / 36000000000.0), @starting_date)
SET @ticks = @ticks % 36000000000
-- Seconds
SET @dateTimeResult = DATEADD(SECOND, FLOOR(@ticks / 10000000.0), @dateTimeResult)
SET @ticks = @ticks % 10000000
-- Nanoseconds
SET @dateTimeResult = DATEADD(NANOSECOND, @ticks * 100, @dateTimeResult)
END
RETURN @dateTimeResult
END
GO
-- =============================================
-- Author: James Coe
-- Create date: 2011-05-23
-- Description: Gets the difference between two dates in 100 nanosecond ticks.
-- =============================================
CREATE FUNCTION [dbo].[DateDiffTicks] (
@starting_date datetimeoffset
, @ending_date datetimeoffset
)
RETURNS bigint
AS
BEGIN
DECLARE @ticks bigint
DECLARE @days bigint
DECLARE @hours bigint
DECLARE @minutes bigint
DECLARE @seconds bigint
SET @hours = DATEDIFF(HOUR, @starting_date, @ending_date)
SET @starting_date = DATEADD(HOUR, @hours, @starting_date)
SET @ticks = @hours * 36000000000
SET @seconds = DATEDIFF(SECOND, @starting_date, @ending_date)
SET @starting_date = DATEADD(SECOND, @seconds, @starting_date)
SET @ticks = @ticks + @seconds * 10000000
SET @ticks = @ticks + CONVERT(bigint, DATEDIFF(NANOSECOND, @starting_date, @ending_date)) / 100
RETURN @ticks
END
GO
--- BEGIN Test Harness ---
SET NOCOUNT ON
DECLARE @dateTimeOffsetMinValue datetimeoffset
DECLARE @dateTimeOffsetMaxValue datetimeoffset
DECLARE @timeSpanMinValueString varchar(26)
DECLARE @timeSpanZeroString varchar(26)
DECLARE @timeSpanMaxValueString varchar(26)
DECLARE @timeSpanMinValueTicks bigint
DECLARE @timeSpanZeroTicks bigint
DECLARE @timeSpanMaxValueTicks bigint
DECLARE @dateTimeOffsetMinMaxDiffTicks bigint
DECLARE @dateTimeOffsetMaxMinDiffTicks bigint
SET @dateTimeOffsetMinValue = '0001-01-01T00:00:00.0000000+00:00'
SET @dateTimeOffsetMaxValue = '9999-12-31T23:59:59.9999999+00:00'
SET @timeSpanMinValueString = '-10675199.02:48:05.4775808'
SET @timeSpanZeroString = '00:00:00'
SET @timeSpanMaxValueString = '10675199.02:48:05.4775807'
SET @timeSpanMinValueTicks = -9223372036854775808
SET @timeSpanZeroTicks = 0
SET @timeSpanMaxValueTicks = 9223372036854775807
SET @dateTimeOffsetMinMaxDiffTicks = 3155378975999999999
SET @dateTimeOffsetMaxMinDiffTicks = -3155378975999999999
-- TimeSpan Conversion Tests
PRINT 'Testing TimeSpan conversions...'
DECLARE @convertToTimeSpanStringMinTicksResult varchar(26)
DECLARE @convertFromTimeSpanStringMinTimeSpanResult bigint
DECLARE @convertToTimeSpanStringZeroTicksResult varchar(26)
DECLARE @convertFromTimeSpanStringZeroTimeSpanResult bigint
DECLARE @convertToTimeSpanStringMaxTicksResult varchar(26)
DECLARE @convertFromTimeSpanStringMaxTimeSpanResult bigint
SET @convertToTimeSpanStringMinTicksResult = dbo.ConvertToTimeSpanString(@timeSpanMinValueTicks)
SET @convertFromTimeSpanStringMinTimeSpanResult = dbo.ConvertFromTimeSpanString(@timeSpanMinValueString)
SET @convertToTimeSpanStringZeroTicksResult = dbo.ConvertToTimeSpanString(@timeSpanZeroTicks)
SET @convertFromTimeSpanStringZeroTimeSpanResult = dbo.ConvertFromTimeSpanString(@timeSpanZeroString)
SET @convertToTimeSpanStringMaxTicksResult = dbo.ConvertToTimeSpanString(@timeSpanMaxValueTicks)
SET @convertFromTimeSpanStringMaxTimeSpanResult = dbo.ConvertFromTimeSpanString(@timeSpanMaxValueString)
-- Test Results
SELECT 'Convert to TimeSpan String from Ticks (Minimum)' AS Test
, CASE
WHEN @convertToTimeSpanStringMinTicksResult = @timeSpanMinValueString
THEN 'Pass'
ELSE 'Fail'
END AS [Test Status]
, @timeSpanMinValueTicks AS [Ticks]
, CONVERT(varchar(26), NULL) AS [TimeSpan String]
, CONVERT(varchar(26), @convertToTimeSpanStringMinTicksResult) AS [Actual Result]
, CONVERT(varchar(26), @timeSpanMinValueString) AS [Expected Result]
UNION ALL
SELECT 'Convert from TimeSpan String to Ticks (Minimum)' AS Test
, CASE
WHEN @convertFromTimeSpanStringMinTimeSpanResult = @timeSpanMinValueTicks
THEN 'Pass'
ELSE 'Fail'
END AS [Test Status]
, NULL AS [Ticks]
, @timeSpanMinValueString AS [TimeSpan String]
, CONVERT(varchar(26), @convertFromTimeSpanStringMinTimeSpanResult) AS [Actual Result]
, CONVERT(varchar(26), @timeSpanMinValueTicks) AS [Expected Result]
UNION ALL
SELECT 'Convert to TimeSpan String from Ticks (Zero)' AS Test
, CASE
WHEN @convertToTimeSpanStringZeroTicksResult = @timeSpanZeroString
THEN 'Pass'
ELSE 'Fail'
END AS [Test Status]
, @timeSpanZeroTicks AS [Ticks]
, CONVERT(varchar(26), NULL) AS [TimeSpan String]
, CONVERT(varchar(26), @convertToTimeSpanStringZeroTicksResult) AS [Actual Result]
, CONVERT(varchar(26), @timeSpanZeroString) AS [Expected Result]
UNION ALL
SELECT 'Convert from TimeSpan String to Ticks (Zero)' AS Test
, CASE
WHEN @convertFromTimeSpanStringZeroTimeSpanResult = @timeSpanZeroTicks
THEN 'Pass'
ELSE 'Fail'
END AS [Test Status]
, NULL AS [Ticks]
, @timeSpanZeroString AS [TimeSpan String]
, CONVERT(varchar(26), @convertFromTimeSpanStringZeroTimeSpanResult) AS [Actual Result]
, CONVERT(varchar(26), @timeSpanZeroTicks) AS [Expected Result]
UNION ALL
SELECT 'Convert to TimeSpan String from Ticks (Maximum)' AS Test
, CASE
WHEN @convertToTimeSpanStringMaxTicksResult = @timeSpanMaxValueString
THEN 'Pass'
ELSE 'Fail'
END AS [Test Status]
, @timeSpanMaxValueTicks AS [Ticks]
, CONVERT(varchar(26), NULL) AS [TimeSpan String]
, CONVERT(varchar(26), @convertToTimeSpanStringMaxTicksResult) AS [Actual Result]
, CONVERT(varchar(26), @timeSpanMaxValueString) AS [Expected Result]
UNION ALL
SELECT 'Convert from TimeSpan String to Ticks (Maximum)' AS Test
, CASE
WHEN @convertFromTimeSpanStringMaxTimeSpanResult = @timeSpanMaxValueTicks
THEN 'Pass'
ELSE 'Fail'
END AS [Test Status]
, NULL AS [Ticks]
, @timeSpanMaxValueString AS [TimeSpan String]
, CONVERT(varchar(26), @convertFromTimeSpanStringMaxTimeSpanResult) AS [Actual Result]
, CONVERT(varchar(26), @timeSpanMaxValueTicks) AS [Expected Result]
-- Ticks Date Add Test
PRINT 'Testing DateAddTicks...'
DECLARE @DateAddTicksPositiveTicksResult datetimeoffset
DECLARE @DateAddTicksZeroTicksResult datetimeoffset
DECLARE @DateAddTicksNegativeTicksResult datetimeoffset
SET @DateAddTicksPositiveTicksResult = dbo.DateAddTicks(@dateTimeOffsetMinMaxDiffTicks, @dateTimeOffsetMinValue)
SET @DateAddTicksZeroTicksResult = dbo.DateAddTicks(@timeSpanZeroTicks, @dateTimeOffsetMinValue)
SET @DateAddTicksNegativeTicksResult = dbo.DateAddTicks(@dateTimeOffsetMaxMinDiffTicks, @dateTimeOffsetMaxValue)
-- Test Results
SELECT 'Date Add with Ticks Test (Positive)' AS Test
, CASE
WHEN @DateAddTicksPositiveTicksResult = @dateTimeOffsetMaxValue
THEN 'Pass'
ELSE 'Fail'
END AS [Test Status]
, @dateTimeOffsetMinMaxDiffTicks AS [Ticks]
, @dateTimeOffsetMinValue AS [Starting Date]
, @DateAddTicksPositiveTicksResult AS [Actual Result]
, @dateTimeOffsetMaxValue AS [Expected Result]
UNION ALL
SELECT 'Date Add with Ticks Test (Zero)' AS Test
, CASE
WHEN @DateAddTicksZeroTicksResult = @dateTimeOffsetMinValue
THEN 'Pass'
ELSE 'Fail'
END AS [Test Status]
, @timeSpanZeroTicks AS [Ticks]
, @dateTimeOffsetMinValue AS [Starting Date]
, @DateAddTicksZeroTicksResult AS [Actual Result]
, @dateTimeOffsetMinValue AS [Expected Result]
UNION ALL
SELECT 'Date Add with Ticks Test (Negative)' AS Test
, CASE
WHEN @DateAddTicksNegativeTicksResult = @dateTimeOffsetMinValue
THEN 'Pass'
ELSE 'Fail'
END AS [Test Status]
, @dateTimeOffsetMaxMinDiffTicks AS [Ticks]
, @dateTimeOffsetMaxValue AS [Starting Date]
, @DateAddTicksNegativeTicksResult AS [Actual Result]
, @dateTimeOffsetMinValue AS [Expected Result]
-- Ticks Date Diff Test
PRINT 'Testing Date Diff Ticks...'
DECLARE @dateDiffTicksMinMaxResult bigint
DECLARE @dateDiffTicksMaxMinResult bigint
SET @dateDiffTicksMinMaxResult = dbo.DateDiffTicks(@dateTimeOffsetMinValue, @dateTimeOffsetMaxValue)
SET @dateDiffTicksMaxMinResult = dbo.DateDiffTicks(@dateTimeOffsetMaxValue, @dateTimeOffsetMinValue)
-- Test Results
SELECT 'Date Difference in Ticks Test (Min, Max)' AS Test
, CASE
WHEN @dateDiffTicksMinMaxResult = @dateTimeOffsetMinMaxDiffTicks
THEN 'Pass'
ELSE 'Fail'
END AS [Test Status]
, @dateTimeOffsetMinValue AS [Starting Date]
, @dateTimeOffsetMaxValue AS [Ending Date]
, @dateDiffTicksMinMaxResult AS [Actual Result]
, @dateTimeOffsetMinMaxDiffTicks AS [Expected Result]
UNION ALL
SELECT 'Date Difference in Ticks Test (Max, Min)' AS Test
, CASE
WHEN @dateDiffTicksMaxMinResult = @dateTimeOffsetMaxMinDiffTicks
THEN 'Pass'
ELSE 'Fail'
END AS [Test Status]
, @dateTimeOffsetMaxValue AS [Starting Date]
, @dateTimeOffsetMinValue AS [Ending Date]
, @dateDiffTicksMaxMinResult AS [Actual Result]
, @dateTimeOffsetMaxMinDiffTicks AS [Expected Result]
PRINT 'Tests Complete.'
GO
--- END Test Harness ---