Converting GMT to EST in SQL Server - sql

I have a table which stores records for Daylight saving and non-Daylight savings
CREATE TABLE #tmp
(
ID int,
IntervalName nvarchar(100),
StartDate datetime,
EndDate Datetime,
offset numeric(5, 2)
)
INSERT INTO #tmp
VALUES (1, 'EDT', '2022-03-13 07:00:00.000', '2022-11-06 06:00:00.000',-4.00)
INSERT INTO #tmp
VALUES (2, 'EST', '2022-11-06 06:00:00.000', '2023-03-12 07:00:00.000', -5.00)
I have my transactional tables which have Date column in the GMT timezone.
ID DatetimeGMT DatetimeLocal
---------------------------------------------------------
1 2022-11-05 07:00:00.000 2022-11-05 03:00:00.000
2 2022-11-10 06:00:00.000 2023-11-10 01:00:00.000
Now my DatetimeLocal column is calculating the offset hours based on the DatetimeGMT column.
The row with ID = 1 falls under offset -4 and the row with ID = 2 falls under offset -5.
Is there any suggestion how we can achieve this?

If you have the offsets all stored in a table like that, then you just need to JOIN to find the correct one.
eg
drop table if exists #tmp
drop table if exists #tran
go
CREATE TABLE #tmp
(
ID int,
IntervalName nvarchar(100),
StartDate datetime,
EndDate Datetime,
offset numeric(5, 2)
)
INSERT INTO #tmp
VALUES (1, 'EDT', '2022-03-13 07:00:00.000', '2022-11-06 06:00:00.000',-4.00)
INSERT INTO #tmp
VALUES (2, 'EST', '2022-11-06 06:00:00.000', '2023-03-12 07:00:00.000', -5.00)
create table #tran(id int primary key, DateTimeUTC datetime)
insert into #tran(id,DateTimeUTC) values (1,'2022-11-05 07:00:00.000'),(2,'2022-11-10 06:00:00.000')
select t.id, t.DateTimeUTC, dateadd(hour,offset,t.DateTimeUTC) DateTimeLocal, tz.offset
from #tran t
join #tmp tz
on t.DateTimeUTC >= tz.StartDate
and t.DateTimeUTC < tz.EndDate
outputs
id DateTimeUTC DateTimeLocal offset
----------- ----------------------- ----------------------- ---------------------------------------
1 2022-11-05 07:00:00.000 2022-11-05 03:00:00.000 -4.00
2 2022-11-10 06:00:00.000 2022-11-10 01:00:00.000 -5.00
SQL Server 2016 and later have the offsets built-in, so you can write queries like
select t.id,
t.DateTimeUTC,
cast(t.DateTimeUTC at time zone 'UTC' at time zone 'EASTERN STANDARD TIME' as datetime) DateTimeLocal
from #tran t

Related

SQL Server copy muptiple rows of same table changing only date of a datetime column

