home

-- TSQL - Date handling, convert format for input and output
Author Nigel Rivett

A few priciples
Work with dates as datetimes. This allows date arithmetic and gets round a lot of issues.

Store dates as UTC. This avoids the issue of changes due to summer time changes.
At some point you will need to calculate the time period between two dates.
If necessary also hold the source (preferred), time zone or the offset

Use an unambiguos string format for data transfer



The simplext way to deal with string character dates is to always use one of the formats
yyyymmdd			convert(varchar(8),getdate(),112)
yyyymmdd hh:mm
yyyymmdd hh:mm:ss		convert(varchar(8),getdate(),112) + ' ' + convert(varchar(8),getdate(),108)
yyyymmdd hh:mm:ss.mmm		replace(convert(varchar(24),getdate(),121)

These will be converted to datetime implicitely.
Therefore the statements
declare @s = '20160101 09:07:20'
select convert(datetime,@s)
should always work whatever the configuration of the system

An alternative is
yyyy-mm-ddThh:mm:ss.mmmm	style 126

Date formats to avoid for data transfer (including internally) are things like:
ddmmyyyy
mmddyyyy
dd/mm/yyyy
dd-mm-yyyy
mm-dd-yyyy

These will always be ambiguous and can eventually cause problems.

Also try to avoid the following
yyyy-mm-dd
yyyy-dd-mm
This can be interpreted wronly with some configration settings

dd-mmm-yyyy
This looks good and will be interpreted correctly - until your system becomes imternational and the date received is not English.

Internally it is best to work with datetimes as these will allow date arithmetic

To convert to common string data formats (note there are many other methods)

yyyymmdd			convert(varchar(8),getdate(),112)
yyyymmdd hh:mm:ss		convert(varchar(8),getdate(),112) + ' ' + convert(varchar(8),getdate(),108)
yyyymmdd hh:mm:ss.mmm		replace(convert(varchar(24),getdate(),121)
dd/mm/yyyy			convert(varchar(10),getdate(),113)
dd/mm/yyyy hh:mm:ss		convert(varchar(10),getdate(),113) + ' ' + convert(varchar(8),getdate(),108)
dd/mm/yyyy hh:mm:ss.mmm		convert(varchar(10),getdate(),113) + ' ' + right(convert(varchar(24),getdate(),121),12)
dd-mm-yyyy			convert(varchar(10),getdate(),105)
dd mmm yyyy			convert(varchar(11),getdate(),106)
yyyy-mm-ddThh:mm:ss.mmm		convert(varchar(23),getdate(),126)
mm/dd/yyyy			convert(varchar(10),getdate(),101)
mm/dd/yyyy hh:mm:ss		convert(varchar(10),getdate(),101) + ' ' + convert(varchar(8),getdate(),108)



I only tend to remeber style 112, 108, 121, 126
I use 126 for logging reports where I need to present milliseconds and want something simple.

The convert function allows a style as the third parameter.
This is used for converting both to and from dates so
declare @d datetime = getdate()
declare @s varchar(100)
select @s = convert(varchar(10),@d,113) + ' ' + convert(varchar(8),@d,108)	-- dd/mm/yyyy hh:mm:ss
select convert(datetime,@s,113)

Date arithmetic works with dates. A date is held in two parts with the integer part being the number of days from 19000101
An expression contains a date then all items will usually be implicitely converted to a datetime
Therefore

datetime @d
Add 1 day
@d = @d + 1
@d = dateadd(dd,1,@d)
@d = @d + '19000102'

add one hour
@d = @d + '01:00:00'
@d = @d + '19000101 01:00:00'
@d = dateadd(hh,1,@d)

Convert a datetime to a date @d
@d = convert(varchar(8),getdate(),112)
	This has the advantage that it is clear what is happening but returns a string which then needs to be converted
	It is not very efficient so only use it to convert single or a few date but not on large tables
@d = dateadd(dd,datediff(dd,getdate(),0)
	This returns a date but can be confusing in a complicated expression.



home