timestamp of 31/12/9999 23:59:29 - jython

Please have a look at the description below and let me know why the timestamp for
31/12/9999 23:59:29 is not 253402264799, but 253402261199.
Many thanks,
Huy
import datetime
d1 = datetime.datetime(1970, 1,1,10,0,0) ; I am in zone time 10
d2 = datetime.datetime(1970, 1,2,23,59, 59)
print d2 - d1 --> 1 day, 13:59:59
convert 1 day, 13:59:59 to sec
= 136799s <-- (48 + 14) * 3600 - 1
d1 = datetime.datetime(1970, 1,1,10,0,0)
d2 = datetime.datetime(9999, 12, 31, 23, 59, 59)
print d2 - d1 --> 2932896 days, 13:59:59
convert 2932896 days, 13:59:59 to sec
253402264799sec <-- (2932896 * 24 + 14) * 3600 - 1
print datetime.datetime.fromtimestamp(253402264799) --> exception throw
print datetime.datetime.fromtimestamp(253402261199) --> 31/12/9999 23:59:59

The reason is Time Daylight Saving. Zone 10 is 11 hours ahead in summer time.

Related

How do I calculate the difference between two timestamps?

How to calculate the difference in minutes between timestamps TIMEIN and TIMEOUT? My table (only 3 rows):
DATE
TIMEIN
TIMEOUT
2020-05-06
14:00
15:00
2020-05-06
14:45
15:55
2020-05-07
09:00
10:45
My SQL doesn't output what I want:
SELECT (T.DATE + T.TIMEIN - T.DATE + T.TIMEOUT) AS `Duration`
FROM Transport T;
Output:
Duration
29
29
19
It should be :
Duration
60
70
105
I tried this without using the date, however that lead to an output of -1 for all rows.
Assuming that TIMEOUT is always greater than TIMEIN you can subtract the unix epochs of the 2 values and divide by 60 to get the number of minutes:
SELECT (strftime('%s', TIMEOUT) - strftime('%s', TIMEIN)) / 60 AS Duration
FROM Transport;
See the demo.
date/time is not like integers so they didn't add/subtract like integers. So convert them in a timestamp before subtraction.

How do I work out minutes that occurred during office hours (9-5) and out of office hours

