Time offset at specific date - sql

I was wondering if anybody knows a function to convert UTC to local time but at the time the record was saved, not the time the script is being run.
Example:
I have a record saved in February and another one in August. Both are in UTC.
When I look at them through the application the February one shows the time -5 hrs and the August one shows the time -4 hours.
When I run a SQL script I need to see the same but using the T-SQL functions both show their time -5 hours (or -4 hours) depending when I run the script.
Analyzing the situation a bit further I realized it’s more complicated that what I thought.
There are 4 possibilities: The record saved during DST or ST and the SQL script being run during DST or ST.
If both are in DST or ST then I've just have to subtract the offset; if the record was saved in ST and the query is run in DST I'll have to subtract the offset – 1 but if it’s the other way around (record in DST and script run in ST) I should subtract the offset + 1.

Let's assume the UTC date was 2017-08-01 13:30:00 and I'm on the East Coast (US)
Select DateAdd(MINUTE, DateDiff(MINUTE, GetUTCDate(), GetDate()), '2017-08-01 13:30:00')
Returns
2017-08-01 09:30:00.000
Also, take a peek at SYSDATETIMEOFFSET()

Related

Date_diff with specific condition time start and time end

is it possible to have date_diff with specific start and end time?
let say my store are open from 8AM - 10PM, which is 14 Hours.
and I have a lot of stuff to sell during that time. One of the SKU is out of stock from 2022-11-01 06.00 PM until tomorrow 2022-11-02 11.00 AM.
Instead of calculate 24 hours, I just want to calculate only from opening store until it closed or until its restock. Meaning from 6PM to 11AM is 8 Hours
my query
select date_diff('2022-11-02 11.00 AM', '2022-11-02 06.00 PM', hour) from table
with the result 17 hours instead of 8 hours
There isn't a way to configure DATE_DIFF to do this for you, but it's possible to do what you want, with some effort.
You should convert your dates to timestamps (TIMESTAMP(yourdate) or CAST(yourdate AS TIMESTAMP)) and use TIMESTAMP_DIFF instead.
This will allow you to work with smaller intervals than days.
For your calculation, you ultimately need to find the total time difference between the two timestamps and then subtract the out-of-hours timeframe.
However, calculating the latter is not as simple as taking the difference in days and multiplying by 8 hours (10pm-6am), because your out-of-hours calculation has to account for weekends and possibly holidays etc. Hence it can get quite complex, which is where the solution in my first link might come in.

how to write a sql to calculate working hours minus rest time

I have a table of rest time in work shift
Begin end
12:00 12:30
17:30 18:30
Now I want to write a SQL to calculate actual working hours given the start and end time. For example if start at 9:00 and end at 15:00, the actual hours is 6-rest time=5.5 hours and if start at 9:00 and end at 20:00 the actual hours is 10 hours. How to write a procedure to check it in SQL server? Thx.
There are no schema details to work with here, which means the following SQL is generic and will have to be altered to fit your db.
SELECT
(datediff(minute, shiftStartTime, shiftEndTime)
- datediff(minute,breakStartTime,breakEndTime)) / 60.0
FROM yourTable
Notes:
If they can have multiple breaks, you need to sum up all the break times in minutes before deducting it from the shift period.
the calculation is specifically in minutes because the datediff counts the number of boundaries passed, so the date diff in hours between 11:59 and 12:01 is 1, even though the break is 2 minutes, you would count that as 1 hour if you count hours using the function.
If you can provide more schema details, we would be able to craft a more complete statement.
you can try below way using DATEDIFF
select *, CONVERT(time(7),DATEADD(s, DATEDIFF(s,S,E),'00:00:00')) from QQ
http://sqlfiddle.com/#!18/01213d/1
for your case column name will be
select *, CONVERT(time(7),DATEADD(s, DATEDIFF(s,Begin,end),'00:00:00')) from yourtable

Converting Time into Minutes in Pentaho (PDI Script)

