Pass a column as parameter to dateadd in SQL Server - sql

I want to convert a column of UTC time to local time.
My data looks like this:
time_utc TZID timezone
------------------------------------------------
2014-02-27 12:00:39.0 America/Toronto -5
2013-05-21 09:35:30.0 America/Goose_Bay -4
2015-01-08 06:58:58.0 America/Creston -7
I know that using
select *, DATEADD(hour, 5,time_utc)
from mytable
will add 5 hours to column time_utc.
However, as you can see, I have a variable time zone column.
How can I pass this variable to the dateadd function?
I tried the following 2 commands but they don't work:
Attempt #1:
select *, DATEADD(hour, timezone, time_utc)
from mytable
Attempt #2:
select *, DATEADD(hour, (select timezone from mytable), time_utc)
from mytable
Both throws this error:
Argument data type varchar is invalid for argument 2 of dateadd function. [SQL State=S0001, DB Errorcode=8116]
For decimal values of timezone, for instance -3.5, how would this work?
Thanks

How can I pass this variable to datetime function?
Just reference the column in the function call:
select *, DATEADD(hour, timezone, time_utc)
from mytable
For decimal values of timezone, for instance -3.5, how would this work?
The "number" parameter of DATEADD takes an integer, so you'd have to change to minutes and scale the hour offset. Since your timezone colume is apparently a varchar column, convert it to a decimal value as well:
select *, DATEADD(minute, cast(timezone as decimal(4,2)) * 60 , time_utc)
from mytable

There is a character value (most probably blank) in your dataset. Sql does implicity conversion but for non numeric value it will fail. Check your table to see if you have blanks or non numeric values for timezone

Related

Explicit conversion from data type date to bigint is not allowed

This used to work with a column type of DATEIME but now it won't with DATE.
CONVERT(BIGINT,ev.StartDate) * -1
Is there anyway to get a BIGINT value from a DATE column?
You can cast the startdate as datetime for conversion.
CONVERT(BIGINT,CAST(ev.StartDate as DATETIME)) * -1
Yet another option. This will even flip the sign for you
Example
Declare #YourTable table (StartDate date)
Insert Into #YourTable values ('2017-05-30')
Select DateDiff(DAY,StartDate,-1)
From #YourTable
Returns
-42884
First, dates in SQL Server are counted by days from the year 1900. A big int starts to be useful at about 2.1 billion. That corresponds to a year in the range of 5.8 million. Do you really have dates that large?
Of course, casting to an int is not permitted. You can cast datetime values . . . but are there other ways?
One simple way is:
select 1 + datediff(day, 0, datecol)
The "+ 1" is needed so the value matches the actual conversion. (You can use "-1" instead of "0" instead.)
Or, perhaps you want Unix time in seconds or milliseconds. For that:
select datediff_big(ms, '1970-01-01', datecol)
You might require to convert to varchar and then bigint
select Convert(bigint,convert(varchar(10),ev.StartDate,112))*(-1)

SQL query not returning data

