Retrieve individual values from datetimeoffset(7) object - sql

I have a datetimeoffset(7) object, I have to convert this object into nvarchar(255) in sql server 2008 r2.
I have source value in format like - '2014-07-01 06:00:00.0000000 +00:00' and desired format is like '07/01/2014 06:00:00 +00:00'.
Below are few ways i tried-
1) DECLARE #a VARCHAR(50) = '2019-10-24 06:00:00.0000000 +00:00'
SELECT (CONVERT(NVARCHAR(255), Cast(#a as DATE) ,101)) +' '+ (CONVERT(NVARCHAR(255),Cast(#a as time))) + ' ' + (CONVERT(NVARCHAR(255),Cast(#a as offset)))
but in code (CONVERT(NVARCHAR(255),Cast(#a as offset)) is causing error.
Is there is any way to get offset time zone value from datetimeoffset(7) objet ? or is there is any inbuild method in sql server using that i can get my desired format ?

datepart function is your friend. In particular, for the time zone offset, you want datepart(tz, #a). Note that the value returned is the number of minutes, so you still have to change that.

Related

I need to convert this string to datetime in SQL Server

String:
'01/04/2019 01:50:31.230000000'
Expected result:
01/04/2019 01:50:31.230
as a DATETIME.
Query used:
SELECT CONVERT(DATETIME, '01/04/2019 01:50:31.230000000', 113)
Converting that string, which is in the 103 format, would work if it didn't have the last 6 zero's.
So a SUBSTRING or LEFT could be used to keep only 23 characters.
And then convert it to a DATETIME.
But that string, can be converted just fine to a DATETIME2.
Since a DATETIME2 is more accurate.
And a DATETIME2 can be simply casted or converted to a DATETIME.
Note that DATETIME isn't stored with a format in the table.
The way it's displayed is a setting.
However, you can FORMAT a DATETIME back to a string in the specific format you need. (starting with SQL Server 2012)
Example snippet:
select
col as col_input_string,
CAST(CONVERT(datetime2, col, 103) AS datetime) as col_as_datetime,
FORMAT(CONVERT(datetime2, col, 103), 'dd/MM/yyyy HH:mm:ss.fff') as col_as_formatted_string
from (values
('01/04/2019 01:50:31.230000000')
,('31/12/2018 13:33:44.123456789')
) q(col);
Result:
col_input_string col_as_datetime col_as_formatted_string
01/04/2019 01:50:31.230000000 2019-04-01 01:50:31.230 01/04/2019 01:50:31.230
31/12/2018 13:33:44.123456789 2018-12-31 13:33:44.123 31/12/2018 13:33:44.123
The code you want is:
SELECT CONVERT(datetime,LEFT('01/04/2019 01:50:31.230000000',23),103);
You need to use LEFT as datetime is only accurate to 1/300 of a second; thus you need to trim off the accuracy that can't be used.
Try to use
declare #vardate varchar(50) = '01/04/2019 01:50:31.230000000'
declare #date datetime =convert(date, left(#vardate,23), 103)
declare #time time = convert(time, substring(#vardate,12,12), 14)
select DATEADD(DAY, DATEDIFF(DAY, #time, #date), CAST(#time AS DATETIME)) AS Result
if that does not work check different convert formats.

Convert LOCAL TIME data type value to UTC time

I am trying to write a query that returns records that fall between two dates (each with a cutoff in TIME format). So far I have the following:
For example:
SELECT
T.CustomerName,
T.MoneyToTransfer
FROM dbo.[Transfer] T
WHERE T.CreatedDate BETWEEN '2016-05-10 03:00:00.0000000' AND '2016-05-11 03:00:00.0000000'
However the cutoff time 03:00:00.0000000 is only a placeholder for how I think the query needs to be formatted - the TIME needs to be retrieved from another table 'TransferSubscriber' from field 'Cutoff' stored as data type TIME. The problem is that this Cutoff field in table TransferSubscriber is stored in LOCAL time (in a TIME data type). I need to convert this TIME to UTC, and place it in my BETWEEN statement in the TIME part of the comparison (where the 03:00:00.0000000).
I have written the following, which has issues concatenating the date and time variables into one:
DECLARE #startDate DATE = (SELECT CONVERT(VARCHAR, '2016-07-13', 110))
DECLARE #Cutoff AS TIME(7) = (SELECT TOP 1 S.CutoffTime FROM Subscriber.dbo.TransferSubscriber S WHERE ID = 10)
DECLARE #CutoffUTC TIME = (SELECT DATEADD(second,DATEDIFF(second, GETDATE(), GETUTCDATE()), #Cutoff))
DECLARE #StartDateFinal = #startDate + #CutoffUTC
#StartDateFinal throws error:
"Operand data type date is invalid for add operator."
I am sure there is a better way to convert local TIME to UTC time, and use it to compare two DATETIME fields.
Any help would be great!
Try the following,
DECLARE #startDate DATE = (SELECT CONVERT(VARCHAR, '2016-07-13', 110))
DECLARE #Cutoff AS TIME(7) = (SELECT TOP 1 S.CutoffTime FROM Subscriber.dbo.TransferSubscriber S WHERE ID = 10)
DECLARE #CutoffUTC TIME = (SELECT DATEADD(second,DATEDIFF(second, GETDATE(), GETUTCDATE()), #Cutoff))
DECLARE #StartDateFinal DATETIME2
SELECT #StartDateFinal=CAST(CAST(#startDate AS VARCHAR) +' '+ CAST(#CutoffUTC AS VARCHAR) AS DATETIME2)
SELECT #StartDateFinal
Hope it helps.

Combining (concatenating) date and time into a datetime

Using SQL Server 2008, this query works great:
select CAST(CollectionDate as DATE), CAST(CollectionTime as TIME)
from field
Gives me two columns like this:
2013-01-25 18:53:00.0000000
2013-01-25 18:53:00.0000000
2013-01-25 18:53:00.0000000
2013-01-25 18:53:00.0000000
.
.
.
I'm trying to combine them into a single datetime using the plus sign, like this:
select CAST(CollectionDate as DATE) + CAST(CollectionTime as TIME)
from field
I've looked on about ten web sites, including answers on this site (like this one), and they all seem to agree that the plus sign should work but I get the error:
Msg 8117, Level 16, State 1, Line 1
Operand data type date is invalid for add operator.
All fields are non-zero and non-null. I've also tried the CONVERT function and tried to cast these results as varchars, same problem. This can't be as hard as I'm making it.
Can somebody tell me why this doesn't work? Thanks for any help.
Assuming the underlying data types are date/time/datetime types:
SELECT CONVERT(DATETIME, CONVERT(CHAR(8), CollectionDate, 112)
+ ' ' + CONVERT(CHAR(8), CollectionTime, 108))
FROM dbo.whatever;
This will convert CollectionDate and CollectionTime to char sequences, combine them, and then convert them to a datetime.
The parameters to CONVERT are data_type, expression and the optional style (see syntax documentation).
The date and time style value 112 converts to an ISO yyyymmdd format. The style value 108 converts to hh:mi:ss format. Evidently both are 8 characters long which is why the data_type is CHAR(8) for both.
The resulting combined char sequence is in format yyyymmdd hh:mi:ss and then converted to a datetime.
The simple solution
SELECT CAST(CollectionDate as DATETIME) + CAST(CollectionTime as DATETIME)
FROM field
An easier solution (tested on SQL Server 2014 SP1 CU6)
Code:
DECLARE #Date date = SYSDATETIME();
DECLARE #Time time(0) = SYSDATETIME();
SELECT CAST(CONCAT(#Date, ' ', #Time) AS datetime2(0));
This would also work given a table with a specific date and a specific time field. I use this method frequently given that we have vendor data that uses date and time in two separate fields.
Cast it to datetime instead:
select CAST(CollectionDate as DATETIME) + CAST(CollectionTime as TIME)
from field
This works on SQL Server 2008 R2.
If for some reason you wanted to make sure the first part doesn't have a time component, first cast the field to date, then back to datetime.
DECLARE #ADate Date, #ATime Time, #ADateTime Datetime
SELECT #ADate = '2010-02-20', #ATime = '18:53:00.0000000'
SET #ADateTime = CAST (
CONVERT(Varchar(10), #ADate, 112) + ' ' +
CONVERT(Varchar(8), #ATime) AS DateTime)
SELECT #ADateTime [A nice datetime :)]
This will render you a valid result.
Solution (1): datetime arithmetic
Given #myDate, which can be anything that can be cast as a DATE, and #myTime, which can be anything that can be cast as a TIME, starting SQL Server 2014+ this works fine and does not involve string manipulation:
CAST(CAST(#myDate as DATE) AS DATETIME) + CAST(CAST(#myTime as TIME) as DATETIME)
You can verify with:
SELECT GETDATE(),
CAST(CAST(GETDATE() as DATE) AS DATETIME) + CAST(CAST(GETDATE() as TIME) as DATETIME)
Solution (2): string manipulation
SELECT GETDATE(),
CONVERT(DATETIME, CONVERT(CHAR(8), GETDATE(), 112) + ' ' + CONVERT(CHAR(8), GETDATE(), 108))
However, solution (1) is not only 2-3x faster than solution (2), it also preserves the microsecond part.
See SQL Fiddle for the solution (1) using date arithmetic vs solution (2) involving string manipulation
Concat date of one column with a time of another column in MySQL.
SELECT CONVERT(concat(CONVERT('dateColumn',DATE),' ',CONVERT('timeColumn', TIME)), DATETIME) AS 'formattedDate' FROM dbs.tableName;
drop table test
create table test(
CollectionDate date NULL,
CollectionTime [time](0) NULL,
CollectionDateTime as (isnull(convert(datetime,CollectionDate)+convert(datetime,CollectionTime),CollectionDate))
-- if CollectionDate is datetime no need to convert it above
)
insert test (CollectionDate, CollectionTime)
values ('2013-12-10', '22:51:19.227'),
('2013-12-10', null),
(null, '22:51:19.227')
select * from test
CollectionDate CollectionTime CollectionDateTime
2013-12-10 22:51:19 2013-12-10 22:51:19.000
2013-12-10 NULL 2013-12-10 00:00:00.000
NULL 22:51:19 NULL
This works in SQL 2008 and 2012 to produce datetime2:
declare #date date = current_timestamp;
declare #time time = current_timestamp;
select
#date as date
,#time as time
,cast(#date as datetime) + cast(#time as datetime) as datetime
,cast(#time as datetime2) as timeAsDateTime2
,dateadd(dayofyear,datepart(dayofyear,#date) - 1,dateadd(year,datepart(year,#date) - 1900,cast(#time as datetime2))) as datetime2;
dealing with dates, dateadd must be used for precision
declare #a DATE = getdate()
declare #b time(7) = getdate()
select #b, #A, GETDATE(), DATEADD(day, DATEDIFF(day, 0, #a), cast(#b as datetime2(0)))
I am using SQL Server 2016 and both myDate and myTime fields are strings. The below tsql statement worked in concatenating them into datetime
select cast((myDate + ' ' + myTime) as datetime) from myTable
SELECT CONVERT(DATETIME, CONVERT(CHAR(8), date, 112) + ' ' + CONVERT(CHAR(8), time, 108))
FROM tablename

Time part of a DateTime Field in SQL

How would I be able to extract the time part of a DateTime field in SQL? For my project I have to return data that has a timestamp of 5pm of a DateTime field no matter what the date is
This will return the time-Only
For SQL Server:
SELECT convert(varchar(8), getdate(), 108)
Explanation:
getDate() is giving current date and time.
108 is formatting/giving us the required portion i.e time in this case.
varchar(8) gives us the number of characters from that portion.
Like:
If you wrote varchar(7) there, it will give you 00:00:0
If you wrote varchar(6) there, it will give you 00:00:
If you wrote varchar(15) there, it will still give you 00:00:00 because it is giving output of just time portion.
SQLFiddle Demo
For MySQL:
SELECT DATE_FORMAT(NOW(), '%H:%i:%s')
SQLFiddle Demo
In SQL Server if you need only the hh:mi, you can use:
DECLARE #datetime datetime
SELECT #datetime = GETDATE()
SELECT RIGHT('0'+CAST(DATEPART(hour, #datetime) as varchar(2)),2) + ':' +
RIGHT('0'+CAST(DATEPART(minute, #datetime)as varchar(2)),2)
If you want only the hour of your datetime, then you can use DATEPART() - SQL Server:
declare #dt datetime
set #dt = '2012-09-10 08:25:53'
select datepart(hour, #dt) -- returns 8
In SQL Server 2008+ you can CAST() as time:
declare #dt datetime
set #dt = '2012-09-10 08:25:53'
select CAST(#dt as time) -- returns 08:25:53
I know this is an old question, but since the other answers all
return strings (rather than datetimes),
rely on the internal representation of dates (conversion to float, int, and back) or
require SQL Server 2008 or beyond,
I thought I'd add a "pure" option which only requires datetime operations and works with SQL Server 2005+:
SELECT DATEADD(dd, -DATEDIFF(dd, 0, mydatetime), mydatetime)
This calculates the difference (in whole days) between date zero (1900-01-01) and the given date and then subtracts that number of days from the given date, thereby setting its date component to zero.
Try this in SQL Server 2008:
select *
from some_table t
where convert(time,t.some_datetime_column) = '5pm'
If you want take a random datetime value and adjust it so the time component is 5pm, then in SQL Server 2008 there are a number of ways. First you need start-of-day (e.g., 2011-09-30 00:00:00.000).
One technique that works for all versions of Microsoft SQL Server as well as all versions of Sybase is to use convert/3 to convert the datetime value to a varchar that lacks a time component and then back into a datetime value:
select convert(datetime,convert(varchar,current_timestamp,112),112)
The above gives you start-of-day for the current day.
In SQL Server 2008, though, you can say something like this:
select start_of_day = t.some_datetime_column
- convert(time, t.some_datetime_column ) ,
from some_table t
which is likely faster.
Once you have start-of-day, getting to 5pm is easy. Just add 17 hours to your start-of-day value:
select five_pm = dateadd(hour,17, t.some_datetime_column
- convert(time,t.some_datetime_column)
)
from some_table t
Note that from MS SQL 2012 onwards you can use FORMAT(value,'format')
e.g. WHERE FORMAT(YourDatetime,'HH:mm') = '17:00'
"For my project, I have to return data that has a timestamp of 5pm of a DateTime field, No matter what the date is."
So I think what you meant was that you needed the date, not the time. You can do something like this to get a date with 5:00 as the time:
SELECT CONVERT(VARCHAR(10), GetDate(), 110) + ' 05:00:00'
This should strip away the date part:
select convert(datetime,convert(float, getdate()) - convert(int,getdate())), getdate()
and return a datetime with a default date of 1900-01-01.
you can use CONVERT(TIME,GETDATE()) in this case:
INSERT INTO infoTbl
(itDate, itTime)
VALUES (GETDATE(),CONVERT(TIME,GETDATE()))
or if you want print it or return that time use like this:
DECLARE #dt TIME
SET #dt = CONVERT(TIME,GETDATE())
PRINT #dt
select cast(getdate() as time(0))
returns for example :- 15:19:43
replace getdate() with the date time you want to extract just time from!
SELECT DISTINCT
CONVERT(VARCHAR(17), A.SOURCE_DEPARTURE_TIME, 108)
FROM
CONSOLIDATED_LIST AS A
WHERE
CONVERT(VARCHAR(17), A.SOURCE_DEPARTURE_TIME, 108) BETWEEN '15:00:00' AND '15:45:00'
declare #datetime as datetime
set #datetime = getdate()
select cast(cast(#datetime as time) as varchar(8))
For year:
SELECT DATEPART(YEAR, '2021-03-21' );
For hour:
SELECT DATEPART(HOUR, '2021-03-21 08:50:30' );

Sql Convert Text Field To Date Field

I'm importing an access database to sql.
The original access database has a date field that imports nicely, but the time field is text (10:00 AM, for instance).
I have over 4000 records and assume there is a way to convert 10:00 AM to 10:00:00.000 (or 07:30 PM to 19:30:00.000, etc...) so that it can be combined with the pre-existing date field (which is now like 2011-11-11 00:00:00.000).
Also, if it's easy to do the conversion and concatenation in the same process, please note.
to convert the time from am or pm 10:00 PM format into time format 10:00:00.000:
select cast(timestring as time(7))
look this:
declare #timeField as varchar(10)
set #timeField = '07:30 PM'
declare #dateField as varchar(10)
set #dateField = '1900-01-01'
select CONVERT(datetime,#dateField + ' ' + CAST(CONVERT(time, #timeField ,121) AS VARCHAR(11)),121)
In your import scripts (I assume you use some sort of SQL to E.T.L your data from Access to SQL server), you can use the convert function as such:
declare #t as time = Convert(time, '10:00PM' )
print #t -- prints 22:00:00.0000000
OR
declare #t as time = Convert(time, '10:00AM' )
print #t -- prints 10:00:00.0000000
And of course if you want to control the precision as per your example:
Convert(time(3), '10:00PM' ) -- prints 22:00:00.000