Convert date to ISO 8601 in SQL Server FOR JSON PATH? - sql

I am converting the data into json (using FOR JSON PATH) in SQL Server, one of the column in that data has a datetime datatype which I need to convert to ISO8601
Correct format: 2018-11-13T20:20:39+00:00
When I tried CONVERT(NVARCHAR(33), datetimecolumn, 127), the result is: 2019-10-24T12:35:12.870
When I tried TODATETIMEOFFSET(datetimecolumn, '+00:00'), the result is: 2015-03-31T00:00:00Z
In both cases I am not getting +00:00.

It appears that SQL Server represents a zero offset or UTC time with Z.
If you were to run SELECT TODATETIMEOFFSET(GETDATE(),60), which grabs the current time and applies a 1 hour offset, you would get the format you are expecting. However, I believe that Z denoting UTC is perfectly acceptable in ISO8601, but could be mistaken.
This command seems to output the JSON as expected.
SELECT TODATETIMEOFFSET(GETDATE(),60) as T FOR JSON PATH
If it is vital that the zero offset be represented as 00:00, I believe you will be force to work with strings.
select CAST(CONVERT(NVARCHAR(33), getdate(), 127) as NVARCHAR(35)) + '+00:00' as T
FOR JSON PATH

JSON (as a data-interchange format) doesn't specify the format for date and time values. FOR JSON implicitly converts date and time values to strings, but you can cast the datetime values in your statement with the appropriate type and style before using FOR JSON:
Statement:
SELECT CONVERT(varchar(30), CONVERT(datetimeoffset(0), GETDATE()), 126) AS T
FOR JSON PATH
Result:
[{"T":"2020-04-22T08:02:58+00:00"}]
If you want to convert to a specific time zone, you may try to use AT TIME ZONE:
Statement:
SELECT CONVERT(nvarchar, CONVERT(datetime2(0), GETDATE()) AT TIME ZONE 'Central European Standard Time', 126) AS T
FOR JSON PATH
Result:
[{"T":"2020-04-24T08:33:49+02:00"}]

Related

How to convert dd-mmm-yy hh.mm nvarchar to any date format

I have a very specific format for date and time stored in my table as nvarchar.
The format is 'DD-MMM-YY hh.mm' ex. '30-NOV-20 19.25' , '22-JAN-52 13.34' etc.
Is there any way to convert the above nvarchar to standard datetime formats within particular table?
Select Convert(DateTime, Replace(YourDateColumn, '.', ':'))
From YourTable
Your format would be fine if you had a colon between the hours and minutes. Use the replace function to accomodate that.
When you select a datetime value in SQL Server Management Studio, you should understand that it is determining how to display the value. If you want it to display in another way, you need to convert it back to a string while applying a format. For example:
Select PERSON_BDAY,
Convert(VarChar(10), Convert(DateTime, Left(PERSON_BDAY, 9)), 1)
From YourTable

Convert 2017-01-13T06:00:00Z time format to yyyy-mm-dd hh:mm:ss

I'm trying to convert time formats. The database table has time stored in a VARCHAR(50) column in the format of "yyyy-mm-ddThh:mi:ssZ". When running a query, I want the time formatted as "yyyy-mm-dd hh:mi:ss". (I don't care about time zone adjustment.) I don't understand why GETDATE with the style 120 returns what I want, but when I use the field name it does nothing.
SELECT
PlateEffectiveFrom as Value_In_Table,
STUFF(CONVERT(VARCHAR(33),PlateEffectiveFrom, 120),20,4,'') as 'Gets_Rid_of_Z',
CONVERT(varchar(33), PlateEffectiveFrom, 120) AS Does_Nothing,
CONVERT(varchar(33), GETDATE(), 120) AS Format_I_Want
FROM dbo.TVLTagDetails13
WHERE ID = 5
Returns:
Value_In_Table Gets_Rid_of_Z Does_Nothing Format_I_Want
2008-03-12T06:00:00Z 2008-03-12T06:00:00 2008-03-12T06:00:00Z 2019-01-08 11:16:41
The solution to this problem would be to change the data type of the column to DateTime2 if you don't need the time zone data, or DateTimeOffset if you need the time zone data.
Assuming this can't be done, what you do is a simple string manipulation to get from "yyyy-mm-ddThh:mi:ssZ" to "yyyy-mm-dd hh:mi:ss":
SELECT LEFT(REPLACE(PlateEffectiveFrom, 'T', ' '), 19) AS Format_I_Want
FROM dbo.TVLTagDetails13
WHERE ID = 5
Also, following the conversation in the comments - a must read: Aaron Bertrand's Bad habits to kick : choosing the wrong data type

How do I convert a value after using DATEADD with it

