SSMS 2012: Convert DATETIME to Excel serial number - sql

I can't seem to find an answer to this anywhere --- I want to convert a datetime in SQL to the excel serial number.
I'm essentially looking for the DATEVALUE function from excel but for use in SQL
Any ideas on how to do this? thanks

Assuming the desired date is 2016-05-25
Select DateDiff(DD,'1899-12-30','2016-05-25')
Returns
42515
If you want the time portion as well
Declare #Date datetime = '2016-05-25 20:00'
Select DateDiff(DD,'1899-12-30',#Date)+(DateDiff(SS,cast(#Date as Date),#Date)/86400.0)
Returns
42515.8333333

I ran into this issue and found the most elegant solution to be the following (as others have mentioned, adding the +2 is essential due to the differences between SQL and Excel dates):
Assuming the "Column" is a DateTimeOffset:
SELECT CAST(CAST(COLUMN_TO_BE_CONVERTED as datetime)+2 as float) as EXCEL_DATE_FLOAT
If the column is not already a DateTimeOffset and is just a DateTime, you would not need the double cast; you'd just need something like:
SELECT CAST(COLUMN_TO_BE_CONVERTED+2 as float) as EXCEL_DATE_FLOAT
The resultant float value in either case is what excel recognizes as the date and time and you can easily extract what you need from there. Upon manually verifying the results in excel, I confirmed that the serial numbers matched the date and time exactly as I expected.

You just need to convert your datetime value to int and add 1:
SELECT CONVERT(INT,YourDate) + 1
FROM dbo.SomeTable;

With collation: SQL_Latin1_General_CP1_CI_AS
you should use
Select DateDiff(DD,'18991230','20160525')
Returns
42515
You could replace '20160525' for getdate() or you date field

Related

T-SQL Dates using Convert() function?

I am bit confusing here?
declare #date1 datetime = '2016-01-21 14:10:47.183'
I want to convert '2016-01-21 14:10:47.183' To '21-01-2016'
when I tried: select convert(date,#date1,105)
I am getting: 2016-01-21
But with: select convert(varchar(10),#date1,105)
I am getting: 21-01-2016
Why I am not having same results with above code?
Why should I convert to varchar?
Thanks in advance
This is just presentation matter and should be done in application layer. If you cannot do it in application you could use FORMAT (SQL Server 2012+):
declare #date1 datetime = '2016-01-21 14:10:47.183'
SELECT FORMAT(#date1, 'dd-mm-yyyy');
LiveDemo
Why I am not having same results with above code?
select convert(date,#date1,105)
-- DATETIME -> DATE
-- vs
select convert(varchar(10),#date1,105)
-- DATETIME -> VARCHAR(10) using specific style
If you only to skip time part use SELECT CAST(#date1 AS DATE) and do not bother how it is presented. It is still DATE.
To sum up: in SQL query use DATE as date, in application display it with desired format.
The reason why is because once you put a value in a datetime column (or date or any of the other variations on date-time datatypes) in SQL Server. SQL Server ceases to think of that date as having any particular format. It translates it into numbers, and stores it that way internally.
So when you select a date from a date time column, SQL Server displays it in the default format that you have selected based on your environment/local settings.
If you want to display it in any other format, you have to first convert it to a string, because as far as SQL Server is concerned, dates don't have formats. They are just numbers. The 21st day of March is the 21st day of March, whether you write it as 3/21 or 21/3.
So when you try to convert a date to a date with a different format, SQL Server just ignores you because dates don't have formats. However, if you want to convert that date to a string, SQL Server will be happy to help you display that string in any format you like.
Hope this helps, but sounds like some further research into how SQL Server stores dates would help your understanding.

SQL Finding the date difference when two formats are different

I have a date stored in format like
18/1/2012 18:51:35
I have to find the difference in days between one date and current date. To get current date i am using getdate() which returns the below
2015-10-30 10:01:25.493
Currently i am using charindex and substring function to make to formats equal in datediff(). Is there a better way
I think this has been answered here:
Converting a date in MySQL from string field
where (i think) you basically would just, (haven't tested :/)
datediff(STR_TO_DATE(your_column_to_convert, '%d/%m/%Y %H:%M:%S'), CURRENT_DATE())
Assuming you using SQL Server, as the GETDATE() and CHARINDEX() are specific to MSSQL.
If the date 18/1/2012 18:51:35 is stored in VARCHAR, you could probably use
DECLARE #DateFromTable VARCHAR(20)
SET #DateFromTable = '18/1/2012 18:51:35'
SELECT DATEDIFF(DAY, CONVERT(DATETIME,#DateFromTable, 103), GETDATE());
Refer to Cast and Convert functions here.
Below is the MSSQL code which you are looking for.
DECLARE #column_date VARCHAR(50)
SET #column_date = '18/1/2012 18:51:35'
SELECT DATEDIFF(DAY,CAST(CONVERT(DATETIME,#column_date,103) AS DATETIME),GETDATE())
Try replacing your column with #column_date.
Hope it will help you.

Convert TEXT to Date in SQL Server 2012

I have a TEXT in this format 31/10/15.
How do I convert this into a DATE format?
As I need to let the user search from data using a date range.
example: From 15/7/13 to 31/10/15
Or is there a way to so without converting to date?
You can use CONVERT() for this:
DECLARE #d VARCHAR(50) = '31/10/50'
SELECT CONVERT(DATE, #d,3)
Note that with a 2-digit year SQL Server will make the year start with '19' for 50 and up, and 49 and below will be '20'
Storing as a DATE field will allow easier comparisons, otherwise you'll have to perform this conversion at each step.
Use CONVERT; example:
SELECT [Date] = CONVERT(date, '31/10/15', 3);
And yes, it's possible to search dates in the same format as the examples you provide, but don't do that – use the proper data types in both your queries and your table columns.

Strange behaviour of Sql query with between operator

There is this strange error in sql query.
The query is something like this.
select * from student where dob between '20150820' and '20150828'
But in the database the column of dob is varchar(14) and is in yyyyMMddhhmmss format,Say my data in the row is (20150827142545).If i fire the above query it should not retrive any rows as i have mentioned yyyyMMdd format in the query.But it retrives the row with yesterday date (i.e 20150827112535) and it cannot get the records with today's date (i.e 20150828144532)
Why is this happening??
Thanks for the help in advance
You can try like this:
select * from student
where convert(date,LEFT(dob,8)) between
convert(date'20150820') and convert(date,'20150828'))
Also as others have commented you need to store your date as Date instead of varchar to avoid such problems in future.
As already mentioned you would need to use the correct date type to have between behave properly.
select *
from student
where convert(date,LEFT(dob,8)) between '20150820' and '20150828'
Sidenote: You don't have to explicitly convert your two dates from text as this will be done implicitly as long as you use an unambiguous date representation, i.e. the ISO standard 'YYYYMMDD' or 'YYYY-MM-DD'. Of course if you're holding the values in variables then use date | datetime datatype
declare #startdate date
declare #enddate date
select *
from student
where convert(date,LEFT(dob,8)) between #startdate and #enddate
Sidenote 2: Performing the functions on your table dob column would prevent any indexes on that column from being used to their full potential in your execution plan and may result in slower execution, if you can, define the correct data type for the table dob column or use a persistent computed column or materialised view if your performance is a real issue.
Sidenote 3: If you need to maintain the time portion in your data i.e. date and time of birth, use the following to ensure all records are captured;
select *
from student
where
convert(date,LEFT(dob,8)) >= '20150820'
and convert(date,LEFT(dob,8)) < dateadd(d,1,'20150828')
All you have to do is to convert first the string to date.
select *
from student
where dob between convert(date, '20150820') and convert(date, '20150828')
Why is this happening?
The comparison is executed from left to right and the order of characters is determined by the codepage in use.
Sort Order
Sort order specifies the way that data values are sorted, affecting
the results of data comparison. The sorting of data is accomplished
through collations, and it can be optimized using indexes.
https://msdn.microsoft.com/en-us/library/ms143726.aspx
There are problems with between in T-SQL.
But if you want a fast answer convert to date first and use >= <= or even datediff to compare - maybe write a between function yourself if you want the easy use like between and no care about begin and start times ...
What do BETWEEN and the devil have in common?

How do I strip the date off of a datetime string in SQL SSIS?

I'm working on a data warehouse project and would like to know how to (preferably in a Derived Column component in a Data flow) strip the date piece off of a SQL datetime record.
Once I have the datetime converted to just a time I am going to do a lookup on the time to find the related time record in a time dimension table.
Can someone give me a simple function to accomplish this inside a derived column transform?
Example: Transform a datetime such as "12/02/2008 11:32:21 AM" into simply "11:32:21 AM".
I would just do a cast to DT_DBTIME type (using Derived Column transform, or Convert type transform). DT_DBTIME contains just (hours, minutes, seconds) part of the date/time, so you'll get rid of the date part.
If you need to do this in a variable expression Michael's solution won't work, but you can use the following expression:
(DT_DATE)(DT_DBDATE)GETDATE()
(DT_DBDATE) converts the current date and time to a date only. But the new datatype is not compatiple with SSIS's datetime. Therefore you'll have to use (DT_DATE) for converting to a compatible type.
Courtesy of this solution belongs to Russel Loski who has posted it in his blog:
http://www.bidn.com/blogs/RussLoski/ssas/1458/converting-datetime-to-date-in-ssis
Actually if you reverse the first 2 expressions like this: (DT_DBDATE)(DT_DATE)GETDATE()
instead of (DT_DATE)(DT_DBDATE)GETDATE(), then you will TRUNCATE the time off the date field.
If the DT_DATE expression is before the DT_DBDATE expression, you will still have the time portion in your output, but it will be reset to all zeroes.
Ran into this with writing a report for a scheduling app, needed the time that was stored as part of a datetime data type. I formated the datetime as 0 which gives you this mon dd yyyy hh:miAM (or PM), and just did a substring of that which returned the time only in an AM/PM format.
Example below.
DECLARE #S DATETIME = GETDATE()
SELECT SUBSTRING(CONVERT(NVARCHAR(30), #S , 0) , 13 , 10) AS ApptTime
, CONVERT(NVARCHAR(30), #S , 0) AS ApptDate
I personally use a series of functions for this. E.g.:
ALTER FUNCTION [dbo].[TIMEVALUE]
(
#Datetime datetime
)
RETURNS datetime
AS
BEGIN
RETURN (#Datetime - CAST(ROUND(CAST(#Datetime AS float), 0, 1) AS datetime))
END
I'd love to claim all the credit but it should really go to this guy.