日期和时间作为独立类型
在 SQL Server 2000 及以上版本中使用日期和时间作为独立组件。
介绍
很多时候我发现自己需要将日期和时间作为单独的类型使用,由于 SQL Server 2000 和 SQL Server 2005 没有这个选项,所以我必须找到一种方法,而我找到的方法就是本文的重点。
我修改了一些旧脚本以解决性能问题,您可以在“SQL Server 脚本 v2”下下载新版本
背景
Datetime 存储在 8 个字节中,内部表示如下
前 4 个字节用于日期,日期单位是天,基准日期是 1-1-1900
接下来的 4 个字节用于时间,时间单位是每秒 300,基准时间是零,表示凌晨 12:00
现在我们将使用 datetime 函数进行分离。
使用代码
现在我们将从编写函数 DateTimeToDate 开始,该函数从以下位置返回整数形式的日期
CREATE FUNCTION dbo.DateTimeToDate
(@datetime DATETIME)
RETURNS INT
AS
BEGIN
DECLARE @date INT
SET @date = 0
IF @datetime IS NOT NULL
SET @date = DATEDIFF(DAY, 0, @datetime)
RETURN @date
END
我们在这里所做的一切就是获取传入日期自 1-1-1900 以来经过的天数
下一个函数是 DateTimeToTime,它返回自午夜以来的秒数
CREATE FUNCTION dbo.DateTimeToTime
(@datetime DATETIME)
RETURNS INT
AS
BEGIN
DECLARE @time INT
SET @time = 0
IF @datetime IS NOT NULL
SET @time = CONVERT(int, CONVERT(BINARY(8), @datetime)) / 300
RETURN @time
END
正如您所看到的,我们将时间结果除以 300 以获取经过时间的秒数。
下一个函数是 DateToDateTime,它只接受日期并返回表示该日期的 datetime
CREATE FUNCTION dbo.DateToDateTime
(@date INT)
RETURNS DATETIME
AS
BEGIN
RETURN DATEADD(DAY, ISNULL(@date, 0), 0)
END
由于我们使用的日期是自 1-1-1900 以来经过的天数,因此我们获得 datetime 实例所要做的就是将该天数加到 1-1-1900,以再次获得 datetime 数据类型中的日期。
您可能注意到我们向零添加了经过的天数,这是正确的,因为 1-1-1900 是基准日期;我们可以将其称为 0,而不是字符串版本 '1-1-1900'
下一个函数是 TimeToDateTime,它将时间存储回 datetime 格式
CREATE FUNCTION dbo.TimeToDateTime
(@time INT, @date INT)
RETURNS DATETIME
AS
BEGIN
RETURN DATEADD(second, ISNULL(@time, 0), ISNULL(dbo.DateToDateTime(@date), 0))
END
正如您所看到的,此函数接受 2 个参数,这是因为 datetime 数据类型不允许您在没有日期的前提下使用时间,因此要以 datetime 格式返回时间,您必须指定一个日期,或者您可以传递 null 来使用基准日期。
目前一切都很好,您可以使用从上述函数返回的值做任何您想做的事情,您可以使用整数值做任何您想做的比较,但是这里缺少一些东西,至少对我来说是,那就是格式化。
对于我们许多人来说,在 SQL Server 中格式化 datetime 是一件令人头疼的事情,那么我们将如何格式化这些分离的类型呢?实际上,我另外编写了 2 个函数,它们分别是 DateToString 和 TimeToString,它们所做的只是格式化日期和时间,而无需将它们转换为任何其他格式,这两个函数是:(代码在附件中)
CREATE FUNCTION dbo.DateToString
(@date INT, @split CHAR, @format VARCHAR(3))
RETURNS VARCHAR(10)
CREATE FUNCTION [dbo].[TimeToString]
(@time INT, @use24 BIT, @showAM_PM BIT)
RETURNS VARCHAR(12)
对于函数 DateToString
@date:是从函数 DateTimeToDate 返回的日期,如果为 null,则不返回任何内容。
@split:用于分隔日、月、年的单个字符,如果为 null,则默认字符为'-'。
@format:是日期的排列方式,使用 D 表示日,M 表示月,Y 表示年,例如“MDY”将产生月-日-年,如果为 null,则默认为“DMY”。
对于函数 TimeToString
@time:是从函数 DateTimeToTime 返回的时间,如果为 null,则不返回任何内容。
@use24:如果为 1,则返回的格式为 24 小时制,并且忽略下一个参数,如果为 0,则返回的格式为 12 小时制。
@showAM_PM:如果为 1,则“AM”或“PM”将出现在时间的末尾,如果为 0,则不会出现此标记。