Difference in minutes between 2 dates and times? - date

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.

Related

How can I find the difference in hours between 2 times in character arrays?

I have 2 times stored in character arrays in MATLAB.
a = '11:00 PM'
b = '07:30 AM'
I want to find the difference in hours between the 2 times, which should be 8.5 hours in this example. Is there any short method to do that? I can datenum both numbers, subtract them, datevec the difference, extract the hours and minutes from the vector, and convert them into hours, but this takes a lot of lines. Is there a more efficient way of doing this or is there an existing function?
You can do this by converting each string using datetime, taking the difference, then converting the result with hours:
numHours = hours(diff(datetime({a; b}, 'InputFormat', 'hh:mm a')));
numHours = numHours + 24.*(numHours < 0)
numHours =
8.5000
The second line accounts for the condition in your example, where the second time has to occur on the next day for the time difference to be positive, so 24 hours are added to the (negative) difference.
add a date to the time
like
a = '1/1/2000 11:00 PM'
b = '1/1/2000 07:30 AM'
the convert the string to datetime
x=str2num(strrep(a,':',''))
y=str2num(strrep(b,':',''))
then fine the difference between 2 dates
e = etime(x,y)
this will give you number of seconds between both times

Converting time to milliseconds?

I have some time as string format in my data. Can anyone help me to convert this date to milliseconds in Matlab.
This is an example how date looks like '00:26:16:926', So, that is 0 hours 26 minutes 16 seconds and 926 milliseconds. After converting this time, I need to get only milliseconds such as 1576926 milliseconds for the time that I gave above. Thank you in advance.
Why don't you try using datevec instead? datevec is designed to take in various time and date strings and it parses the string and spits out useful information for you. There's no need to use regexp or split up your string in any way. Here's a quick example:
[~,~,~,hours,minutes,seconds] = datevec('00:26:16:926', 'HH:MM:SS:FFF');
out = 1000*(3600*hours + 60*minutes + seconds);
out =
1576926
In this format, the output of datevec will be a 6 element vector which outputs the year, month, day, hours, minutes and seconds respectively. The millisecond resolution will be added on to the sixth element of datevec's output, so all you have to do is convert the fourth to sixth elements into milliseconds and add them all up, which is what is done above. If you don't specify the actual day, it just defaults to January 1st of the current year... but we're not using the date anyway... we just want the time!
The beauty with datevec is that it can accept multiple strings so you're not just limited to a single input. Simply put all of your strings into a single cell array, then use datevec in the following way:
times = {'00:26:16:926','00:27:16:926', '00:28:16:926'};
[~,~,~,hours,minutes,seconds] = datevec(times, 'HH:MM:SS:FFF');
out = 1000*(3600*hours + 60*minutes + seconds);
out =
1576926
1636926
1696926
One solution could be:
timeString = '00:26:16:926';
cellfun(#(x)str2num(x),regexp(timeString,':','split'))*[3600000;60000;1000;1]
Result:
1576926
Assuming that your date string comes in that format consistently, you could use something as simple as this:
test = '00:26:16:926';
H = str2num(test(1:2)); % hours
M = str2num(test(4:5)); % minutes
S = str2num(test(7:8)); % seconds
MS = str2num(test(10:12)); % milliseconds
totalMS = MS + 1000*S + 1000*60*M + 1000*60*60*H;
Output:
1576926.00
you can convert a single string with a date or even a vector by using datevec for conversion and the dot product
a = ['00:26:16:926' ; '08:42:12:936']
datevec(a,'HH:MM:SS:FFF') * [0 0 0 3600e3 60e3 1e3]'
ans =
1576926
31332936

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);

subtracting one from another in matlab

My time comes back from a database query as following:
kdbstrbegtime =
09:15:00
kdbstrendtime =
15:00:00
or rather this is what it looks like in the command window.
I want to create a matrix with the number of rows equal to the number of seconds between the two timestamps. Are there time funcitons that make this easily possible?
Use datenum to convert both timestamps into serial numbers, and then subtract them to get the amount of seconds:
secs = fix((datenum(kdbstrendtime) - datenum(kdbstrbegtime)) * 86400)
Since the serial number is measured in days, the result should be multiplied by 86400 ( the number of seconds in one day). Then you can create a matrix with the number of rows equal to secs, e.g:
A = zeros(secs, 1)
I chose the number of columns to be 1, but this can be modified, of course.
First you have to convert kdbstrendtime and kdbstrbegtime to char by datestr command, then:
time = datenum(kdbstrendtime )-datenum(kdbstrbegtime )
t = datestr(time,'HH:MM:SS')

Vectorising Date Array Calculations

I simply want to generate a series of dates 1 year apart from today.
I tried this
CurveLength=30;
t=zeros(CurveLength);
t(1)=datestr(today);
x=2:CurveLength-1;
t=addtodate(t(1),x,'year');
I am getting two errors so far?
??? In an assignment A(I) = B, the number of elements in B and
Which I am guessing is related to the fact that the date is a string, but when I modified the string to be the same length as the date dd-mmm-yyyy i.e. 11 letters I still get the same error.
Lsstly I get the error
??? Error using ==> addtodate at 45
Quantity must be a numeric scalar.
Which seems to suggest that the function can't be vectorised? If this is true is there anyway to tell in advance which functions can be vectorised and which can not?
To add n years to a date x, you do this:
y = addtodate(x, n, 'year');
However, addtodate requires the following:
x must be a scalar number, not a string.
n must be a scalar number, not a vector.
Hence the errors you get.
I suggest you use a loop to do this:
CurveLength = 30;
t = zeros(CurveLength, 1);
t(1) = today; % # Whatever today equals to...
for ii = 2:CurveLength
t(ii) = addtodate(t(1), ii - 1, 'year');
end
Now that you have all your date values, you can convert it to strings with:
datestr(t);
And here's a neat one-liner using arrayfun;
datestr(arrayfun(#(n)addtodate(today, n, 'year'), 0:CurveLength))
If you're sequence has a constant known start, you can use datenum in the following way:
t = datenum( startYear:endYear, 1, 1)
This works fine also with months, days, hours etc. as long as the sequence doesn't run into negative numbers (like 1:-1:-10). Then months and days behave in a non-standard way.
Here a solution without a loop (possibly faster):
CurveLength=30;
t=datevec(repmat(now(),CurveLength,1));
x=[0:CurveLength-1]';
t(:,1)=t(:,1)+x;
t=datestr(t)
datevec splits the date into six columns [year, month, day, hour, min, sec]. So if you want to change e.g. the year you can just add or subtract from it.
If you want to change the month just add to t(:,2). You can even add numbers > 12 to the month and it will increase the year and month correctly if you transfer it back to a datenum or datestr.