{# days since ANSI 0} = {AD timestamp} / {# 100ns/day}
{# days since SQL 0} = {# days since ANSI 0} - {# days from ANSI 0 to SQL 0}
DECLARE @timestamp BIGINT
SET @timestamp = 128881226539059241
;
SELECT CAST((@timestamp / 864000000000.0 - 109207) AS DATETIME)
;
Simple!
2009-05-30 02:04:13.903
Set objUser = _
GetObject("LDAP://cn=Ken Myer, ou=Finance, dc=fabrikam, dc=com")
Set objLastLogon = objUser.Get("lastLogonTimestamp")
intLastLogonTime = objLastLogon.HighPart * (2^32) _
+ objLastLogon.LowPart
'Added this echo
Wscript.Echo "Timestamp: " & intLastLogonTime
intLastLogonTime = intLastLogonTime / (60 * 10000000)
intLastLogonTime = intLastLogonTime / 1440
Wscript.Echo "Last logon time: " & intLastLogonTime _
+ #1/1/1601#
*NOTE: change LDAP path to correct value for your environment.
DECLARE @timestamp BIGINT
SET @timestamp = 128881226539059241
;
DECLARE @tzOffset INT
SET @tzOffset = DATEDIFF(mi, GETUTCDATE(), GETDATE())
;
SELECT DATEADD(mi, @tzOffset, (@timestamp / 864000000000.0 - 109207))
;
Equally simple!
-- =============================================
-- Author: mwvisa1
-- Create date: 2009.05.29 22:35
-- Last modified: 2009.06.04 18:15
-- Description:
-- Convert Active Directory (AD)
-- based timestamps to SQL datetime.
-- =============================================
CREATE FUNCTION dbo.fn_GetDatetimeFromADTimestamp
(
-- AD timestamp to be converted
@timestamp BIGINT,
-- flag determining if local time zone,
-- or GMT should be returned
@asLocalTime BIT = 0
)
RETURNS DATETIME
AS
BEGIN
-- variable to store resulting date
DECLARE @datetime DATETIME
-- if local timezone flag set,
-- then adjust offset minutes for timezone,
-- or 0 for GMT.
DECLARE @tzOffset INT
SET @tzOffset =
CASE COALESCE(@asLocalTime, 0)
WHEN 1 THEN
DATEDIFF(mi,
GETUTCDATE(),
GETDATE()
)
ELSE 0
END
;
-- calculate SQL number of days since date 0
/*
864000000000 (86400 * 10000000)
is the number of 100ns intervals per day,
which is significant as AD timestamp is:
the # of 100ns since 1601-01-01 00:00:00.000.
:86400 == number of seconds per day
:10000000 == number of 100ns per second
109207 (299 * 365 + 72) is:
the offset # of days from 1601-01-01 (ANSI 0)
to 1900-01-01 (SQL 0).
:299 == number of years between 1601 and 1900
:365 == standard days per year
:72 == number of leap years between 1601 and 1900
*/
DECLARE @timestampInDays FLOAT
SET @timestampInDays = @timestamp / 864000000000.0 - 109207
;
-- -53690 is: # days from 1900-01-01 to 1753-01-01.
-- (i.e., datediff(d, 0, '1753-01-01'))
-- 1753-01-01 is minimum date in SQL Server 2005 or lower.
-- (limit of datetime data type)
-- try / catch not yet implemented in functions!!
IF @timestampInDays >= -53690
BEGIN
SET @datetime = DATEADD(mi, @tzOffset, @timestampInDays)
END
;
-- return the result of the function
RETURN @datetime;
END
DECLARE @timestamp BIGINT
DECLARE @asLocalTime BIT
SET @timestamp = 128881226539059241
SET @asLocalTime = 0
;
SELECT
dbo.fn_GetDatetimeFromADTimestamp(
@timestamp,
@asLocalTime
)
;
2009-05-30 02:04:13.903
With @asLocaltime set to 1, you will get results offset for your specific timezone.
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (2)
Commented:
Commented:
CREATE FUNCTION SQLDateTimeToADTimestamp
(
@datetime DATETIME
)
RETURNS BIGINT
AS
BEGIN
RETURN CAST(DATEDIFF(MINUTE, '1601-01-01 00:00:00', @datetime) AS BIGINT) * 600000000
END
GO