I need to copy all rows of a table, changing only the date part of the Datetime. The query I've been testing in sqlfiddle, returns record count of 0, and obviously the #newDate + SameTime isn't part of the query, but I put it there so you know what I want to do.
CREATE TABLE Games
(
[Id] int IDENTITY(1, 1) PRIMARY KEY,
[GameTypeId] int,
[DateCreated] datetime,
[DateTime] datetime,
[Location] int
);
INSERT INTO Games ([GameTypeId], [DateCreated], [DateTime], [Location])
VALUES ('1', GETDATE(), '8/21/2021 8:00:00', '1'),
('2', GETDATE(), '8/21/2021 9:00:00', '1'),
('2', GETDATE(), '8/21/2021 10:00:00', '1');
The query I'm testing to copy the rows but is not working:
INSERT INTO Games (GameTypeId, DateCreated, DateTime, Location)
SELECT
GameTypeId, GETDATE(), #newDate + SameTime, Location
FROM
Games
WHERE
CONVERT(date, DateTime) = '8/21/2021'
The results from the initial insert:
Id GameTypeID DateCreated DateTime Location
--------------------------------------------------------------
1 1 8/15/2021 8/21/2021 8:00:00 1
2 1 8/15/2021 8/21/2021 9:00:00 1
3 1 8/15/2021 8/21/2021 10:00:00 1
And after the copy rows query, the results I want (but can't get). I want to copy everything to a new row, except the date only needs to change. The time stays the same:
4 1 8/20/2021 8/28/2021 8:00:00 1
5 1 8/20/2021 8/28/2021 9:00:00 1
6 1 8/20/2021 8/28/2021 10:00:00 1
You can use date arithmetic:
INSERT INTO Games (GameTypeId, DateCreated, DateTime, Location)
SELECT GameTypeId, DATEADD(day, 5, DateCreated),
DATEADD(day, 7, DateTime), location
FROM Games
WHERE CONVERT(date, DateTime) = '2021-08-21'

Converting date time format

We have data in a Visit_Time column stored in 24Hrs date format as well as 12Hrs.
The data is inserted into a table from a different type of source like MobileApp and Web source etc.
Example:
Create table VisitorDetails
(
Visit_Date Date,
Visit_Time varchar(12)
)
VisitorDetails
----------------------------
Visit_Date Visit_Time
----------------------------
2020-01-01 01:00PM
2020-01-02 17:00
2020-01-03 04:00PM
2020-01-04 20:00
-----------------------------
How to convert Visit_Time Column either in 12 Hrs format or 24 Hrs formate?
Need Result like below
VisitorDetails 12Hrs 24Hrs
---------------------------- --------------
Visit_Date Visit_Time (OR) Visit_Time
---------------------------- --------------
2020-01-01 01:00PM 13:00
2020-01-02 05:00PM 17:00
2020-01-03 04:00PM 16:00
2020-01-04 08:00PM 20:00
----------------------------- --------------
12 hour format
declare #t1 time
declare #t2 time
declare #t3 time
set #t1 = '14:40'
set #t2 = '17:00'
set #t3 = '01:00PM'
select CONVERT(varchar(15),#t1,100)
select CONVERT(varchar(15),#t2,100)
select CONVERT(varchar(15),#t3,100)
When fetching your rows you could do:
SELECT [Visit_Date], LEFT(PARSE([Visit_Time] AS time), 5)
FROM [VisitorDetails]
for a consistent time format.
However, I would strongly recommend returning time values from the db and do the display modification in your app.
Please try below solution:
--24 Hour Format
SELECT CONVERT(VARCHAR(5),CONVERT(DATETIME, '01:00PM', 0), 108)
SELECT CONVERT(VARCHAR(5),CONVERT(DATETIME, '17:00', 0), 108)
--12 Hour Format
SELECT LTRIM(RIGHT(CONVERT(VARCHAR(20), CONVERT(DATETIME, '01:00PM', 0), 100), 7))
SELECT LTRIM(RIGHT(CONVERT(VARCHAR(20), CONVERT(DATETIME, '17:00', 0), 100), 7))
To Store 24 hrs format declare the Column data type as DATETIME Instead of Varchar(12)
DECLARE #T TABLE(
ID INT IDENTITY(1,1),
Visit_DATE_TIME varchar(20))
12 hrs Data insertion:
INSERT INTO #T VALUES('24-MAY-2020 10:30PM')
INSERT INTO #T VALUES('25-MAY-2020 11:30AM')
24 hrs Data insertion:
INSERT INTO #T VALUES('26-MAY-2020 16:30')
INSERT INTO #T VALUES('28-MAY-2020 22:30')
Query
SELECT *, CAST(VISIT_DATE_TIME as DATE) as Visit_Date ,
CAST(VISIT_DATE_TIME as TIME) as Visit_Time_24,
RIGHT(CONVERT(DATETIME,RTRIM(VISIT_DATE_TIME), 109),7) as Visit_Time_12
FROM #T

How do I add time datatype column in SQL server

I have a table in sql server 2012,with column named Duration as Time datatype.i want to update this column base on difference of dates, by adding the difference to this duration column.how can I do this in SP.
ID StartDate EndDate Duration
1 2017-02-27 09:10:35 2017-02-27 09:25:35 00:15
2 2017-02-27 09:26:35 2017-02-27 09:36:35 00:25
Durtion always less than 24 hours.
One method is:
update t
set duration = cast(dateadd(ms, datediff(ms, startdate, enddate), 0) as time);
This is an easy one. Just use a simple arithmetic operation:
DECLARE #TABLE TABLE (Start DATETIME, Finish DATETIME, Duration TIME);
INSERT INTO #TABLE VALUES ('02/28/2017 08:00','02/28/2017 08:30','');
INSERT INTO #TABLE VALUES ('02/28/2017 09:00','02/28/2017 09:40','');
INSERT INTO #TABLE VALUES ('02/28/2017 10:02','02/28/2017 11:53','');
INSERT INTO #TABLE VALUES ('02/28/2017 11:56','02/28/2017 12:45','');
INSERT INTO #TABLE VALUES ('02/28/2017 13:45','02/28/2017 23:59','');
UPDATE #TABLE
SET Duration = Finish - Start;
SELECT * FROM #TABLE;
Returns:
Start Finish Duration
---------------------------------------------------------
28/02/2017 08:00:00 28/02/2017 08:30:00 00:30:00
28/02/2017 09:00:00 28/02/2017 09:40:00 00:40:00
28/02/2017 10:02:00 28/02/2017 11:53:00 01:51:00
28/02/2017 11:56:00 28/02/2017 12:45:00 00:49:00
28/02/2017 13:45:00 28/02/2017 23:59:00 10:14:00
The only caveat here being that they need to be on the same day. You explicitly stated that the duration is never more than one day, so that should be fine.
If you want to add the result to the original value of Duration, then you would just add it on...
INSERT INTO #TABLE VALUES ('02/27/2017 08:00','02/28/2017 08:30','00:15');
INSERT INTO #TABLE VALUES ('02/28/2017 09:00','02/28/2017 09:40','00:14');
INSERT INTO #TABLE VALUES ('02/28/2017 10:02','02/28/2017 11:53','00:13');
INSERT INTO #TABLE VALUES ('02/28/2017 11:56','02/28/2017 12:45','02:16');
INSERT INTO #TABLE VALUES ('02/28/2017 13:45','02/28/2017 23:59','00:17');
UPDATE #TABLE
SET Duration = Duration + (Finish - Start);
Returns:
Start Finish Duration
---------------------------------------------------------
27/02/2017 08:00:00 28/02/2017 08:30:00 00:45:00
28/02/2017 09:00:00 28/02/2017 09:40:00 00:54:00
28/02/2017 10:02:00 28/02/2017 11:53:00 02:04:00
28/02/2017 11:56:00 28/02/2017 12:45:00 03:05:00
28/02/2017 13:45:00 28/02/2017 23:59:00 10:31:00
UPDATE [TABLE] SET [DURATION] = CONVERT(varchar(5),DATEADD(minute, DATEDIFF(MINUTE, StartDate, EndDate), 0), 114);
None of the other answers attempt to SUM the duration which is what you expect.
DECLARE #TABLE TABLE (ID INT, StartTime DATETIME, EndTime DATETIME, Duration TIME);
INSERT INTO #TABLE VALUES (1, '02/28/2017 01:00','02/28/2017 06:30','');
INSERT INTO #TABLE VALUES (2, '02/28/2017 09:00','02/28/2017 23:40','');
INSERT INTO #TABLE VALUES (3, '03/01/2017 10:02','03/01/2017 21:53','');
UPDATE t
SET Duration=
CONVERT(TIME,
(
SELECT DATEADD(ms, SUM(DATEDIFF(ms, '00:00:00.000', EndTime - StartTime)), '00:00:00.000')
FROM #TABLE it
WHERE it.EndTime<= t.EndTime
)
)
FROM #TABLE t;
SELECT * FROM #TABLE;

How to compare date in SQL Server 2008

Here I need to compare date using SQL Server 2008. I want show details of the table if the specific date appears more than one time.
Example:
create table datetest
(
columnx nvarchar(10),
columny nvarchar(10),
coldate date,
coltime datetime
)
insert into datetest values('a123','b123','2014-01-01','01:05:00.000');
insert into datetest values('a123','b456','2014-01-01','02:15:00.000');
insert into datetest values('a123','b789','2014-01-01','03:25:00.000');
insert into datetest values('a321','b321','2014-02-03','10:05:00.000');
insert into datetest values('a243','b243','2014-03-04','11:05:00.000');
insert into datetest values('a243','b243','2014-03-04','12:05:00.000');
insert into datetest values('a243','b243','2014-03-04','12:05:00.000');
Now I need to show only that records whose dates are greater than one appear in the table.
Expected result:
columnx columny coldate coltime
-------------------------------------------------------
a123 b123 2014-01-01 1900-01-01 01:05:00.000
a123 b456 2014-01-01 1900-01-01 02:15:00.000
a123 b789 2014-01-01 1900-01-01 03:25:00.000
a243 b243 2014-03-04 1900-01-01 11:05:00.000
a243 b243 2014-03-04 1900-01-01 12:05:00.000
a243 b243 2014-03-04 1900-01-01 12:05:00.000
My attempt:
select *
from datetest
where coldate = '2014-01-01' or coldate = '2014-03-04';
Note: But this is not the right way for the large records to check.
try like this
select * from datetest
where coldate in (select coldate from
datetest group by coldate having count(*) > 1)
DEMO

Finding Max and Min Times

I want to display max time and min time for a day in grid control using Visual Basic from a SQL Server database. My data currently looks like this:
UserID UserName Date Time
------------------------------------------
1 Shanks 30/1/2009 10:11:22
1 Shanks 30/1/2009 10:15:22
1 Shanks 30/1/2009 12:15:22
1 Shanks 30/1/2009 13:15:22
I need the output like this:
1 Shanks 30/1/2009 10:11:22 13:15:22
My table structure is:
UserID integer,
UserName varchar(20),
[Date] datetime,
[Time] datetime
How can I get that output from my data?
Is this what you're looking for?
SELECT UserID,
UserName,
Date,
MIN([Time]) AS MinTime,
MAX([Time]) AS MaxTime,
FROM Users
GROUP BY UserID, UserName, [Date]
SELECT
UserID,
UserName,
[Date],
MIN([Time]),
MAX([Time])
FROM
Table
GROUP BY
UserID,
UserName,
[Date]
Tested and working correctly with the following
DECLARE #Table TABLE (UserID INT,UserName VARCHAR(25),[Date] DATETIME,[Time] DATETIME)
INSERT INTO #Table VALUES(1, 'Shanks', '30 JAN 2009', '10:11:22');
INSERT INTO #Table VALUES(1, 'Shanks', '30 JAN 2009', '10:15:22');
INSERT INTO #Table VALUES(1, 'Shanks', '30 JAN 2009', '12:15:22');
INSERT INTO #Table VALUES(1, 'Shanks', '30 JAN 2009', '13:15:22');
INSERT INTO #Table VALUES(2, 'Shilpa', '3 JAN 2009', '10:11:22');
INSERT INTO #Table VALUES(2, 'Shilpa', '3 JAN 2009', '11:15:22');
INSERT INTO #Table VALUES(2, 'Shilpa', '3 JAN 2009', '12:15:22');
INSERT INTO #Table VALUES(2, 'Shilpa', '3 JAN 2009', '17:15:22');
SELECT
UserID,
UserName,
[Date],
MIN([Time]),
MAX([Time])
FROM
#Table
GROUP BY
UserID,
UserName,
[Date]
Results in
UserID UserName Date
----------- ------------------------- ----------------------- ----------------------- -----------------------
1 Shanks 2009-01-30 00:00:00.000 1900-01-01 10:11:22.000 1900-01-01 13:15:22.000
2 Shilpa 2009-01-03 00:00:00.000 1900-01-01 10:11:22.000 1900-01-01 17:15:22.000