I have a little query that strips the date from the datetime field but when I try to convert it from GMT to CST it readds the date. Is there a better way to do this?
Location table:
arrival
4-6-2018 12:35:43
SELECT arrival
FROM(
SELECT CONVERT(VARCHAR(8), arrival))
FROM locations
)a
This query will give me this result:
12:35:43
SELECT (DATEADD(hour,-5,arrival))
FROM(
SELECT CONVERT(VARCHAR(8), arrival))
FROM locations
)a
4-6-2018 12:35:43
This query will give readd the date. How can I remove the date and then do the dateadd function without it readding the date
arrival seems to be a DateTime, which always carries a date part. You need a time instead, supported by SQL Server 2008+:
cast(DATEADD(hour,-5,arrival) as time)
To quote from DATEADD (Transact-SQL) - Return Types:
The return data type is the data type of the date argument, except for string literals. The return data type for a string literal is datetime. An error will be raised if the string literal seconds scale is more than three positions (.nnn) or contains the time zone offset part.
Emphasis my own.
As you are passing a string (varchar), then DATEADD is returning a datetime.
Like those in the comments have said, if you use the correct data type (time) this problem goes away:
SELECT DATEADD(HOUR, -5,CONVERT(time,Arrival))
FROM (VALUES('4-6-2018 12:35:43'),('4-6-2018 07:35:43'),('4-6-2018 03:35:43')) V(Arrival)
Probably this is what you are asking for:
SELECT Convert(Varchar(8), DATEADD(hour,-5,arrival), 108)
FROM locations;
Note: This is compatible with SQL server versions that doesn't have Time datatype too.

Convert datetime string in datetime format in SQL server

I'm using MS SQL server and I have a date field of type text. The dates stored there are in this format
2017-03-01T18:23:02+0700
I'm trying to convert this field in a datetime field but I fail. I have tried
CONVERT(datetimeoffset,date, 127)
CONVERT(datetime,date, 127)
CONVERT(datetime2,date, 127)
but I keep getting
Conversion failed when converting date and/or time from character
string.
I think the problem is that according to ISO8601 the time offset must be in the format hh:mm while mine is hhmm. I don't mind keeping only the date (yyyy-mm-dd) if it is more easy.
I have read similar question but none matches exactly my case and I can't figure out the solution.
Try this
Declare #dt varchar(50)
set #dt = '2017-03-01T18:23:02+0700'
select convert(datetime, replace(LEFT(#dt, LEN(#dt) - 1), '+', '.'), 126)
If you need only date part then you can use below query
SELECT CAST(LEFT('2017-03-01T18:23:02+0700',10) as DATE)
Use Below query to convert datetime :
SELECT CONVERT(DATETIME,REPLACE(REPLACE('2017-03-01T18:23:02+070','T','
'),'+','.'),103)
For DATE only use below query :
SELECT CONVERT(DATE,REPLACE(REPLACE('2017-03-01T18:23:02+010','T','
'),'+','.'),102)
It doesn't seem to work in both ways (both raise error):
SELECT CONVERT(datetime,'2017-03-01T18:23:02+0700',127)
SELECT CONVERT(datetime,'2017-03-01T18:23:02+07:00',127)
It seems that it works only specifying Z as time zone:
SELECT CONVERT(datetime,'2017-03-01T18:23:02Z',127)

Why does SQL Server convert VARCHAR to DATETIME using an invalid style?

I can't make out from the documentation why SQL Server parses a text in a format other than the specified style.
Regardless of whether I provide text in the expected format:
SELECT CONVERT(DATETIME, N'20150601', 112)
or incorrect format (for style 113):
SELECT CONVERT(DATETIME, N'20150601', 113)
The results are the same: 2015-06-01 00:00:00.000 I would expect the latter to fail to convert the date (correctly).
What rules does it employ when trying to convert a VARCHAR to DATETIME? I.e. why does the latter (incorrect format style) still correctly parse the date?
EDIT: It seems I've not been clear enough. Style 113 should expect dd mon yyyy hh:mi:ss:mmm(24h) but it happily converts values in the format yyyymmdd for some reason.
Because the date is in a canonical format ie(20150101). The database engine falls over it implicitly. This is a compatibility feature.
If you swapped these around to UK or US date formats, you would receive conversion errors, because they cannot be implicitly converted.
EDIT: You could actually tell it to convert it to a pig, and it would still implicitly convert it to date time:
select convert(datetime,'20150425',99999999)
select convert(datetime,'20150425',100)
select convert(datetime,'20150425',113)
select convert(datetime,'20150425',010)
select convert(datetime,'20150425',8008135)
select convert(datetime,'20150425',000)
And proof of concept that this is a compatibility feature:
select convert(datetime2,'20150425',99999999)
Although you can still implicitly convert datetime2 objects, but the style must be in the scope of the conversion chart.
Reason why is the date N'20150601' converted to valid datetime is because of fact that literal N'20150601' is universal notation of datetime in SQL Server. That means, if you state datetime value in format N'yyyymmdd', SQL Server know that it is universal datetime format and know how to read it, in which order.
You should convert to varchar type in order to apply those formats:
SELECT CONVERT(varchar(100), CAST('20150601' as date), 113)
OK, you are converting datetime to datetime. What did you expect? In order to apply formats you should convert to varchar and you have to have date or time type as second parameter.