A common problem in moving data between SQL Server and UNIX systems is converting to/from the SQL Server datetime format to the UNIX time format.There are several UNIX time formats, but the most common is a signed 32-bit integer that represents time as the number of seconds between 1970-01-01 00:00:00 and a given time. The functions in the script can be use to convert between SQL Server datetime and this UNIX time format.For more information on UNIX Time, please read this link:http://en.wikipedia.org/wiki/Unix_timeFor more information about SQL Server date/time conversions, refer to this link:Date/Time Info and Script Linkshttp://www.sqlteam.com/forums/topic.asp?TOPIC_ID=64762The conversion of UNIX Time to SQL Server datetime is fairly trivial using the SQL Server DATEADD function, and this is the logic used by the F_UNIX_TIME_TO_DATETIME function in the script:declare @UNIX_TIME intselect @UNIX_TIME = 1111111111-- Using dateadd to add seconds to 1970-01-01select [Datetime from UNIX Time] = dateadd(ss,@UNIX_TIME,'1970-01-01')
Results:Datetime from UNIX Time ------------------------------------------------------ 2005-03-18 01:58:31.000(1 row(s) affected)
The conversion of SQL Server datetime to UNIX Time is more complex. SQL Server datetime is accurate to milliseconds so is necessary to either truncate or round off the time to a whole second. The function in the F_DATETIME_TO_UNIX_TIME script rounds the time down if milliseconds is less than 500 and up otherwise. A second problem is that UNIX Time is an integer, so it can only represent time from 1901-12-13 20:45:52 through 2038-01-19 03:14:07. The range of SQL Server datetime is 1753-01-01 through 9999-12-31, so the function in the script has logic to return a NULL if the datetime is outside the valid UNIX Time range. Another minor issue is that the SQL Server DATEDIFF function will not cover the full range of an integer value with seconds, so it is necessary to have additional logic in the function do cover the time from 1901-12-13 20:45:52 to 1901-12-14 00:00:00.The function names created by this script are:dbo.F_DATETIME_TO_UNIX_TIME( @DAY )dbo.F_UNIX_TIME_TO_DATETIME( @UNIX_TIME )The script also includes code to test and demo the functions.if objectproperty(object_id('dbo.F_DATETIME_TO_UNIX_TIME'),'IsScalarFunction') = 1 begin drop function dbo.F_DATETIME_TO_UNIX_TIME endgocreate function dbo.F_DATETIME_TO_UNIX_TIME ( @DAY datetime )returns intas/*Function: F_DATETIME_TO_UNIX_TIME Finds UNIX time as the difference in seconds between 1970-01-01 00:00:00 and input parameter @DAY after rounding @DAY to the neareast whoie second. Valid datetime range is 1901-12-13 20:45:51.500 through 2038-01-19 03:14:07.497. This range is limited to the smallest through the largest possible integer. Datetimes outside this range will return null.*/begindeclare @wkdt datetime-- Return null if outside of valid UNIX Time rangeif @DAY < '1901-12-13 20:45:51.500' or @DAY > '2038-01-19 03:14:07.497' return null-- Round off datetime to nearest whole secondselect @wkdt = dateadd(ms,round(datepart(ms,@DAY),-3)-datepart(ms,@DAY),@DAY)-- If date GE 1901-12-14if @wkdt >= 712 return datediff(ss,25567,@wkdt) -- Handles time GE '1901-12-13 20:45:52.000 and LT 1901-12-14return -2147472000-datediff(ss,@wkdt,712)endgoif objectproperty(object_id('dbo.F_UNIX_TIME_TO_DATETIME'),'IsScalarFunction') = 1 begin drop function dbo.F_UNIX_TIME_TO_DATETIME endgocreate function dbo.F_UNIX_TIME_TO_DATETIME ( @UNIX_TIME int )returns datetimeas/*Function: F_UNIX_TIME_TO_DATETIME Converts UNIX time represented as the difference in seconds between 1970-01-01 00:00:00 to a datetime. Any valid integer -2,147,483,648 through 2,147,483,647 can be converted to datetime.*/beginreturn dateadd(ss,@UNIX_TIME,25567)endgogo/*Demo functions F_DATETIME_TO_UNIX_TIME and F_UNIX_TIME_TO_DATETIME by converting a datetimeto UNIX time and back to datetime.*/select [Input Datetime] = convert(varchar(23),DT,121), [UNIX Time] = dbo. F_DATETIME_TO_UNIX_TIME(a.dt), [Datetime from UNIX Time] = -- Convert datetime to UNIX time an back to Datetime convert(varchar(23), dbo. F_UNIX_TIME_TO_DATETIME(dbo. F_DATETIME_TO_UNIX_TIME(a.dt)),121), Note = .a.notefrom(select DT = getdate(), Note = 'Current date'union allselect DT = dateadd(ms,500,getdate()), Note = 'Current date + 500 ms'union allselect DT = dateadd(ms,750,getdate()), Note = 'Current date + 750 ms'union allselect DT = '1901-12-13 20:45:51.500', Note = 'Earliest datetime function can convert'union allselect DT = '2038-01-19 03:14:07.497', Note = 'Last datetime function can convert'union allselect DT = '2001-09-09 01:46:40', Note ='UNIX time 1000000000'union allselect DT = '2005-03-18 01:58:31', Note = 'UNIX time 1111111111'union allselect DT = '2009-02-13 23:31:30', Note ='UNIX time 1234567890'union allselect DT = '1901-12-14 00:00:00.000', Note = 'Date time dateadd second limit'union allselect DT = '1901-12-13 23:59:59.000', Note = 'Date time dateadd outside second limit'union allselect DT = '1901-12-13 20:45:51.497', Note = 'Date time function cannot convert - low end'union allselect DT = '2038-01-19 03:14:07.500', Note = 'Date time function cannot convert - high end'union allselect DT = '1753-01-01 00:00:00.000', Note = 'Min Datetime'union allselect DT = '9999-12-31 23:59:59.997', Note = 'Max Datetime') a
Results:Input Datetime UNIX Time Datetime from UNIX Time Note ----------------------- ----------- ----------------------- -------------------------------------------- 2006-05-29 23:34:11.517 1148945652 2006-05-29 23:34:12.000 Current date2006-05-29 23:34:12.017 1148945652 2006-05-29 23:34:12.000 Current date + 500 ms2006-05-29 23:34:12.267 1148945652 2006-05-29 23:34:12.000 Current date + 750 ms1901-12-13 20:45:51.500 -2147483648 1901-12-13 20:45:52.000 Earliest datetime function can convert2038-01-19 03:14:07.497 2147483647 2038-01-19 03:14:07.000 Last datetime function can convert2001-09-09 01:46:40.000 1000000000 2001-09-09 01:46:40.000 UNIX time 10000000002005-03-18 01:58:31.000 1111111111 2005-03-18 01:58:31.000 UNIX time 11111111112009-02-13 23:31:30.000 1234567890 2009-02-13 23:31:30.000 UNIX time 12345678901901-12-14 00:00:00.000 -2147472000 1901-12-14 00:00:00.000 Date time dateadd second limit1901-12-13 23:59:59.000 -2147472001 1901-12-13 23:59:59.000 Date time dateadd outside second limit1901-12-13 20:45:51.497 NULL NULL Date time function cannot convert - low end2038-01-19 03:14:07.500 NULL NULL Date time function cannot convert - high end1753-01-01 00:00:00.000 NULL NULL Min Datetime9999-12-31 23:59:59.997 NULL NULL Max Datetime(14 row(s) affected)
Edit: Fixed minor bug that caused an overflow, instead of returning NULL, if input to function F_DATETIME_TO_UNIX_TIME was >= 9999-12-31 23:59:59.500.CODO ERGO SUM