SQL Change format of datetime to specific style - sql

I'm trying to convert a datetime value to a specific format, but noe of the style codes seem to do what I want. I tried the SQLUSA post on style codes, but none of them are quite right.
I have a column where the date/time is stored as yyyy-mm-dd hh:nn:ss (24 hour time)
I have a select statement were I want to take this column, but express the date as: mm/dd/yyyy hh:nn:ss AM/PM
The closest I've come is:
CONVERT(varchar,[datetimecolum],22) AS [newcolumnname]
but that only gives me a 2 digit year, not a century year (yyyy).
Any ideas? I'm totally lost. :(

Firstly, datetime fields are not stored in a specific string format, or but as a serial number. So what you see on screen is not what is stored but rather your database tool's default rendering of the date. Secondly why are you doing this in SQL? If you're passing the value to an application, make the conversion there from a native type. Thirdly, I don't think 22 is a valid conversion code in TSQL. Check http://msdn.microsoft.com/en-us/library/ms187928.aspx, for more info.

From: http://msdn.microsoft.com/en-us/library/ms187928.aspx
Judging by all the other formats listed, it would infer just add 100 to the format number to get "with century" (yyyy).
Although according to the documentation (and my tests) there is no format 22 (or 122) - so you'll have to combine two other formats to get exactly what you need:
CONVERT(varchar,[datetimecolum],101) + ' ' + CONVERT(varchar,[datetimecolum],108) AS [newcolumnname]
SQLFiddle demo

I think this does it
select stuff(convert(varchar(20),getdate(),22),7,2,
CAST( DATEPART(yyyy,getdate()) as CHAR(4)))
This is close but no AM PM
select convert(varchar(100),getdate(),22),
+ ' ' + CAST(DATEPART(mm,getdate()) as CHAR(2))
+ '/' + CAST( DATEPART(dd,getdate()) as CHAR(2))
+ '/' + CAST( DATEPART(yyyy,getdate()) as CHAR(4))
+ ' ' + CAST(DATEPART(HH,getdate()) as CHAR(2))
+ ':' + CAST(DATEPART(mi,getdate()) as CHAR(2))
+ ':' + CAST(DATEPART(ss,getdate()) as CHAR(2))

This is a Even clunkier than my original, but it works, except you won't get leading zeros for hours or minutes. You could modify this code to do that as well, but it will get really messy then, so I leave that to you ;-)
In other words, if the date + time is
3/1/2012 10:01:35 PM,
you will instead get:
3/1/2012 10:1:35 PM
Irritating, eh?
Anyway, here you go. Hope this helps.
SELECT dt.ID,
CASE WHEN EXISTS(SELECT DATEPART(HH, mt.TheDate)
FROM MyTable AS mt
WHERE mt.ID = dt.ID
AND (DATEPART(HH, mt.TheDate)) > 12)
THEN
(SELECT
CONVERT(varchar,(MONTH(dt.TheDate))) + '/' +
CONVERT(varchar,(DAY(dt.TheDate))) + '/' +
CONVERT(varchar,(YEAR(dt.TheDate))) + ' ' +
CONVERT(varchar, DATEPART(HH, dt.TheDate)-12) + ':' +
CONVERT(varchar,(DATEPART(mi, dt.TheDate))) + ':' +
CONVERT(varchar,(DATEPART( ss, dt.TheDate))) + ' PM')
ELSE
(SELECT
CONVERT(varchar,(MONTH(dt.TheDate))) + '/' +
CONVERT(varchar,(DAY(dt.TheDate))) + '/' +
CONVERT(varchar,(YEAR(dt.TheDate))) + ' ' +
CONVERT(varchar, DATEPART(HH, dt.TheDate)) + ':' +
CONVERT(varchar,(DATEPART(mi, dt.TheDate))) + ':' +
CONVERT(varchar,(DATEPART( ss, dt.TheDate))) + ' AM') END As FullDate
FROM MyTable AS dt

you need to do it in 2 parts and you need to use stuff to remove millisecond.I will update if find an other way to get rid of millisecond
SELECT CONVERT(VARCHAR(10), GETDATE(), 101)+' '+STUFF(RIGHT(CONVERT(VARCHAR(26), GETDATE(), 109),14),9,4,'')
output : 09/13/2012 11:15:21PM
Edit: incase you want space before AM/PM then use ' ' instead of '' in stuff
SELECT CONVERT(VARCHAR(10), GETDATE(), 101)+' '+STUFF(RIGHT(CONVERT(VARCHAR(26), GETDATE(), 109),14),9,4,' ')
output : 09/13/2012 11:15:59 PM

Related

Is there a simpler method for getting the two digit year?

