I want to convert a value from bigint to datetime.
For example, I'm reading the HISTORY table of teamcity server. On the field build_start_time_server, I have this value on one record 1283174502729.
How can I convert it to a datetime value?
Does this work for you? It returns 30-8-2010 13:21:42 at the moment on SQL Server 2005:
select dateadd(s, convert(bigint, 1283174502729) / 1000, convert(datetime, '1-1-1970 00:00:00'))
I've divided by 1000 because the dateadd function won't work with a number that large. So you do lose a little precision, but it is much simpler to use.
Slightly different approach:
Your scenario:
SELECT dateadd(ms, 1283174502729 / 86400000, (1283174502729 / 86400000) + 25567)
FROM yourtable
Generic code:
SELECT dateadd(ms, yourfield / 86400000, (yourfield / 86400000) + 25567)
FROM yourtable
Output:
August, 30 2010 00:00:14
SQL Fiddle: http://sqlfiddle.com/#!3/c9eb5a/2/0
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 following takes new SQL terminology into account and will return the milliseconds (can also be modified for use in a calculated field.) [SQL Server 2012 or later]
declare #StartDate datetime2(3) = '1970-01-01 00:00:00.000'
, #milliseconds bigint = 1283174502729
, #MillisecondsPerDay int = 60 * 60 * 24 * 1000 -- = 86400000
SELECT DATEADD(MILLISECOND, TRY_CAST(#milliseconds % #millisecondsPerDay AS
INT), DATEADD(DAY, TRY_CAST(#milliseconds / #millisecondsPerDay AS INT),
#StartDate));
select Cast(Cast(19980324 as nvarchar) as Datetime)
If you want precision in milliseconds to be maintained then you could do as follows. Works on SQL server 2016
SELECT dateadd(ms, ((CONVERT(bigint, build_start_time_server)%1000)),
dateadd(ss, ((CONVERT(bigint, build_start_time_server)/1000)%60),
dateadd(mi, ((CONVERT(bigint, build_start_time_server)/1000)/60), '1970-01-01'))) FROM yourtable
The answer I got was
Monday, August 30, 2010 1:21 PM
To convert bigint to datetime/unixtime, you must divide these values by 1000000 (10e6) before casting to a timestamp.
SELECT
CAST( bigIntTime_column / 1000000 AS timestamp) example_date
FROM example_table
Simple and easy solution which won't require any added library or function to be imported
DATEADD(second,YourValue, CAST('1970-01-01 00:00:00' AS datetime))
Did you try FROM_UNIXTIME?
select from_unixtime('your_field') from 'your_table'
https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_from-unixtime
Works for me.
Related
In an extract I am dealing with, I have 2 datetime columns. One column stores the dates and another the times as shown.
How can I query the table to combine these two fields into 1 column of type datetime?
Dates
2009-03-12 00:00:00.000
2009-03-26 00:00:00.000
2009-03-26 00:00:00.000
Times
1899-12-30 12:30:00.000
1899-12-30 10:00:00.000
1899-12-30 10:00:00.000
You can simply add the two.
if the Time part of your Date column is always zero
and the Date part of your Time column is also always zero (base date: January 1, 1900)
Adding them returns the correct result.
SELECT Combined = MyDate + MyTime FROM MyTable
Rationale (kudos to ErikE/dnolan)
It works like this due to the way the date is stored as two 4-byte
Integers with the left 4-bytes being the date and the right
4-bytes being the time. Its like doing $0001 0000 + $0000 0001 =
$0001 0001
Edit regarding new SQL Server 2008 types
Date and Time are types introduced in SQL Server 2008. If you insist on adding, you can use Combined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)
Edit2 regarding loss of precision in SQL Server 2008 and up (kudos to Martin Smith)
Have a look at How to combine date and time to datetime2 in SQL Server? to prevent loss of precision using SQL Server 2008 and up.
If the time element of your date column and the date element of your time column are both zero then Lieven's answer is what you need. If you can't guarantee that will always be the case then it becomes slightly more complicated:
SELECT DATEADD(day, 0, DATEDIFF(day, 0, your_date_column)) +
DATEADD(day, 0 - DATEDIFF(day, 0, your_time_column), your_time_column)
FROM your_table
This is an alternative solution without any char conversions:
DATEADD(ms, DATEDIFF(ms, '00:00:00', [Time]), CONVERT(DATETIME, [Date]))
You will only get milliseconds accuracy this way, but that would normally be OK. I have tested this in SQL Server 2008.
This worked for me
CAST(Tbl.date as DATETIME) + CAST(Tbl.TimeFrom AS TIME)
(on SQL 2008 R2)
If you're not using SQL Server 2008 (i.e. you only have a DateTime data type), you can use the following (admittedly rough and ready) TSQL to achieve what you want:
DECLARE #DateOnly AS datetime
DECLARE #TimeOnly AS datetime
SET #DateOnly = '07 aug 2009 00:00:00'
SET #TimeOnly = '01 jan 1899 10:11:23'
-- Gives Date Only.
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, #DateOnly))
-- Gives Time Only.
SELECT DATEADD(Day, -DATEDIFF(Day, 0, #TimeOnly), #TimeOnly)
-- Concatenates Date and Time parts.
SELECT
CAST(
DATEADD(dd, 0, DATEDIFF(dd, 0, #DateOnly)) + ' ' +
DATEADD(Day, -DATEDIFF(Day, 0, #TimeOnly), #TimeOnly)
as datetime)
It's rough and ready, but it works!
If both of your fields are datetime then simply adding those will work.
eg:
Declare #d datetime, #t datetime
set #d = '2009-03-12 00:00:00.000';
set #t = '1899-12-30 12:30:00.000';
select #d + #t
If you used Date & Time datatype then just cast the time to datetime
eg:
Declare #d date, #t time
set #d = '2009-03-12';
set #t = '12:30:00.000';
select #d + cast(#t as datetime)
This was my solution which ignores the date value of the time column
CAST(Tbl.date as DATETIME) + CAST(CAST(Tbl.TimeFrom AS TIME) as DATETIME)
Hope this helps others
Convert the first date stored in a datetime field to a string, then convert the time stored in a datetime field to string, append the two and convert back to a datetime field all using known conversion formats.
Convert(datetime, Convert(char(10), MYDATETIMEFIELD, 103) + ' ' + Convert(char(8), MYTIMEFIELD, 108), 103)
Convert both field into DATETIME :
SELECT CAST(#DateField as DATETIME) + CAST(#TimeField AS DATETIME)
and if you're using Getdate() use this first:
DECLARE #FechaActual DATETIME = CONVERT(DATE, GETDATE());
SELECT CAST(#FechaActual as DATETIME) + CAST(#HoraInicioTurno AS DATETIME)
I had many errors as stated above so I did it like this
try_parse(concat(convert(date,Arrival_date),' ',arrival_time) as datetime) AS ArrivalDateTime
It worked for me.
Finding this works for two dates where you want time from one and date from the other:
declare #Time as datetime = '2021-11-19 12:34'
declare #Date as datetime = '2021-10-10'
SELECT #time + datediff(day, #Time, #Date)
DECLARE #Dates table ([Date] datetime);
DECLARE #Times table ([Time] datetime);
INSERT INTO #Dates VALUES('2009-03-12 00:00:00.000');
INSERT INTO #Dates VALUES('2009-03-26 00:00:00.000');
INSERT INTO #Dates VALUES('2009-03-30 00:00:00.000');
INSERT INTO #Times VALUES('1899-12-30 12:30:00.000');
INSERT INTO #Times VALUES('1899-12-30 10:00:00.000');
INSERT INTO #Times VALUES('1899-12-30 10:00:00.000');
WITH Dates (ID, [Date])
AS (
SELECT ROW_NUMBER() OVER (ORDER BY [Date]), [Date] FROM #Dates
), Times (ID, [Time])
AS (
SELECT ROW_NUMBER() OVER (ORDER BY [Time]), [Time] FROM #Times
)
SELECT Dates.[Date] + Times.[Time] FROM Dates
JOIN Times ON Times.ID = Dates.ID
Prints:
2009-03-12 10:00:00.000
2009-03-26 10:00:00.000
2009-03-30 12:30:00.000
To combine date from a datetime column and time from another datetime column this is the best fastest solution for you:
select cast(cast(DateColumn as date) as datetime) + cast(TimeColumn as datetime) from YourTable
SELECT CAST(CAST(#DateField As Date) As DateTime) + CAST(CAST(#TimeField As Time) As DateTime)
Another way is to use CONCATand CAST, be aware, that you need to use DATETIME2(x) to make it work. You can set x to anything between 0-7 7 meaning no precision loss.
DECLARE #date date = '2018-03-12'
DECLARE #time time = '07:00:00.0000000'
SELECT CAST(CONCAT(#date, ' ', #time) AS DATETIME2(7))
Returns 2018-03-12 07:00:00.0000000
Tested on SQL Server 14
simply concatenate both , but cast them first as below
select cast(concat(Cast(DateField as varchar), ' ', Cast(TimeField as varchar)) as datetime) as DateWithTime from TableName;
select s.SalesID from SalesTbl s
where cast(cast(s.SaleDate as date) as datetime) + cast(cast(s.SaleCreatedDate as time) as datetime) between #FromDate and #ToDate
The existing answers do not address the datetime2 datatype so I will add mine:
Assuming that you want to add a time value to a datetime2 value where:
The datetime2 value could contain non-zero time component and/or fractional seconds
The time value could contain the value 23:59:59.9999999 which is 86,399.9999999 seconds, 86,399,999,999.9 microseconds or 86,399,999,999,900 nanoseconds¹
Due to the limitations of dateadd function¹ you must add them in two steps:
Convert the time value to seconds and use dateadd(second, ...)
Extract the nanoseconds from the time value and use dateadd(nanosecond, ...) to add them to the date calculated above
declare #dv datetime2 = '2000-01-01 12:34:56.7890123';
declare #tv time = '23:59:59.9999999';
select dateadd(
nanosecond,
datepart(nanosecond, #tv),
dateadd(
second,
datepart(hour, #tv) * 60 * 60 + datepart(minute, #tv) * 60 + datepart(second, #tv),
#dv
)
);
-- 2000-01-02 12:34:56.7890122
¹ Nanosecond values might not fit in int datatype which dateadd function expects.
SELECT CAST(your_date_column AS date) + CAST(your_time_column AS datetime) FROM your_table
Works like a charm
I ran into similar situation where I had to merge Date and Time fields to DateTime field. None of the above mentioned solution work, specially adding two fields as the data type for addition of these 2 fields is not same.
I created below solution, where I added hour and then minute part to the date. This worked beautifully for me. Please check it out and do let me know if you get into any issues.
;with tbl
as
(
select StatusTime = '12/30/1899 5:17:00 PM', StatusDate = '7/24/2019 12:00:00 AM'
)
select DATEADD(MI, DATEPART(MINUTE,CAST(tbl.StatusTime AS TIME)),DATEADD(HH, DATEPART(HOUR,CAST(tbl.StatusTime AS TIME)), CAST(tbl.StatusDate as DATETIME)))
from tbl
Result: 2019-07-24 17:17:00.000
I am trying to convert milliseconds to date in SQL Server for a date after 01/01/2040.
I tried this, but I'm getting an error:
Arithmetic overflow error
Code:
CREATE TABLE XYZ
(
[ExpirationDate] float
);
INSERT INTO XYZ ([ExpirationDate])
VALUES
(1301598290687),
(2240542800000),--> this is 01/01/2040
(2144034000000);
SELECT
DATEADD(MILLISECOND,
CAST(ExpirationDate AS bigint) % 1000,
DATEADD(SECOND, CAST(ExpirationDate AS bigint) / 1000, '19700101'))
FROM
XYZ
Also tried
SELECT CAST(ExpirationDate AS DATETIME) FROM XYZ
but that's not working either.
See this https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=4c03a31832364b5a636f47eb66034c19
Looking for Date output like if we pass 2240542800000 ms as value then output should be date 01/01/2040
One method is to split the problem into date and time pieces:
select (DATEADD(DAY,
FLOOR(ExpirationDate / (24*60*60*1000.0) ),
'19700101') +
DATEADD(MILLISECOND, CONVERT(bigint, ExpirationDate) % (24*60*60*1000), 0)
)
from XYZ
select dateadd(ms, CAST (3471725580 AS BIGINT), '1970-01-01 00:00:00.0');
You can separate that really big number of milliseconds intoto seconds and milliseconds to prevent the arithmetic overflow error. Try the below code and see the results:
SELECT DATEADD(MILLISECOND, 3471725580 % 1000, DATEADD(SECOND, 3471725580 / 1000, '19700101'))
This is result when I run the above code in MS SQL Server:
Use bigger date time part:
select dateadd(SECOND, CAST (3471725580/1000 AS BIGINT), '1970-01-01 00:00:00.0')
3471725580 is bigger than bigint then you have the error.
You can easily use SECOND instead of ms and then decrease the 3471725580 to 3471726
(you may loose some accuracy)
Making it as safe as possible:
declare #ms BIGINT = 3471725580;
-- ms per a week
declare #msw INT = 1000 * 60 * 60 * 24 * 7;
select dateadd(ms, #ms % #msw, dateadd(week, #ms / #msw, '1970-01-01 00:00:00.0'));
I have a column "Time" with Time as its Datatype.
I need to get 25% of the value in that column.
Please help. I've been banging my head on the wall for the solution.
You need to convert TIME to float value. According to Data type conversion table you can do it through DATETIME, so:
DECLARE #d time = '03:00:00';
SELECT CONVERT(float, CONVERT(datetime, #d)) * 0.25 -- this will be 25% of the value in float
And then do reverse conversion:
DECLARE #f float = 0.03125; -- this is result of previous select.
SELECT CONVERT(time, CONVERT(datetime, #f)) -- Result = 00:45:00
So, in your query it will be:
SELECT ResultTime = CONVERT(time, CONVERT(datetime, (CONVERT(float, CONVERT(datetime, TimeColumn)) * 0.25)))
FROM Table
See DEMO
declare #time NUMERIC
set #TIME=(select cast(replace(replace(cast(cast(getdate() as time) as varchar),':',''),'.','') as NUMERIC)*.25)
IF LEN(#TIME)=12 BEGIN
SELECT '0'+SUBSTRING(CAST(#TIME AS VARCHAR(20)),0,2)+':'+SUBSTRING(CAST(#TIME AS VARCHAR(20)),3,2)+':'+SUBSTRING(CAST(#TIME AS VARCHAR(20)),5,2)+'.'+SUBSTRING(CAST(#TIME AS VARCHAR(20)),7,13)
END
ELSE
SELECT SUBSTRING(CAST(#TIME AS VARCHAR(20)),0,2)+':'+SUBSTRING(CAST(#TIME AS VARCHAR(20)),3,2)+':'+SUBSTRING(CAST(#TIME AS VARCHAR(20)),5,2)+'.'+SUBSTRING(CAST(#TIME AS VARCHAR(20)),7,13)
Not sure it's the best answer you can get, but i did it in one query :
SELECT CONVERT(TIME,
CONVERT(DATETIME,
CONVERT(FLOAT,
CONVERT(DATETIME, field )) / 4))
Here's a fiddle : http://sqlfiddle.com/#!3/01b3f/7
This worked for me:
select convert(varchar, dateadd(s, datediff(s, '00:00:00' , t) * .25, '00:00:00'), 8)
SQLFiddle
Convert from the date to Float
DECLARE #d time =getdate()
print #d
SELECT CONVERT(float , CONVERT(datetime, #d)) * 0.25
In an extract I am dealing with, I have 2 datetime columns. One column stores the dates and another the times as shown.
How can I query the table to combine these two fields into 1 column of type datetime?
Dates
2009-03-12 00:00:00.000
2009-03-26 00:00:00.000
2009-03-26 00:00:00.000
Times
1899-12-30 12:30:00.000
1899-12-30 10:00:00.000
1899-12-30 10:00:00.000
You can simply add the two.
if the Time part of your Date column is always zero
and the Date part of your Time column is also always zero (base date: January 1, 1900)
Adding them returns the correct result.
SELECT Combined = MyDate + MyTime FROM MyTable
Rationale (kudos to ErikE/dnolan)
It works like this due to the way the date is stored as two 4-byte
Integers with the left 4-bytes being the date and the right
4-bytes being the time. Its like doing $0001 0000 + $0000 0001 =
$0001 0001
Edit regarding new SQL Server 2008 types
Date and Time are types introduced in SQL Server 2008. If you insist on adding, you can use Combined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)
Edit2 regarding loss of precision in SQL Server 2008 and up (kudos to Martin Smith)
Have a look at How to combine date and time to datetime2 in SQL Server? to prevent loss of precision using SQL Server 2008 and up.
If the time element of your date column and the date element of your time column are both zero then Lieven's answer is what you need. If you can't guarantee that will always be the case then it becomes slightly more complicated:
SELECT DATEADD(day, 0, DATEDIFF(day, 0, your_date_column)) +
DATEADD(day, 0 - DATEDIFF(day, 0, your_time_column), your_time_column)
FROM your_table
This is an alternative solution without any char conversions:
DATEADD(ms, DATEDIFF(ms, '00:00:00', [Time]), CONVERT(DATETIME, [Date]))
You will only get milliseconds accuracy this way, but that would normally be OK. I have tested this in SQL Server 2008.
This worked for me
CAST(Tbl.date as DATETIME) + CAST(Tbl.TimeFrom AS TIME)
(on SQL 2008 R2)
If you're not using SQL Server 2008 (i.e. you only have a DateTime data type), you can use the following (admittedly rough and ready) TSQL to achieve what you want:
DECLARE #DateOnly AS datetime
DECLARE #TimeOnly AS datetime
SET #DateOnly = '07 aug 2009 00:00:00'
SET #TimeOnly = '01 jan 1899 10:11:23'
-- Gives Date Only.
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, #DateOnly))
-- Gives Time Only.
SELECT DATEADD(Day, -DATEDIFF(Day, 0, #TimeOnly), #TimeOnly)
-- Concatenates Date and Time parts.
SELECT
CAST(
DATEADD(dd, 0, DATEDIFF(dd, 0, #DateOnly)) + ' ' +
DATEADD(Day, -DATEDIFF(Day, 0, #TimeOnly), #TimeOnly)
as datetime)
It's rough and ready, but it works!
If both of your fields are datetime then simply adding those will work.
eg:
Declare #d datetime, #t datetime
set #d = '2009-03-12 00:00:00.000';
set #t = '1899-12-30 12:30:00.000';
select #d + #t
If you used Date & Time datatype then just cast the time to datetime
eg:
Declare #d date, #t time
set #d = '2009-03-12';
set #t = '12:30:00.000';
select #d + cast(#t as datetime)
This was my solution which ignores the date value of the time column
CAST(Tbl.date as DATETIME) + CAST(CAST(Tbl.TimeFrom AS TIME) as DATETIME)
Hope this helps others
Convert the first date stored in a datetime field to a string, then convert the time stored in a datetime field to string, append the two and convert back to a datetime field all using known conversion formats.
Convert(datetime, Convert(char(10), MYDATETIMEFIELD, 103) + ' ' + Convert(char(8), MYTIMEFIELD, 108), 103)
Convert both field into DATETIME :
SELECT CAST(#DateField as DATETIME) + CAST(#TimeField AS DATETIME)
and if you're using Getdate() use this first:
DECLARE #FechaActual DATETIME = CONVERT(DATE, GETDATE());
SELECT CAST(#FechaActual as DATETIME) + CAST(#HoraInicioTurno AS DATETIME)
I had many errors as stated above so I did it like this
try_parse(concat(convert(date,Arrival_date),' ',arrival_time) as datetime) AS ArrivalDateTime
It worked for me.
Finding this works for two dates where you want time from one and date from the other:
declare #Time as datetime = '2021-11-19 12:34'
declare #Date as datetime = '2021-10-10'
SELECT #time + datediff(day, #Time, #Date)
DECLARE #Dates table ([Date] datetime);
DECLARE #Times table ([Time] datetime);
INSERT INTO #Dates VALUES('2009-03-12 00:00:00.000');
INSERT INTO #Dates VALUES('2009-03-26 00:00:00.000');
INSERT INTO #Dates VALUES('2009-03-30 00:00:00.000');
INSERT INTO #Times VALUES('1899-12-30 12:30:00.000');
INSERT INTO #Times VALUES('1899-12-30 10:00:00.000');
INSERT INTO #Times VALUES('1899-12-30 10:00:00.000');
WITH Dates (ID, [Date])
AS (
SELECT ROW_NUMBER() OVER (ORDER BY [Date]), [Date] FROM #Dates
), Times (ID, [Time])
AS (
SELECT ROW_NUMBER() OVER (ORDER BY [Time]), [Time] FROM #Times
)
SELECT Dates.[Date] + Times.[Time] FROM Dates
JOIN Times ON Times.ID = Dates.ID
Prints:
2009-03-12 10:00:00.000
2009-03-26 10:00:00.000
2009-03-30 12:30:00.000
To combine date from a datetime column and time from another datetime column this is the best fastest solution for you:
select cast(cast(DateColumn as date) as datetime) + cast(TimeColumn as datetime) from YourTable
SELECT CAST(CAST(#DateField As Date) As DateTime) + CAST(CAST(#TimeField As Time) As DateTime)
Another way is to use CONCATand CAST, be aware, that you need to use DATETIME2(x) to make it work. You can set x to anything between 0-7 7 meaning no precision loss.
DECLARE #date date = '2018-03-12'
DECLARE #time time = '07:00:00.0000000'
SELECT CAST(CONCAT(#date, ' ', #time) AS DATETIME2(7))
Returns 2018-03-12 07:00:00.0000000
Tested on SQL Server 14
simply concatenate both , but cast them first as below
select cast(concat(Cast(DateField as varchar), ' ', Cast(TimeField as varchar)) as datetime) as DateWithTime from TableName;
select s.SalesID from SalesTbl s
where cast(cast(s.SaleDate as date) as datetime) + cast(cast(s.SaleCreatedDate as time) as datetime) between #FromDate and #ToDate
The existing answers do not address the datetime2 datatype so I will add mine:
Assuming that you want to add a time value to a datetime2 value where:
The datetime2 value could contain non-zero time component and/or fractional seconds
The time value could contain the value 23:59:59.9999999 which is 86,399.9999999 seconds, 86,399,999,999.9 microseconds or 86,399,999,999,900 nanoseconds¹
Due to the limitations of dateadd function¹ you must add them in two steps:
Convert the time value to seconds and use dateadd(second, ...)
Extract the nanoseconds from the time value and use dateadd(nanosecond, ...) to add them to the date calculated above
declare #dv datetime2 = '2000-01-01 12:34:56.7890123';
declare #tv time = '23:59:59.9999999';
select dateadd(
nanosecond,
datepart(nanosecond, #tv),
dateadd(
second,
datepart(hour, #tv) * 60 * 60 + datepart(minute, #tv) * 60 + datepart(second, #tv),
#dv
)
);
-- 2000-01-02 12:34:56.7890122
¹ Nanosecond values might not fit in int datatype which dateadd function expects.
SELECT CAST(your_date_column AS date) + CAST(your_time_column AS datetime) FROM your_table
Works like a charm
I ran into similar situation where I had to merge Date and Time fields to DateTime field. None of the above mentioned solution work, specially adding two fields as the data type for addition of these 2 fields is not same.
I created below solution, where I added hour and then minute part to the date. This worked beautifully for me. Please check it out and do let me know if you get into any issues.
;with tbl
as
(
select StatusTime = '12/30/1899 5:17:00 PM', StatusDate = '7/24/2019 12:00:00 AM'
)
select DATEADD(MI, DATEPART(MINUTE,CAST(tbl.StatusTime AS TIME)),DATEADD(HH, DATEPART(HOUR,CAST(tbl.StatusTime AS TIME)), CAST(tbl.StatusDate as DATETIME)))
from tbl
Result: 2019-07-24 17:17:00.000