how to split a duration by hourly basis depending on start and end time in postgres? - postgresql

How can I split a duration by one hour interval depending on the start time and end time?
Like, if start time = 6:30:00 and end time = 8:30:00 then from 6.30 to 7.30 it will give h1, 7.30 to 8.30 it will give h2 n all.. Tried with dense_rank but didn't work.. Can anyone plz help?
I need to have hour_of_shift h1,h2... like this..with time key 0630 to 0730 it will give h1 and so on..
tried with this query
select td.time_key tdkey, shft.shid shid,
('h' || DENSE_RANK() OVER ( ORDER BY substr(time_key, 1, 2))) hour_of_shift
from smartweld_sample_dev4.time_dim td,
smartweld_sample_dev4.shift shft
where td.timeofday::time between shft.START and shft.END;
but it is giving h1 for 6.30 to 7.00 and then it is increasing the rank by one.how can can do that?

Related

How to get Number of days between 2 dates when specific condition is met?

I want to get the number of days between two dates based on specific condition, here is the image illustration of what I am talking about:
I need to devise a formula to calculate number of days from dates (column C) it takes ID = 1 to reach from L1 to L2 , so ideally the output for ID = 1 should be:
L1 : 0
L2 : 2022-07-14 - 2022-07-06 = 8
Same for other ids (2,3). I am just a beginner trying to learn, so I apologize for my ordinary question. Thank you
DAYS will give you the day count between dates. try:
=DAYS(SINGLE(FILTER(C:C; B:B="L2"; A:A=1));
SINGLE(FILTER(C:C; B:B="L1"; A:A=1)))
=DAYS(SINGLE(FILTER(C:C; B:B="L2"; A:A=2));
SINGLE(FILTER(C:C; B:B="L1"; A:A=2)))
=DAYS(SINGLE(FILTER(C:C; B:B="L2"; A:A=3));
SINGLE(FILTER(C:C; B:B="L1"; A:A=3)))

Shift time series to start from zero H:M:S:MS (possibly in Matlab)