I want to calculate sum of activity time(HH:mm:ss) for various transactions in PDI. For example, consider 3 activity times: 1) Activity 1 - 01:22:03,
2) Activity 2 - 01:10:11 and 3) Activity 3 - 00:22:20. The sum of all this time should be 02:54:34 but the result displays negative value. How would I improve it?
I ran into your issue (and the solution) almost by accident. It's worth explaining in a bit of detail.
Date fields are not meant for durations. They define instants. If you define a date field without its date part you're actually defining it as an instant on 1 Jan 1970, which is Unix time's start.
So, if you take your first timestamp, when you set 01:22:23 as a date field you're actually setting it to be "1 Jan 1970 01:22:23". You'd expect this field to return 4923 it's value in seconds (e.g., using getTime() on Javascript). This would work out nicely for your calculations; you could then add them up, and re-format to display.
However, if you don't specify the Timezone when setting the date value, then the date field will use your LOCAL timezone settings to define that time.
So, if you're in NY timezone, defining 01:22:23 as a Date field with format HH:mm:ss returns "31 Dec 1969 6:22:23 UTC", which returns 22923 in seconds.
If you're in Paris or another city which was ahead of UTC on 1 Jan 1970, some or all of your durations may return negative values.
The reason I say I ran into it by accident is because I'm based in London, which should be on UTC in the winter. However, oddly, that was not the case in 1970 (see UNIX timestamp(0): Europe/London returns UTC+1)
So, when calculating the timestamps in London timezone, I got:
Local time, seconds in Unix time
1:22:03, 1323
1:10:11, 611
0:22:20, -2260
These numbers add up to -326.
My suggestion:
Don't define durations as dates, or timestamps; that's not what they are. Durations are time intervals. A 1h duration is worth the same regardless of the year, day or timezone you measure it in.
Instead, just parse the values in a javascript step and do the math without resorting to date parsing.
Hacks to get around the problem (which I don't recommend):
explicitly set the timezone as +0000 when converting the fields to dates;
change your computer's timezone to UTC.

DATEDIFF - How many days until Sunday

In SQL Server, trying to write a age-off report for inventory purposes. Each week, the inventory system marks thousands of rows for deletion. This takes place on Sundays # 06:00:00 as part of weekly SQL DB purge schedule.
Using (yyyy-mm-dd hh:mm:ss:ms) format for closed_time, how can I calculate the numbers of days between that date, until next Sunday of the current week? And to be more elaborate, is there a way to narrow it down to the exact DD:HH:MM? The problem is the each client's Sunday DB schedule for purge varies. So that might be difficult to compute. Might be easier to just calculate whole days until Sunday 00:00:00. I tried using the DATEDIFF function with no success.
SELECT
Yada
DATEDIFF(DAY, closed_time,DW) AS Days_Until_Purged
FROM DB1
WHERE closed_time DESC
Thx in advance
If you choose any Sunday in the past (Such as 06:00 Sunday 2nd January 2000), you can calculate time that has GONE BY since then.
Then, if you take that and do modulo 7-days you get the time that has gone by since the most recent Sunday.
Then, if you do 7 - time_gone_by_since_last_sunday you get the time until the next sunday.
I'm going to do this in minutes to cope with a client that has a setting of 06:30.
DECLARE
#batch_processing_time SMALLDATETIME
SET
#batch_processing_time = '2000-01-02 06:00'
SELECT
(60*24*7) - DATEDIFF(minute, #batch_processing_time, closed_time) % (60*24*7)
FROM
yourTable
That's the number of minutes from each record's closed_time until the next #batch_processing_time.
Divide by (24*60) to get it in days.
try this:
select 8-DATEpart(w, closed_time) AS Days_Until_Purged from DB1 ...
This should solve your problem
SET DATEFIRST 1
Select DATEDIFF(dd,GETDATE(),DATEADD(DAY , 7-DATEPART(WEEKDAY,GETDATE()),GETDATE()))

datetime manipulation: replace all dates with 00:00 time with 24:00 the previous day

I have a table described here: http://sqlfiddle.com/#!3/f8852/3
The date_time field for when the time is 00:00 is wrong. For example:
5/24/2013 00:00
This should really be:
5/23/2013 24:00
So hour 00:00 corresponds to the last hour of the previous day (I didn't create this table but have to work with it). Is there way quick way when I do a select I can replace all dates with 00:00 as the time with 24:00 the previous day? I can do it easily in python in a for loop but not quite sure how to structure it in sql. Appreciate the help.
All datetimes are instants in time, not spans of a finite length, and they can exist in only one day. The instant that represents Midnight is by definition, in the next day, the day in which it is the start of the day, i.e., a day is closed on its beginning and open at its end, or, to phrase it again, valid allowable time values within a single calendar date vary from 00:00:00.00000, to 23:59:59.9999.
This would be analogous to asking that the minute value within an hour be allowed to vary from 1 to 60, instead of from 0 to 59, and that the value of 60 was the last minute of the previous hour.
What you are talking about is only a display issue. Even if you could enter a date as 1 Jan 2013 24:00, (24:00:00 is not a legal time of day) it would be entered as a datetime at the start of the date 2 Jan, not at the end of 1 Jan.
One thing that illustrates this, is to notice that, because of rounding (SQL can only resolve datetimes to within about 300 milleseconds), if you create a datetime that is only a few milleseconds before midnight, it will round up to midnight and move to the next day, as can be seen by running the following in enterprise manager...
Select cast ('1 Jan 2013 23:59:59.999' as datetime)
SQL server stoers all datetimes as two integers, one that represents the number days since 1 Jan 1900, and the other the number of ticks (1 tick is 1/300th of a second, about 3.33 ms), since midnight. If it has been zero time interval since Midnight, it is stll the same day, not the previous day.
If you have been inserting data assuming that midnight 00:00:00 means the end of the day, you need to fix that.
If you need to correct your existing data, you need to add one day to every date in your database that has midnight as it's time component, (i.e., has a zero time component).
Update tbale set
date_time = dateAdd(day, 1, date_time)
Where date_time = dateadd(day, datediff(day, 0, date_time), 0)