65.9K
CodeProject 正在变化。 阅读更多。
Home

日期和时间作为独立类型

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.80/5 (4投票s)

2010 年 5 月 19 日

CPOL

4分钟阅读

viewsIcon

25670

downloadIcon

193

在 SQL Server 2000 及以上版本中使用日期和时间作为独立组件。

INT

介绍  

很多时候我发现自己需要将日期和时间作为单独的类型使用,由于 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,则不会出现此标记。

关注点

使用整数数据类型分别表示日期和时间将为您提供更多控制权和更多选项来编写自己的脚本,您可以使用从 DateTimeToDate 和 DateTimeToTime 生成的整数,就像使用 datetime 数据类型一样,例如,如果日期 2/15/2010 早于 1/1/2000,则第一个日期的结果整数将大于表示最后一个日期的数字,时间也是如此,如果时间 11:00 AM 早于 3:00 PM,则第一个时间的结果整数将小于最后一个时间。
© . All rights reserved.