I have some ECG data for a number of subjects. For each subject, I can export an excel file with the RR interval, Heart Rate and other measures. The problem is that I have a timestamp starting at the time of recording (in this case 11:22:3:00).
I need to compare the date with other subjects and I want to automate the procedure in Matlab.
I need to flexibly compare, for instance, the first 3 minutes of subjects in condition 1 with those of sbj in condition 2. Or minutes 4 to 8 of condition 1 and 2 and so forth. To do this, I am thinking that the best way is to shift the time vector for each subject so that it starts from 0.
There are a couple of problems to note: I CANNOT create just one vector for all subjects. This would be inaccurate because the heart measures are variable for each individual.
So, IN SHORT I need to shift the time vector for each participant so that it starts at 0 and increases exactly like the original one. So, in this example:
H: M: S: MS RR HR
11:22:03:000 0.809 74.1
11:22:03:092 0.803 74.7
11:22:03:895 0.768 78.1
11:22:04:663 0.732 81.9
11:22:05:395 0.715 83.9
11:22:06:110 0.693 86.5
11:22:06:803 0.705 85.1
11:22:07:508 0.706 84.9
11:22:08:214 0.749 80.1
11:22:08:963 0.762 78.7
11:22:09:725 0.766 78.3
would become:
00:00:00:0000
00:00:00:092
00:00:00:895
00:00:01:663
and so forth...
I would like to do it in Matlab...
P.S.
I was working around the idea of extracting the info in 4 different variables.
Then, I could subtract the values for each cell from the first cell.
For instance:
11-11 = 0; 22-22=0; 03-03=0; ms: keep the same value
Maybe this could kind of work, except that it wouldn't if I have a subject that started, say, at 11:55:05:00
Thank you all for any help.
Gluce
Basic timestamp normalization just subtracts the minimum (or first, assuming they're properly ordered) time from the rest.
With MATLAB's datetime object, this is just subtraction, which yields a duration object:
ts = ["11:22:03:000", "11:22:03:092", "11:22:03:895", "11:22:04:663"];
% Convert to datetime & normalize
t = datetime(ts, 'InputFormat', 'HH:mm:ss:SSS');
t.Format = 'HH:mm:ss:SSS';
nt = t - t(1);
% Reformat & display
nt.Format = 'hh:mm:ss.SSS';
Which returns:
>> nt
nt =
1×4 duration array
00:00:00.000 00:00:00.092 00:00:00.895 00:00:01.663
Alternatively, you can normalize the datetime array itself:
ts = ["11:22:03:000", "11:22:03:092", "11:22:03:895", "11:22:04:663"];
t = datetime(ts, 'InputFormat', 'HH:mm:ss:SSS');
t.Format = 'HH:mm:ss:SSS';
[h, m, s] = hms(t);
[t.Hour, t.Minute, t.Second] = deal(h - h(1), m - m(1), s - s(1));
Which returns the same:
>> t
t =
1×4 datetime array
00:00:00:000 00:00:00:092 00:00:00:895 00:00:01:663

Creating category to show hours as a KPI

Need help with calculation in Tableau. I have field as priority High, Medium and Low.
For High and medium i have the TAT as 2 hours and for low it is 4 hours.
I need to add a calculation which for each ticket based on their priority level shows respective priority hours as either 2 or 4 hours.
I have added a calculation :
if [Priority]= "High" then "2 Hours"
ELSEIF [Priority]= "Medium" then "2 Hours"
ELSE "4 Hours"
END
however this is a string whereas i need it in hour format so that i can add a flag whether ticket missed or met the SLA.
This i would do basis another column which is time taken to acknowledge.
Let’s consider Start Time = 07/06/2017 5:30:00 AM and End Time = 07/06/2017 8:40:00 AM
Create a calculated field (time_diff_seconds) to calculate time difference between start & end time
(DATEDIFF('hour’,[Start Time],[End Time]) * 3600) + (DATEDIFF(‘minute’,[Start Time],[End Time]) * 60) + DATEDIFF(’second’,[Start Time],[End Time])
Now coming back to your calculated field (SLA_seconds) definition, I would modify it to look something like:
IF [Priority]= "High" then 2*3600
ELSEIF [Priority]= "Medium" then 2*3600
ELSE 4*3600
END
Then finally create your flag as another calculated field i.e. SLA_met
IF time_diff_seconds <= SLA_seconds THEN “Y”
ELSE “N”
END
Hope this helps! Pls don't forget to mention if it solves your problem :)

timestamp to milliseconds conversion around midnight getting messed up

I am using following function to convert timestamp in format (e.g.) 02:49:02.506 to milliseconds in perl.
sub to_millis {
my( $hours, $minutes, $seconds, $millis) = split /:/, $_[0];
$millis += 1000 * $seconds;
$millis += 1000 * 60 * $minutes;
$millis += 1000 * 60 * 60 * $hours;
return $millis;
}
I am then using the milliseconds generated from above routine to calculate the time difference between two timestamps in milliseconds. This works fine all day but gets messed up around midnight, when the timestamp changes to 00:00:00.000. So any logs generated for 1 hr (between 12am to 1am) gets me values in negative for the timestamp difference. Since my timestamp doesn't have a date in it, how do I fix this problem? I am trying to do this on a mobile device, which doesn't have many perl modules installed. So I don't have the liberty of using all the perl modules available.
If you know the ordering of your two timestamps, and if you know that they're no more than 24 hours apart, if you get a negative difference add 24 hours (86,400,000 milliseconds).
If you don't have that information, then you won't be able to distinguish between a 2-minute span and a span of 24 hours and 2 minutes.
I assume that your timestamps will never be more than 23 hours 59 minutes apart?
Let's take two time stamps A and B. I am assuming that A happens before B.
Normally, if A is less than B, I know I can get my time by subtracting A from B. However, in this case, A is bigger than B. I now have to assume that I've wrapped around midnight. What do I do?
I know that the difference between A and B is A going to midnight, PLUS B.
For example, A is 11:58:30 and B is 00:02:00
I know that A will be 90 seconds before midnight, and B will add another 120 seconds to that time. Thus, the total difference will be 90 + 120 = 210 seconds.
Using your routine:
my $midnight = to_millis( "23:59:00:000" ); # Need the time at midnight
my $a_time = to_millis( $a_timestamp );
my $b_time = to_millis( $b_timestamp );
my $time_diff;
if ( $a_time < $b_time ) { # Normal timestamp issue
$time_diff = $b_time - $a_time;
}
else { # We wrapped around midnight!
my $first_part = $midnight - $a_time; # Time from A to midnight
$time_diff = $first_part + $b_time # We add the time from midnite to B
}
You have two timestamps, A and B. If B is always conceptually "after" A but the interval from A to B could cross a date boundary, then do
if (B < A) B+=86400000
and then do the subtraction. Or equivalently
diff = B - A
if (diff < 0) diff+=86400000
If, however you are not guaranteed that B will always be "after" A, you have to decide what is the acceptable range of positive and negative values for the difference. If it's more than half a day you're out of luck, there's no way to solve the problem as you cannot tell if a negative interval represents a real negative interval or a positive one that happened to cross a day boundary.
To handle the wrap around at midnight:
$elapsed_ms = $t2_ms - $t1_ms;
if ($elapsed_ms < 0) $elapsed_ms += (24 * 60 * 60 * 1000);

Difference in minutes between 2 dates and times?

I need to compute time difference in minutes with four input parameters, DATE_FROM, DATE_TO, TIME_FROM, TIME_TO. And one output parameter DIFF_TIME. I have created a function module, I need to write a formula which computes the time diff in minutes.
Any help would be great!
Thanks,
Sai.
Use CL_ABAP_TSTMP=>TD_SUBTRACT to get the number of seconds between two date/time pairs.
(then, to get the number of minutes, divide the number of seconds by 60).
Example:
DATA(today_date) = CONV d( '20190704' ).
DATA(today_time) = CONV t( '000010' ).
DATA(yesterday_date) = CONV d( '20190703' ).
DATA(yesterday_time) = CONV t( '235950' ).
cl_abap_tstmp=>td_subtract(
EXPORTING
date1 = today_date
time1 = today_time
date2 = yesterday_date
time2 = yesterday_time
IMPORTING
res_secs = DATA(diff) ).
ASSERT diff = 20. " verify expectation or short dump
If the values are guaranteed to be in the same time zone, it's easy enough that you don't need any special function module or utility method. Read this, then get the difference of the dates and multiply that by 24 * 60 and get the difference of the times (which is in seconds) and divide that by 60. Sum it up and there you are.