Difference between datetime converts in MSExcel and SQL Server
hehe ;) one day ages ago I wondered the same thing... do a simple exercise:
compare Select Cast(0 as DateTime)
vs. =DATEVALUE("1900-01-01")
which explains 1 day difference
and find the one extra leap year by reading the father of VBA, Joel Spolsky, explanation
tl;dr
check out the difference - which exlpains the 2nd day
=DateValue("1900-02-28")
and =DateValue("1900-03-01")
SQL Server and excel date to number conversion give difference
I think there are 2 reasons.
The first date with a serial number in Excel is 1900-01-01. This has a serial number of 1. https://support.office.com/en-gb/article/DATEVALUE-function-df8b07d4-7761-4a93-bc33-b7471bbff252
In SQL this date has a numeric number of 0 not 1. So that accounts for a difference of 1.
The second unit is a bit odd. In Excel the date 1900-02-29 has a serial number even though that date didn't exist (29th Feb exists every 4 years except at the turn of a century). In SQL 1900-02-29 doesn't exist (try doing this SELECT CONVERT(int, CONVERT(datetime, '19000229'))
). So that accounts for the second unit difference.
integer to date conversion issue in SQL vs Excel
SQL Server uses a different date format.
I believe the correct conversion is:
select dateadd(day, 43251, '1899-12-30')
This is confusing. Excel treats 0
as 1900-00-00
, which means that 0 is 1899-12-31 and 1 is 1900-01-01. That should suggest that the conversion is:
select dateadd(day, 43251, '1899-12-31')
However, that does not produce the correct date. Why not? Excel has incorrect leap year arithmetic. So, it treats day 60 as 1900-02-29. However, 1900 is not a leap year, so "60" should be 1900-03-01.
The rules for leap years are:
- Years that are divisible by 4
- Except years that are divisible by 100
- Except years that are divisible by 400
So, 2000 was a leap year, but 1900 and 2100 are not.
In other words, the dates are correct only for dates after 1900-03-01.
Variance in Dates in SQL Server, Excel and MS Access
It's because they use different origin dates to define a datetime.
If you want to cast a datetime field to an integer, always choose your own origin date.
For example, when you want to use 1970-01-01 as a reference date, use:
SELECT DATEDIFF(d, '1970-01-01', '2021-01-01');
And if you want to cast it back to a date:
SELECT DATEADD(d, 18628, '1970-01-01')
Never rely on implementation details like the default origin date.
Note that you can easily get the origin date by using SELECT CAST(0 AS DATETIME)
for SQL server (1900-01-01) or SELECT FORMAT(CDATE(0), "Short Date")
in Access (1899-12-30), which reveals the 2-day difference.
How to convert datetime (SQL Server) into Excel datetime?
You could use CAST
:
select CAST(GETDATE() as float)+2
How Dates work in Excel:
https://www.excelcampus.com/functions/how-dates-work-in-excel/
Basically any date can be stored as number of days since 1/1/1900. And the time is fractional value which is equal to (number_of_seconds_since_midnight)*(1/(24*60*60))
Need to add 2 days as Excel and SQL count number of days from a different start date.
Hope this all makes sense.
CONVERT vs CAST when exporting datetime as dates from sql server
To answer your questions sequentially:
126 uses the ISO 8601 date standard, which signifies the Year aspect to be the full 4 characters long, rather than just the last two. 127 uses the same date standard, but in Time Zone Zulu, which is a military time zone (4 hours ahead of EST)
There essentially is no difference when copy/pasting to Excel. When opening an Excel doc, the default cell formatting is "General". When you paste any of these date types into Excel, it will register option A as a number (in this case 41270) and based on the pre-existing format from your query will convert it to Date format. Options B and C will first register as text, but since they are in the format of a Date (i.e. they have the "/" marks), Excel can register these as dates as well and change the formatting accordingly.
As long as the person you are sharing your script with uses T-SQL this shouldn't cause problems. MySQL or other variations could start to cause issues.
CAST(createdat as date)
is the best option (IMO)
Sources:
SQL Conversion Types
ISO 8601 Details
Zulu Time Zone
Excel 5 digit Datetime converted in SQL is 2 days ahead
Excel dates are tricky. What they do is count the number of days since Dec 30th, 1899 (and early years are not entirely accurate).
One option is:
dateadd(d, 28540, '1899-12-30')
Demo on DB Fiddle:
select dateadd(d, 28540, '1899-12-30') new_dt
| new_dt |
| :---------------------- |
| 1978-02-19 00:00:00.000 |
convert Excel Date Serial Number to Regular Date
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
Sql server and Excel float to date offset
SQL server simply calculates the conversion of a date time to a float as the number of days since midnight on 01-Jan-1900 (i.e. select convert(DATETIME, 0)
gives 1900-01-01 00:00:00.000
)
Excel calculates a similar number, but the zero date is "00/01/1900". This is probably related to the fact that excel uses one based indexing, rather than the more common zero based indexing. The second day of difference comes from a well known bug whereby excel considers 1900 to have been a leap year.
Takeaway message: if you assume that excel is always behind by two days you'll be ok, except for dates on or before the 28th of February 1900.
Related Topics
How to Find Specific Value to Specific String Location in Different Strings
Duplicate Column Name Error While Creating View
Fetch Table Name from a Column for from Clause
Handling Non Existent Values in SQL Query Expression for Ssrs Chart
Select Non-Empty Columns Using SQL Server
Using Tuples to Put More Than 1000 Entries in SQL in Clause
Get All Punch in and Out for Each Employee
Tips and Tricks to Speed Up an SQL
Is There a Function That Takes a Year, Month and Day to Create a Date in Postgresql
Find Out the Calling Stored Procedure in SQL Server
Filter Based on an Aliased Column Name
Can SQL Server Pivot Without Knowing the Resulting Column Names
How to Create a Check Constraint on a Varchar Column in SQL Server Specifying a Minimum Data Length
Performance of Inner Join VS Cartesian Product
SQL Server 2008 Password Ending in a Semicolon
How to Declare Input-Output Parameters in SQL Server Stored Procedure/Function