EDIT: Forced to use 2008 R2
I need to get the two digit year to appended to an invoice number (for simplicity sake I am using a test variable). Previously I only needed the month and day appended but the customer is now asking for the two digit year.
My Method: REPLACE + SUBSTRING + STR + YEAR(variable DATETIME)
REPLACE((SUBSTRING(STR (Year(#Date),4),3,2)), ' ', '0')**
My code:
DECLARE #TestVariable AS VARCHAR(100),
#Date as datetime = GetDate()
SET #TestVariable = '1234'
+ REPLACE(STR(MONTH(#Date), 2), ' ', '0')
+ REPLACE(STR(DAY(#Date), 2), ' ', '0')
+ REPLACE((SUBSTRING(STR (Year(#Date),4),3,2)), ' ', '0')
PRINT #TestVariable
Honestly, just don't work with 2 digit years any more; learn the lessons of last century's mistake and use 4 digits.
If you "have" to, then you could use CONVERT with a style code, and then just replace the characters with an empty string:
DECLARE #TestVariable varchar(100) = '1234',
#Date datetime = GETDATE();
SELECT #TestVariable + REPLACE(CONVERT(varchar(8),#Date, 1),'/','');
You can simplify the whole process, not just the year portion. Using FORMAT you can accomplish this easily.
DECLARE #TestVariable AS VARCHAR(100) = '1234'
, #Date as datetime = GetDate()
Select #TestVariable + FORMAT(#Date, 'MMddyy')
select replace(convert(varchar(20),#date,1)'/','') --or any other you need
See the docs
I'll echo others' sentiment of "do you really have to use a two-digit year"? But if you have to, I like this sort of thing
set #TestVariable = '1234'
+ right('0' + cast(month(#date) as varchar(2)), 2)
+ right('0' + cast(day(#date) as varchar(2)), 2)
+ right('0' + cast(year(#date) % 100 as varchar(2)), 2);
To talk through the general approach, I'm using right('0', «something», 2) as a means to zero pad to two places, using cast(«something» as varchar(2)) to get a string instead of a number (so implicit conversion doesn't just add zero and the relevant datepart), and finally year(#date) % 100 to get the last two digits of the date.

CONVERT function does not have a proper format for the datetime I need in SQL 2008

Could you please help me format date as it is on the screenshot below:
The closest to it is 109 in the CONVERT function that I'm using, but it doesn't have slashes and space between seconds and PM + I don't need milliseconds there:
Thank you.
Actually it is super simple. You can use datename(), convert() ... to build your own (though I would do this in frontend):
DECLARE #d DATETIME = GETUTCDATE();
SELECT LEFT(DATENAME(MONTH,#d),3) + '/' +
CAST(DAY(#d) AS VARCHAR(2)) + '/' +
CAST(YEAR(#d) AS VARCHAR(4)) + ' ' +
LTRIM(RIGHT(CONVERT(VARCHAR(100),#d,22),11)) + ' (UTC)';

sql convert string to date/datetime

My Filename column looks like 'D181115.T000000'. I used the following code to make it a string, looks like '2018-11-15'.
select '20' + substring(filename, 2,2) + '-' + substring(filename, 4,2) + '-' + substring(filename,6,2)
from table_name
Then I want to convert the string to date type (because I need to sort by date)
select convert(datetime, '20 + substring(filename, 2,2) + '-' + substring(filename, 4,2) + '-' + substring(filename,6,2)')
from table_name
Then I got this error message:
The data types varchar and varchar are incompatible in the subtract
operator.
Any help will be greatly appreciated!
I suspet the database is SQL Server. In that case one can use just
select cast('20' + substring('D181115.T000000', 2,6) as date)
or
select try_cast('20' + substring('D181115.T000000', 2,6) as date)
YYYYMMDD is one of the two unambiguous date formats. The other is the full ISO8601 date+time format. YYYY-MM-DD on the other hand depends on the DATEFORMAT setting
Update
I'd suggest performing this conversion as part of data loading though. Applying functions to a field prevents the server from using any indexes that cover the field. The server will have to scan the entire table in order to produce the final values used for filtering and sorting.
At least consider addd an indexed computed column that produces the file date
I want to convert the string to date type
Look at the first and 2nd statements you included, they are different in that you are missing a quote and you added an extra quote in the second one.
declare #filename varchar(20) = 'D181115.T000000'
select convert(datetime, '20' + substring(#filename, 2,2) + '-' + substring(#filename, 4,2) + '-' + substring(#filename,6,2))
Produces output:
2018-11-15 00:00:00.000

SQL Most efficient way to create int value from dateTime

Using SQL Server 2008 R2, I have a trigger which updates a field AFTER UPDATE. It inserts the date for each of the updated rows. This line in the trigger does this action:
SET t.lastUpdatedDateTime = CURRENT_TIMESTAMP
Using yyyymmddhhmmss the above line will insert this 2015-07-16 16:19:00. Now I have a situation where the business wants an integer version of this.
What is the most effective way to achieve this. This is what I have which does work but it seems very long and expensive:
SET t.lastUpdatedDateTimeINT = CAST('' + cast(year(GETDATE()) as varchar(4)) + right('0' + cast((month(GETDATE())) as varchar(2)), 2) + right('0' + cast((day(GETDATE())) as varchar(2)), 2) + right('0' + cast((datepart(hh, GETDATE())) as varchar(2)), 2) + right('0' + cast((datepart(MI, GETDATE())) as varchar(2)), 2) + right('0' + cast((datepart(ss, GETDATE())) as varchar(2)), 2) as bigint)
Is there a better more efficient way to do this? The desired outcome is 20150716161900
A secondary question. I am not a fan of storing dates as integers at all. in fact I have never done it before this current role. Can I ask for opinions on this, what are great reasons to avoid this? There are a few reasons why there is a preference for this in this organisation. Here is one, every time a client hit a webservice this dateTime value is delivered with the content, when the client hits the webservice in the future it need to pass in this dateTime value to effectivley get the best data back. Simply, The business is afraid this will come back in a different format.
EDITED:
Here is the full trigger for completness:
ALTER TRIGGER [dbo].[trig_lastUpdated]
ON [dbo].[AAdeleteMe]
AFTER UPDATE
AS
BEGIN
IF NOT UPDATE(lastUpdatedDateTime)
BEGIN
UPDATE t
-- my original code (the long way for my result)
--SET t.lastUpdatedDateTimeINT = CAST('' + cast(year(GETDATE()) as varchar(4)) + right('0' + cast((month(GETDATE())) as varchar(2)), 2) + right('0' + cast((day(GETDATE())) as varchar(2)), 2) + right('0' + cast((datepart(hh, GETDATE())) as varchar(2)), 2) + right('0' + cast((datepart(MI, GETDATE())) as varchar(2)), 2) + right('0' + cast((datepart(ss, GETDATE())) as varchar(2)), 2) as bigint)
--and here is the solution below (the shortway for my result)
--SET t.lastUpdatedDateTimeINT = REPLACE(REPLACE((convert(varchar(10),CURRENT_TIMESTAMP,111) + convert(varchar(8),CURRENT_TIMESTAMP,114)),'/',''),':','')
--Just discovered the 112 format so managed to drop one replace
SET t.lastUpdatedDateTimeINT = REPLACE((convert(varchar(10),CURRENT_TIMESTAMP,112) + convert(varchar(8),CURRENT_TIMESTAMP,114)),':','')
FROM dbo.AADeleteMe AS t
INNER JOIN inserted AS i
ON t.ID = i.ID;
END
END
GO
If you want only integer part of Date, then one of the solution will be just remove the separators in Date Value ex:- '/', '-', ':' and ' ' space from date, and you will get the date with the format you want:-
SELECT REPLACE(REPLACE(REPLACE ( '2015-07-16 16:19:00' , '-' , '' ),':',''),' ','')
Output:- 20150716161900
See DEMO
Update:-
Use this As per you requirement
Select REPLACE(REPLACE((convert(varchar(10),CURRENT_TIMESTAMP,101)
+ convert(varchar(8),CURRENT_TIMESTAMP,114)),'/',''),':','')
And If your column lastUpdatedDateTimeINT is INT then its going to throw overflow error, so overcome that you have to change the datatype for that column as Value you going to assign is quite big for INT
If business is afraid that client can't handle complex data type such as datetime properly and wants to use simple int, at least use a standard way to store dates as int.
One of the widely spread ways to store dates as simple int - is unix time. It is always UTC. It is simply a number of seconds passed since 1970-01-01. You should use bigint, not int in any case. Still, I would store the date in the database as datetime and convert it to and from unix time when talking to client.
Convert from unix time to datetime:
DATEADD(second, [unixtime_value], '19700101')
Convert from datetime to unix time:
DATEDIFF(second, '19700101', [datetime_value])
Instead of CURRENT_TIMESTAMP use GETUTCDATE to get the current UTC time and then convert it to bigint:
DATEDIFF(second, '19700101', GETUTCDATE())

Converting separate columns for mm, dd, and yr into a workable mm/dd/year format

Basically I have 3 separate columns in a table. I will call them SMonth, Sday, Syear. They are stored as numeric values for some reason. I can use the following string to format them into what looks like a date but doesn't allow me to use functions such as sort, order by, datediff or dateadd.
CAST(SMonth AS varchar(2)) + '/' + CAST(SDay varchar(2)) + '/' + CAST(SYear AS varchar(4))
Anyone know how to convert this into a workable date, without changing the table?
It doesn't matter how it looks as long as I can use it ie a date or datetime makes no difference.
Thanks in advance.
Just convert your result into a date or datetime.
DECLARE #SMonth AS INT = 12
DECLARE #SDay AS INT = 31
DECLARE #SYear as INT = 2013
SELECT CONVERT(DATE,CAST(#SMonth AS varchar(2)) + '/' + CAST(#SDay AS varchar(2)) + '/' + CAST(#SYear AS varchar(4)))
you should convert format the string as yyyy/mm/dd in order to make sure that SQL Server uses ODBC canonical format
SELECT CONVERT(date, CONVERT(varchar, Syear) + '/' + convert(VARCHAR, SMonth) + '/' + convert(VARCHAR, SDay ) )
Otherwise it your results could depend on the default dateformat or someone changed it using SET DATEFORMAT, for example:
05/10/2013 could mean
May 10, 2013 if the DATEFORMAT is U.S.
October 5, 2013 if the DATEFORMAT is Brithish / French
see this for complete reference of dateformat