I have a datetime field that is when an activity starts and an int field with active_time in minutes.
What I want to do is work out in minutes (and then hours /60) how much time the activity was spent during work hours (9-5) and time outside of those hours.
E.G.
Data columns
Datetime: '2022-02-28 16:54:00.000 +0000'.
Active_time in minutes: '20'
Desired output:
Activity time in work hours: '6'
Activity time out of work hours: '14'
Can anyone help?
Many thanks.
SELECT start_time, minutes, time_pre_work, work_time, post_work_time
FROM (
SELECT *
,timeadd('minute', minutes, start_time) as time_end
,date_trunc('day', start_time) as day
,timeadd('hour', 8, day) as workday_start
,timeadd('hour', 17, day) as workday_end
,timediff('minute', least(start_time, workday_start), workday_start) as time_pre_work
,timediff('minute', greatest(start_time, workday_start), least(workday_end, time_end)) as work_time
,timediff('minute', greatest(workday_end, workday_end), greatest(workday_end, time_end)) as post_work_time
FROM VALUES
('2022-02-28 16:54:00.000'::timestamp, 20)
t(start_time, minutes)
);
gives:
START_TIME
MINUTES
TIME_PRE_WORK
WORK_TIME
POST_WORK_TIME
2022-02-28
16:54:00.000 20
0
6
14
Within day clipping:
And not correctly bounding for multi-days, this data:
FROM VALUES
('2022-02-28 16:54:00.000'::timestamp, 20),
('2022-02-28 7:54:00.000'::timestamp, 20),
('2022-02-28 6:54:00.000'::timestamp, 1000)
t(start_time, minutes)
gives:
START_TIME
MINUTES
TIME_PRE_WORK
WORK_TIME
POST_WORK_TIME
2022-02-28
16:54:00.000
20
0
6
2022-02-28
07:54:00.000
20
6
14
2022-02-28
06:54:00.000
1,000
66
540
Across days with daily clipping:
WITH input_data as (
SELECT * FROM VALUES
('2022-02-28 16:54:00.000'::timestamp, 20),
('2022-02-28 7:54:00.000'::timestamp, 20),
('2022-02-28 6:54:00.000'::timestamp, 3000)
t(start_time, minutes)
), range as(
SELECT row_number() over(order by null)-1 as rn
FROM TABLE(generator(ROWCOUNT => 100))
), day_condition as (
SELECT *
,timeadd('minute', minutes, start_time) as time_end
,date_trunc('day', dateadd('day', r.rn, start_time)) as r_day_start
,dateadd('day', 1, r_day_start ) as r_day_end
,greatest(r_day_start, start_time) as clip_start
,least(r_day_end, time_end) as clip_end
-- insert logic for "which day is it and what hours it has here"
,timeadd('hour', 8, r_day_start) as workday_start
,timeadd('hour', 17, r_day_start) as workday_end
FROM input_data i
JOIN range r ON r.rn <= datediff(day, start_time, timeadd('minute', minutes, start_time))
)
SELECT
start_time
,minutes
,r_day_start
--,clip_start
--,clip_end
,timediff('minute', least(clip_start, workday_start), workday_start) as time_pre_work
,timediff('minute', greatest(clip_start, workday_start), least(workday_end, clip_end)) as work_time
,timediff('minute', greatest(workday_end, workday_end), greatest(workday_end, clip_end)) as post_work_time
FROM day_condition
ORDER BY 1,3;
START_TIME
MINUTES
R_DAY_START
TIME_PRE_WORK
WORK_TIME
POST_WORK_TIME
2022-02-28 06:54:00.000
3,000
2022-02-28 00:00:00.000
66
540
420
2022-02-28 06:54:00.000
3,000
2022-03-01 00:00:00.000
480
540
420
2022-02-28 06:54:00.000
3,000
2022-03-02 00:00:00.000
480
54
0
2022-02-28 07:54:00.000
20
2022-02-28 00:00:00.000
6
14
0
2022-02-28 16:54:00.000
20
2022-02-28 00:00:00.000
0
6
14
I couldn't think of a way to approach this using built in date functions, so this is maybe not the prettiest solution, but the math is there. This converts the start_timestamp/active_time into minutes relative to your business hours
I subtracted 540 to essentially set the time 9:00AM to "minute 0" to make the numbers easier to work with. This makes 5:00PM "minute 480"
Then it's just a matter of subtracting times within and outside of your business hours.
set startdatetime = '2022-03-23 7:31:00'::timestamp_ntz;
set active_minutes = 125;
set business_start = 0;
set business_end = 480;
select
-540 + (hour($startdatetime) * 60 + minute($startdatetime)) as start_minute,
start_minute + $active_minutes as end_minute,
-- End time (within business hours) - Start time (within business hours). Can't be less than 0
greatest(0, least(end_minute, $business_end) - greatest(start_minute, $business_start)) as minutes_during_business,
-- End - Start. With any "business minutes" ignored. first for pre-work minutes, then for post-work minutes
least(end_minute, $business_start) - least(start_minute, $business_start)
+ greatest(end_minute, $business_end) - greatest(start_minute, $business_end) as minutes_outside_business,
minutes_during_business / 60 as hours_during_business,
minutes_outside_business / 60 as hours_outside_business;
;
This does not work well if your active minutes spans into business hours of the following day. That would take some extra handling.
You could also add on seconds, and convert all of the hardcoded numbers to seconds if you do want that extra granularity.

Time Difference between two time columns in sql server

