I have a 'datetime' column with value 2013-03-22 15:19:02.000
I need to convert this value into epoch time and store it in a 'bigint' field
The actual epoch value for the above time is, 1363945741898, when I use
select DATEDIFF(s, '1970-01-01 00:00:00', '2013-03-22 15:19:02.000')
I get, 1363965542, when I use
select DATEDIFF(ms, '1970-01-01 00:00:00', '2013-03-22 15:19:02.000')
I get,
Msg 535, Level 16, State 0, Line 1
The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.
How to get the exact epoch value from the 'datetime' field
I use SQL Server 2008. Also this should work with 2005.
Here is an example, not tested, written from free hand :)
declare #v_Date datetime
set #v_Date = '2013-03-22 15:19:02.000'
declare #v_DiffInSeconds integer
declare #v_DiffInMSeconds bigint
select #v_DiffInSeconds = DATEDIFF(s, '1970-01-01 00:00:00', #v_Date)
select #v_DiffInMSeconds = cast(#v_DiffInSeconds as bigint) * 1000 + cast(DATEPART(ms, #v_Date) as bigint)
Edit
I have made this example below to illustrate the time zone conversion. The given time stamp (in seconds where I have removed the last three digits "898") is here converted to the local IST time zone by adding the 5.5 hours (19800 seconds) and I convert it back to the time stamp from local time to GMT again. Below calculations matches the values in the question (in seconds).
declare #v_time datetime
set #v_time = '1970-01-01 00:00:00'
declare #v_date datetime
set #v_date = '2013-03-22 15:19:01'
-- This returns "March, 22 2013 15:19:01"
select dateadd(s, (1363945741 + 19800), #v_time)
-- This returns "1363945741"
select datediff(s, #v_time, #v_date) - 19800
When tried to get exact milliseconds we get the overflow exception. we can get the values till seconds and multiply with 1000.
This is equivalent to new Date().getTime() in javascript:
Use the below statement to get the time in seconds.
SELECT cast(DATEDIFF(s, '1970-01-01 00:00:00.000', '2016-12-09 16:22:17.897' ) as bigint)
Use the below statement to get the time in milliseconds.
SELECT cast(DATEDIFF(s, '1970-01-01 00:00:00.000', '2016-12-09 16:22:17.897' ) as bigint) * 1000
convert epoch to human readable date time using below statement:
select DATEADD(s, 1481300537, '1970-01-01 00:00:00')
Epoch to datetime
create function [dbo].[EpochToDate](#Date bigint)
returns datetime
begin
return (select dateadd(s, #Date, '19700101'))
end
Use below code to get human readable date from epoch time
select DATEADD(s,convert(bigint,#date)/2, DATEADD(s, convert(bigint,#date)/2, '1970-01-01 00:00:00'))
Related
Looking for the most efficient and elegant way to do truncate the time to the minute
-- I need to truncate the time to the minute,
-- this code almost works but rounds up
SELECT
CAST('2021-09-02T15:15:30.9233333' AS datetime2(7)) AS EventDatetime2,
CAST(CAST('2021-09-02T15:15:30.9233333' AS datetime2(7)) AS TIME(0)) AS EventTime
As Larnu posted, if you want to round up or down depending on the seconds value, a simple convert to smalldatetime will do.
If you want to truncate, there are several ways, the simplest is probably just to add minutes to midnight (only posting because I prefer without the magic dates like 1900-01-01):
DECLARE #dt datetime2(7) = '2021-09-02T15:15:30.9233333';
DECLARE #d datetime2(7) = CONVERT(date, #dt);
SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, #d, #dt), #d);
Another way is more intuitive but a little ugly:
DECLARE #dt datetime2(7) = '2021-09-02T15:15:30.9233333';
SELECT SMALLDATETIMEFROMPARTS
(
DATEPART(YEAR, #dt),
DATEPART(MONTH, #dt),
DATEPART(DAY, #dt),
DATEPART(HOUR, #dt),
DATEPART(MINUTE, #dt)
);
If you want to "round" to the nearest minute you could just CONVERT the value to a smalldatetime; they are only accurate to 1 minute:
SELECT CONVERT(smalldatetime,CONVERT(datetime2,'2021-09-02T15:15:30.9233333'));
If you want to, you can then CONVERT back to your original data type.
If you want to truncate (so strip the minutes) you could use the old DATEDIFF and DATEADD method:
DECLARE #DateTime2 datetime2(7) = '2021-09-02T15:15:30.9233333';
SELECT DATEADD(MINUTE,DATEDIFF(MINUTE,'19000101',#DateTime2),CONVERT(datetime2(7),'19000101'));
Just another option using left() and the implicit conversion.
Depending on the actual USE CASE, the outer convert() is optional
Example
DECLARE #dt datetime2(7) = '2021-09-02T15:15:30.9233333';
select convert(smalldatetime,left(#dt,16))
Results
2021-09-02 15:15:00
Combining the DATEADD and CAST(... AS SMALLDATETIME) approaches effectively gives you a minute "floor", like so:
SELECT CAST('2021-09-02T15:15:30.9233333' AS DATETIME2(7)) AS EventDatetime2,
CAST(CAST('2021-09-02T15:15:30.9233333' AS DATETIME2(7)) AS TIME(0)) AS EventTime,
CAST(CAST(DATEADD(
SECOND,
(DATEPART(SECOND, CAST('2021-09-02T15:15:30.9233333' AS DATETIME2(7))) * -1),
CAST('2021-09-02T15:15:30.9233333' AS DATETIME2(7))) AS SMALLDATETIME) AS TIME(0));
EventDatetime2
EventTime
(No column name)
2021-09-02 15:15:30.9233333
15:15:31
15:15:00
The DATEADD in this example subtracts the number of seconds from the datetime before converting it to a smalldatetime, so when that cast/convert does its rounding it will always go to the lower minute.
If, however, your input value is the sort of string literal that the wording of your question implies, you could also do this:
SELECT CAST(SUBSTRING('2021-09-02T15:15:30.9233333', CHARINDEX('T', '2021-09-02T15:15:30.9233333')+1, 6) + '00' AS TIME(0));
and get this result:
15:15:00
I'm stuck in finding an answer on how to convert:
07-DEC-18 01.00.54.984000 PM to 2018-12-07 13.00.54.984000
I think the time of 01.00.54 PM is 13hours , 0 minutes and 54 seconds
I have try to convert with 112 but still i can't find out how to cast or convert this.
Below is one method that converts the date and time portions separately, and then uses DATEADD to combine the results. This assumes the actual time precision is not greater than milliseconds. Note that you need to use datetime2 instead of datetime to avoid rounding to 1/300 milliseconds.
DECLARE #DateTimeString varchar(30) = '07-DEC-18 01.00.54.984000 PM';
SELECT DATEADD(
millisecond
, DATEDIFF(millisecond, '', CAST(REPLACE(SUBSTRING(#DateTimeString, 11, 8), '.', ':') + RIGHT(#DateTimeString, 10) AS time))
, CAST(LEFT(#DateTimeString, 9) AS datetime2)
);
This converts your value to the datatype it should be, a datetime2(6). Date and time datatypes don't have formats, if you're storing them in a particular format you're doing it wrong (as it means you're storing the value as a varchar).
DECLARE #YourDate varchar(30) = '07-DEC-18 01.00.54.984000 PM';
SELECT V.YD,
TRY_CONVERT(datetime2(6),F.FormatedYD,106)
FROM (VALUES(#YourDate)) V(YD)
CROSS APPLY (VALUES(STUFF(STUFF(V.YD,13,1,':'),16,1,':'))) F(FormatedYD);
If this was a table, then I would fix your actual column datatype by doing the following:
UPDATE YT
SET YourDateColumn = CONVERT(varchar(30),TRY_CONVERT(datetime2(6),F.FormatedYD,106),126)
FROM YourTable YT
CROSS APPLY (VALUES(STUFF(STUFF(YT.YourDateColumn,13,1,':'),16,1,':'))) F(FormatedYD);
ALTER TABLE YourTable ALTER COLUMN YourDateColumn datetime2(6);
I have made a function in SQL to calculate the Age from the Birthday and it is like this:
FUNCTION [dbo].[GetAge] (#birthday datetime, #date datetime)
RETURNS int
AS
BEGIN
return datediff(SECOND, #birthday, #date) / (365.23076923074 * 24 * 60 * 60)
END
The birthday is of format : 1963-01-01 00:00:00.000
My problem is that when I call the function like this :
SELECT dbo.GetAge(birthday, '2014-12-17 00:00:00')
FROM [dbo].[Users]
GO
it says:
Msg 535, Level 16, State 0, Line 3
The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.
BUT I call the same function with a date like :
SELECT dbo.GetAge(birthday, '1963-01-01 00:00:00')
FROM [dbo].[Users]
GO
I get the results..
So I don't understand what is the problem.
Pls help me and thank you in advance
The error says it all. "Try to use datediff with a less precise datepart"
return DATEDIFF(DAY, '1963-01-01 00:00:00', '2014-12-17 00:00:00') / (365.23076923074)
Seems obvious..the number of seconds from a user's birthday to today is too many for whatever datatype MySQL uses for DATEDIFF. But it's not too many from 1/1/1963.
Change your function to use a less precise datepart, i.e. minute instead of second.
FUNCTION [dbo].[GetAge] (#birthday datetime, #date datetime)
RETURNS int
AS
BEGIN
return datediff(MINUTE, #birthday, #date) / (365.23076923074 * 24 * 60)
END
OR hour
FUNCTION [dbo].[GetAge] (#birthday datetime, #date datetime)
RETURNS int
AS
BEGIN
return datediff(HOUR, #birthday, #date) / (365.23076923074 * 24)
END
OR DAY
FUNCTION [dbo].[GetAge] (#birthday datetime, #date datetime)
RETURNS int
AS
BEGIN
return datediff(DAY, #birthday, #date) / (365.23076923074)
END
Why not just DATEDIFF(year, #birthday, #date)? You only want the whole number of years, right?
Try casting your birthday to a date before sending it off.
SELECT dbo.GetAge(birthday, select cast('1963-01-01 00:00:00.000' as date))
FROM [dbo].[Users]
GO
I am storing all my dates in SQL Server Datetime fields in UTC Date.
There is a requirement where by I have to calculate local Datetime in a procedure from the UTC Date field, and for that i have the Time zone offset of the local datetime.
For ex. my Timezone offset is:'05:30:00'
and UTC Date is: 2013-02-09 08:34:12.037
Desired output: 2013-02-09 14:04:12.037
Now is there a simple way where of doing this without DateAdd and splitting the offset in hours and minutes.
You should be able to use the SWITCHOFFSET function. Here is an example:
declare #dt datetime;
set #dt = '2013-02-09 08:34:12.037';
select SWITCHOFFSET(CONVERT(datetimeoffset, #dt), '+05:30') as 'DATETIMEOFFSET',
CAST(SWITCHOFFSET(CONVERT(datetimeoffset, #dt), '+05:30') as datetime) as 'DATETIME'
-- Outputs:
--
-- 2013-02-09 14:04:12.0370000 +05:30 2013-02-09 14:04:12.037
Use the convert with 112:
declare #d datetime
set #d = getdate()
declare #s nvarchar(20)
set #s = convert(varchar, #d, 112)
print #s
That string will have the year, month, seconds etc.. always on the same position
Extract the desired part with substring:
print substring(#s, 1, 4) -- the year
Now recalculate the entire thing to minutes, by multiplying the hours by 60 and adding the minutes. Now substract your minutes delta from that number. Build a new string with the adjusted date-time, and convert that back to datetime. But... if you need to know the date as well, and you want to do it correct.... there is some coding left.
My advice: do use dateadd it's simple and correct (substract minutes is my advice).
I want to convert UTC milliseconds to DateTime in SQL server.
This can easily be done in C# by following code:
DateTime startDate = new DateTime(1970, 1, 1).AddMilliseconds(1348203320000);
I need to do this in SQL server. I found some script here, but this was taking initial ticks from 1900-01-01.
I have used the DATEADD function as below, but this was giving an arithmetic overflow exception by supping milliseconds as difference:
SELECT DATEADD(MILLISECOND,1348203320000,'1970-1-1')
How can I do the conversion properly?
DECLARE #UTC BIGINT
SET #UTC = 1348203320997
SELECT DATEADD(MILLISECOND, #UTC % 1000, DATEADD(SECOND, #UTC / 1000, '19700101'))
Below the function that converts milliseconds to datetime
IF object_id('dbo.toDbTimeMSC', 'FN') IS NOT NULL DROP FUNCTION dbo.toDbTimeMSC
GO
CREATE FUNCTION [dbo].[toDbTimeMSC] (#unixTimeMSC BIGINT) RETURNS DATETIME
BEGIN
RETURN DATEADD(MILLISECOND, #unixTimeMSC % 1000, DATEADD(SECOND, #unixTimeMSC / 1000, '19700101'))
END
GO
-- select dbo.toDbTimeMSC(1348203320000)
I had problems with using answers given here (especially that the system was counting ticks form 0001-01-01) - so I did this:
CONVERT(DATETIME,[Time]/ 10000.0/1000/86400-693595)
--explanation for [Time_in_Ticks]/ 10000.0/1000/86400-693595
--Time is in "ticks"
--10000 = number of ticks in Milisecond
--1000 = number of milisecons in second
--86400 = number of seconds in a day (24hours*60minutes*60second)
--693595= number of days between 0001-01-01 and 1900-01-01 (which is base
-- date when converting from int to datetime)
Using SQL Server 2008R2 this produced the required result:
CAST(SWITCHOFFSET(CAST(dateadd(s, convert(bigint, [t_stamp]) / 1000, convert(datetime, '1-1-1970 00:00:00')) AS DATETIMEOFFSET), DATENAME (TZoffset, SYSDATETIMEOFFSET())) AS DATETIME)
The DATEADD requires an integer as a second argument. Your number 1348203320000 is very large for integer therefore it produce an error in runtime. Your should use bigint type instead and provide DATEADD with correct int values by splitting your milliseconds to seconds and milliseconds. That is sample you could use.
DECLARE #total bigint = 1348203320000;
DECLARE #seconds int = #total / 1000
DECLARE #milliseconds int = #total % 1000;
DECLARE #result datetime = '1970-1-1';
SET #result = DATEADD(SECOND, #seconds,#result);
SET #result = DATEADD(MILLISECOND, #milliseconds,#result);
SELECT #result
Right now, you can use dateadd with division on minutes and not seconds.
The code will be like this:
DATEADD(MILLISECOND, epoch% 60000, DATEADD(MINUTE, epoch/ 60000, '19700101'));
=dateadd("d",INT((Fields!lastLogon.Value / 864000000000)- 134774),"1970-01-01 00:00:00")
That's what I used in SSRS to get around the INT error, use days instead of seconds. Is it wrong?