I am trying to retrieve data from a Intersystems Cached database using a where clause with a timestamp, but nothing works.
Query:
select *
from dbo.iSkillsetStat
where Timestamp >= '2014-07-29 00:00:00'
Error:
ERROR: [SQLCODE: <-4>:<A term expected, beginning with one of
the following: identifier, constant, aggregate, %ALPHAUP, %EXACT,
%MVR, %SQLSTRING, %SQLUPPER, %STRING, %UPPER, $$, :,
+, -, (, NOT, EXISTS, or FOR>]
[Location: <Prepare>]
If I run the query without the timestamp all the data is returned.
Please any suggestions!
as TIMESTAMP is a reserved word, you should enclose it in double quotes "TIMESTAP"
In similar cases this worked for me:
select * from dbo.iSkillsetStat where Timestamp >= '2014-07-29T00:00:00'
Note the 'T' between the date and time values.
Try this:
select *
from dbo.iSkillsetStat
where Timestamp >= Convert(datetime, '2014-07-29 00:00:00')
Here you are missing 000 in your datetime 2014-07-29 00:00:00.
It should be like this 2014-07-29 00:00:00:000
instead of 2014-07-29 00:00:00
the field timestamp may be a reserved keyword and shouldn't be used for columnnames (have a look at https://www.drupal.org/node/141051 #728)
HINT:
if you field is of type TIMESTAMP convert the value before you compare it:
SELECT *
FROM dbo.iSkillsetStat
WHERE columnname >= TIMESTAMP('2014-07-29 00:00:00')

Converting a numeric value to date time

I am working in SQL Server 2012. My date column in a data set looks like this: 41547. The column is in nvarchar (255). I want to convert it to something like this: yyyy-mm-dd hh:mm:ss (Example: 2013-09-14 12:23:23.98933090). But I can not do this. I am using following code:
select convert(datetime, date_column, 6)
But this is giving following error:
Msg 241, Level 16, State 1, Line 1 Conversion failed when converting
date and/or time from character string.
What am I doing wrong?
Your date is actually a numeric value (float or integer), stored in a char column. So, you need to convert it to a numerical value (in this case, to float) first, like:
select convert(datetime, CONVERT(float,date_column))
A value of 41547.5 will result in:
`2013-10-02 12:00:00`
The style argument, in your case 6 is only necessary when converting from or to char-types. In this case it is not needed and will be ignored.
NB: The float value is the number of days since 1900-01-01.
e.g. select convert(datetime, CONVERT(float,9.0)) => 1900-01-10 00:00:00; the same as select dateadd(day,9.0,'1900-01-01') would.
The decimal part of the number also equates to days; so 0.5 is half a day / 12 hours.
e.g. select convert(datetime, CONVERT(float,.5)) => 1900-01-01 12:00:00. (Here our comparison to dateadd doesn't make sense, since that only deals with integers rather than floats).
There is an easier way to do it as well.
select convert(date,cast (date_Column+ 19000000 as nvarchar(10)))
as date_Column_Formated
from table_Name
I have just found the way to do this.
First I have to covert the nvarchar to int then I have to convert it to date time. I have used following code:
Select convert(datetime, (convert (int, [date_column])), 6) as 'convertedDateTime' from mytable
6 format is: "dd mon yy"
Like this: SELECT convert(datetime, '23 OCT 16', 6)
Other formats will cause your error
SELECT CONVERT(DATETIME,CONVERT(INT,date_column))

Firebird cast integer as Time or Date

I have a table which stores an amount of seconds as integer.
I want to display it and use it as Time or Date.
If I write this:
Select Cast(ColAmountofSeconds as Time) as ThisTime From MyTable;
same with:
Select Cast(ColAmountofSeconds as Date) as ThisTime From MyTable;
I get the following error:
Overflow occurred during data type conversion. conversion error from
string "14".
Note "14" is the value of the first row in the ColAmountofSeconds column.
This is so natural in SQL Server, that I can't believe the amount of time I've spent on figuring this out.
EDIT
I can't believe this is the answer:
Update MyTable
Set TIMESPENT = time '00:00:00' + ColAmountOfSeconds;
Firebird cast function does not support converting a numeric value to date, time or timestamp.
You can take advantage of the fact that Firebird supports arithmethic between dates and numeric values, so you can write your query like this:
select dateadd(second, ColAmountOfSeconds, cast('00:00:00' as time))
from myTable;
--or the equivalent:
select cast(cast('2013-01-01' as timestamp) + cast(ColAmountofSeconds as double precision) / 86400 as TIME)
from myTable;

convert Excel Date Serial Number to Regular Date

I got a column called DateOfBirth in my csv file with Excel Date Serial Number Date
Example:
36464
37104
35412
When i formatted cells in excel these are converted as
36464 => 1/11/1999
37104 => 1/08/2001
35412 => 13/12/1996
I need to do this transformation in SSIS or in SQL. How can this be achieved?
In SQL:
select dateadd(d,36464,'1899-12-30')
-- or thanks to rcdmk
select CAST(36464 - 2 as SmallDateTime)
In SSIS, see here
http://msdn.microsoft.com/en-us/library/ms141719.aspx
The marked answer is not working fine, please change the date to "1899-12-30" instead of "1899-12-31".
select dateadd(d,36464,'1899-12-30')
You can cast it to a SQL SMALLDATETIME:
CAST(36464 - 2 as SMALLDATETIME)
MS SQL Server counts its dates from 01/01/1900 and Excel from 12/30/1899 = 2 days less.
tldr:
select cast(#Input - 2e as datetime)
Explanation:
Excel stores datetimes as a floating point number that represents elapsed time since the beginning of the 20th century, and SQL Server can readily cast between floats and datetimes in the same manner. The difference between Excel and SQL server's conversion of this number to datetimes is 2 days (as of 1900-03-01, that is). Using a literal of 2e for this difference informs SQL Server to implicitly convert other datatypes to floats for very input-friendly and simple queries:
select
cast('43861.875433912' - 2e as datetime) as ExcelToSql, -- even varchar works!
cast(cast('2020-01-31 21:00:37.490' as datetime) + 2e as float) as SqlToExcel
-- Results:
-- ExcelToSql SqlToExcel
-- 2020-01-31 21:00:37.490 43861.875433912
this actually worked for me
dateadd(mi,CONVERT(numeric(17,5),41869.166666666664)*1440,'1899-12-30')
(minus 1 more day in the date)
referring to the negative commented post
SSIS Solution
The DT_DATE data type is implemented using an 8-byte floating-point number. Days are represented by whole number increments, starting with 30 December 1899, and midnight as time zero. Hour values are expressed as the absolute value of the fractional part of the number. However, a floating point value cannot represent all real values; therefore, there are limits on the range of dates that can be presented in DT_DATE. Read more
From the description above you can see that you can convert these values implicitly when mapping them to a DT_DATE Column after converting it to a 8-byte floating-point number DT_R8.
Use a derived column transformation to convert this column to 8-byte floating-point number:
(DT_R8)[dateColumn]
Then map it to a DT_DATE column
Or cast it twice:
(DT_DATE)(DT_R8)[dateColumn]
You can check my full answer here:
Is there a better way to parse [Integer].[Integer] style dates in SSIS?
Found this topic helpful so much so created a quick SQL UDF for it.
CREATE FUNCTION dbo.ConvertExcelSerialDateToSQL
(
#serial INT
)
RETURNS DATETIME
AS
BEGIN
DECLARE #dt AS DATETIME
SELECT #dt =
CASE
WHEN #serial is not null THEN CAST(#serial - 2 AS DATETIME)
ELSE NULL
END
RETURN #dt
END
GO
I had to take this to the next level because my Excel dates also had times, so I had values like this:
42039.46406 --> 02/04/2015 11:08 AM
42002.37709 --> 12/29/2014 09:03 AM
42032.61869 --> 01/28/2015 02:50 PM
(also, to complicate it a little more, my numeric value with decimal was saved as an NVARCHAR)
The SQL I used to make this conversion is:
SELECT DATEADD(SECOND, (
CONVERT(FLOAT, t.ColumnName) -
FLOOR(CONVERT(FLOAT, t.ColumnName))
) * 86400,
DATEADD(DAY, CONVERT(FLOAT, t.ColumnName), '1899-12-30')
)
In postgresql, you can use the following syntax:
SELECT ((DATE('1899-12-30') + INTERVAL '1 day' * FLOOR(38242.7711805556)) + (INTERVAL '1 sec' * (38242.7711805556 - FLOOR(38242.7711805556)) * 3600 * 24)) as date
In this case, 38242.7711805556 represents 2004-09-12 18:30:30 in excel format
In addition of #Nick.McDermaid answer I would like to post this solution, which convert not only the day but also the hours, minutes and seconds:
SELECT DATEADD(s, (42948.123 - FLOOR(42948.123))*3600*24, dateadd(d, FLOOR(42948.123),'1899-12-30'))
For example
42948.123 to 2017-08-01 02:57:07.000
42818.7166666667 to 2017-03-24 17:12:00.000
You can do this if you just need to display the date in a view:
CAST will be faster than CONVERT if you have a large amount of data, also remember to subtract (2) from the excel date:
CAST(CAST(CAST([Column_With_Date]-2 AS INT)AS smalldatetime) AS DATE)
If you need to update the column to show a date you can either update through a join (self join if necessary) or simply try the following:
You may not need to cast the excel date as INT but since the table I was working with was a varchar I had to do that manipulation first. I also did not want the "time" element so I needed to remove that element with the final cast as "date."
UPDATE [Table_with_Date]
SET [Column_With_Excel_Date] = CAST(CAST(CAST([Column_With_Excel_Date]-2 AS INT)AS smalldatetime) AS DATE)
If you are unsure of what you would like to do with this test and re-test! Make a copy of your table if you need. You can always create a view!
Google BigQuery solution
Standard SQL
Select Date, DATETIME_ADD(DATETIME(xy, xm, xd, 0, 0, 0), INTERVAL xonlyseconds SECOND) xaxsa
from (
Select Date, EXTRACT(YEAR FROM xonlydate) xy, EXTRACT(MONTH FROM xonlydate) xm, EXTRACT(DAY FROM xonlydate) xd, xonlyseconds
From (
Select Date
, DATE_ADD(DATE '1899-12-30', INTERVAL cast(FLOOR(cast(Date as FLOAT64)) as INT64) DAY ) xonlydate
, cast(FLOOR( ( cast(Date as FLOAT64) - cast(FLOOR( cast(Date as FLOAT64)) as INT64) ) * 86400 ) as INT64) xonlyseconds
FROM (Select '43168.682974537034' Date) -- 09.03.2018 16:23:28
) xx1
)
For those looking how to do this in excel (outside of formatting to a date field) you can do this by using the Text function https://exceljet.net/excel-functions/excel-text-function
i.e.
A1 = 132134
=Text(A1,"MM-DD-YYYY") will result in a date
This worked for me because sometimes the field was a numeric to get the time portion.
Command:
dateadd(mi,CONVERT(numeric(17,5),41869.166666666664)*1440,'1899-12-31')