I have the issue in getting the minutes difference between two time columns in sql server.
Column1: Starttime
Column2: Endtime
These two are of the type nchar(10) , I converted them into time format in the below way and using the datediff function.
If the two columns have AM format or PM format, then difference of minutes is coming fine. But if i have start time is in PM format and End time as AM (SQL taking it as next day) format then i am getting negative minutes than expected.
select
dty_act_start_time,
dty_act_end_time,
datediff(minute, convert(varchar,dty_act_start_time,114),convert(varchar,dty_act_end_time,114))
from DB.Mydatabase;
Please let me know how to get the correct difference in minutes.
Just add 1440 minutes (number of minutes in 24 hours) if start time is greater than end time:
select
start_time_time,
end_time_time,
datediff(minute, start_time_time, end_time_time) + iif(start_time_time <= end_time_time, 0, 1440) as diff
from (
select
convert(time(0), dty_act_start_time, 114) as start_time_time,
convert(time(0), dty_act_end_time, 114) as end_time_time
from (values
('09:00am', '10:00pm'),
('10:00pm', '09:00am')
) tests(dty_act_start_time, dty_act_end_time)
) x
Result:
start_time_time | end_time_time | diff
09:00:00 | 22:00:00 | 780
22:00:00 | 09:00:00 | 660

I want to create a zabbix alert for sending email to users if no report ran in past 2 hrs

We have zabbix setup in our unix system. And report is connected to DB2 Database where zabbix alert is setup.Now I want to write a query which will invoke this alert when no records is seen in the output.
That means query will check if anything ran in past 2 hr and return those record.If nothing is there as output it will invoke alert.
select from_tz(to_timestamp(substr(lastmodifytime,1,19), 'YYYY MM DD HH24 MI
SS'),'GMT') at time zone 'US/Pacific',
objectid, parentid, typeid, ownerID, LastModifyTime
from BODEV.CMS_INFOOBJECTS7 c
where to_date(substr(lastmodifytime,1,19), 'YYYY MM DD HH24 MI SS') >
sysdate - 2/60/60/24
order by lastmodifytime desc;
If your fractional seconds have leading zeroes (i.e. 2019 01 22 13 01 18 002 and not 2019 01 22 13 01 18 2), then ... where lastmodifytime > to_char(current timestamp - 2 hour, 'YYYY MM DD HH24 MI FF3').
Use the line with substr otherwise.
select *
from table(values
to_char(current timestamp - 3 hour, 'YYYY MM DD HH24 MI FF3')
--, to_char(current timestamp - 1 hour, 'YYYY MM DD HH24 MI FF3')
) c (lastmodifytime)
where
lastmodifytime > to_char(current timestamp - 2 hour, 'YYYY MM DD HH24 MI FF3')
--substr(lastmodifytime, 1, 19) > to_char(current timestamp - 2 hour, 'YYYY MM DD HH24 MI')
fetch first 1 row only
optimize for 1 row
;
Uncomment the 2-nd row to have the result indicating that something ran in past 2 hours.

Unable to convert 4 digit int value to 24 hour time format

My input data format is in the form of 4 digit numbers which represent 24 hour time format. I am trying to find the time difference in minutes between 2 such fields - Expected Arrival Time and Scheduled Arrival Time in minutes. For that I need to convert 4 digit int values to 24 hour time format but I am unable to do so.
I have tried innumerable permutations and combinations but to no avail.
Expected Arrival time: 1902
Scheduled Arrival Time: 1806
Expected result: 56
Any help will be highly appreciated.
The difference between these two times are 56 minutes.
Expected Arrival time: 1902 (07:02 PM) //2 minutes from 7:00PM
Scheduled Arrival Time: 1806 (06:06 PM) //54 minutes to 7:00PM
select (unix_timestamp('1902','HHmm') - unix_timestamp('1806',"HHmm"))/60;
+-------+--+
| _c0 |
+-------+--+
| 56.0 |
+-------+--+
(or)
select int((unix_timestamp('1902','HHmm') - unix_timestamp('1806',"HHmm"))/60);
+------+--+
| _c0 |
+------+--+
| 56 |
+------+--+
(t2 / 100) * 60 + t2 % 100
- (t1 / 100) * 60 - t1 % 100
+ case when t2 < t1 then 1440 else 0 end
I'm assuming that the two times can span midnight.