PDA

View Full Version : Date calculations



J.Wells
04-03-2002, 07:14 AM
Keith, I do not know if this will hellp or not, but you can use the SUBDUR opcode to calculate the difference between two dates (or times, or timestamps). Maybe you could build two timestamps from the existing fields and then calculate the total elapsed seconds <pre> C TIMESTAMP2 SUBDUR TIMESTAMP1 SECONDS:*S </pre> and convert the result to the desired format? This seems kind of "convoluted" too, but maybe it will spur another idea! Joe

Guest.Visitor
04-03-2002, 07:32 AM
To be sure, books have been written on Dates and Date-time durations. It depends on what you mean by duration; say the 'from' is 11:30 pm on Dec 31, 1900 and the 'to' is some time in january 1901. Are you going to say the Year part of duration is 1 = 1901 - 1900 et c. What are you going to do with the duration, once you have it? might be something to consider. bobh

Guest.Visitor
04-03-2002, 07:35 AM
I've written a utility program like this before. You need to drill down. Construct a "from" timestamp and a "to" timestamp. Compute the difference in years with SUBDUR, then substract the difference in years from the "to" timestamp (more recent timestamp) with SUBDUR. Then repeat for months, days, hours, minutes, seconds. Chris

kgaskill@unifi.com
04-04-2002, 05:04 AM
Chris, Your technique is exactly what I used to derive results. It just seems that there may be an easier way. I'm actually reporting hours and minutes. Here is my code: "Fromdate"/ "Fromtime" and "Todate"/ "Totime" are fields coming into the program defined as date and time fields. __________________________________________________ ____ DRslt S 5 0 DRslthours S 5 0 DRsltminutes S 2 0 Eval Rslthours = *zeros Eval Rsltminutes = *zeros Fromdate Iflt Todate Todate Subdur Fromdate Rslt:*d Eval Rslthours = Rslt * 24 Endif Tottime Subdur Fromtime Rslt:*mn If Rslt < *Zeros Eval Rslt = Rslt * -1 Eval Rslthours = Rslthours - (Rslt / 60) Eval Rsltminutes = %rem(rslt:60) Else Eval Rslthours = Rslthours + (Rslt / 60) Eval Rsltminutes = %rem(rslt:60) Endif O Rslthours Z 94 O 95 ':' O Rsltminutes 97 _________________________________________________ A thought I had would be to combine "from" date and time fields into a timestamp and "to" date and time fields into a timestamp to make the code somewhat less complicated. Does this sound doable? Constructive criticism is always welcomed. Thank you for your response. Keith

kgaskill@unifi.com
04-04-2002, 05:56 AM
Chris, Tottime should be Totime. Sorry. Keith

Guest.Visitor
04-04-2002, 09:33 AM
Keith - If you're looking for number of hours and minutes difference, I think the following will work: Hdebug Dtimenow s t inz(*sys) Dtimethen s t inz(T'16.30.27') Ddatenow s d inz(*sys) Ddatethen s d inz(D'2002-02-27') Dmin s 10i 0 Dtotalmin s 10i 0 Ddays s 10i 0 Dhrs s 10i 0 C timenow subdur timethen min:*mn C datenow subdur datethen days:*d C eval totalmin = days * 1440 + min C eval hrs = %div(totalmin:60) C eval min = %rem(totalmin:60) C dump C eval *inlr = *on

kgaskill@unifi.com
04-04-2002, 10:28 AM
Chris, Just determined that the minutes field is wrong if the "from" date is less than the "to" date. I'm in the process of re-writing. Don't put to much stock in the code above. It stinks. Thanks, Keith

Guest.Visitor
04-04-2002, 01:31 PM
For just hours and minutes, I'd do this: <pre> D FromDate s 8s 0 Inz(20020101) D FromTime s 6s 0 Inz(153045) D ToDate s 8s 0 Inz(20020404) D ToTime s 6s 0 Inz(172600) * D ds D StampThen z D DateThen d DatFmt(*iso) Overlay(StampThen:1) D TimeThen t DatFmt(*iso) Overlay(StempThen:12) D ds D StampNow z D DateNow d DatFmt(*iso) Overlay(StampNow:1) D TimeNow t DatFmt(*iso) Overlay(StampNow:12) * D Min s 10i 0 D Sec s 10i 0 * C *iso move FromDate DateThen C *iso move FromTime TimeThen C *iso move ToDate DateNow C *iso move ToTime TimeNow * C StampNow subdur StampThen Min:*mn C StampNow subdur Min:*Mn StampNow C StampNow subdur StampThen Sec:*s</pre> Chris Ringer

Guest.Visitor
04-05-2002, 03:26 AM
Oops...the durations in my example should be hours and minutes, not minutes and seconds. Chris

Guest.Visitor
04-05-2002, 07:04 AM
Chris - I like the three-step timestamp approach. Don't you have to initialize the timestamps in order to get the microseconds portion filled? Bill

Guest.Visitor
04-05-2002, 07:45 AM
Bill, Good catch. Yes, add an 'Inz' on the 'Z' definitions in the data structures. I typed the example from memory, not copy/paste.<pre>D StampThen z Inz(*LoVal)</pre>Thanks, Chris

kgaskill@unifi.com
04-05-2002, 08:32 AM
Using fields "fromdate", "fromtime, "todate", "totime, defined as date and time fields, I have a need to determine lapsed time between the "from" and the "to" and report it as y/m/d/h/m. It would seem that the new RPG IV date/time operations would allow it, but I can't seem to find a good fit. I wrote code to handle, but it is very convoluted and I'm not proud of it. Any suggestions would be appreciated. We are currently on V4.5 Thanks, Keith

kgaskill@unifi.com
04-05-2002, 08:32 AM
All, Your input greatly appreciated. Used a combination of examples plus some suggestions from one of my co-workers and came up with the following. Works great. Thanks again. ________ ...(Tomdy, Totime), (Frmdy, Frtime) are date and time fields (respectively) coming in from file. D DS DTodate Z Inz(*sys) D Toymdy D Overlay(Todate:1) D Totime T Overlay(Todate:12) D DS DFrdate Z Inz(*sys) D Frmdy D Overlay(Frdate:1) D Frtime T Overlay(Frtime:12) DHours S 5 0 DMinutes S 2 0 DDiff S 8 0 C Frdate Subdur Todate Hours:*h C Subdur Hours:*h Frdate C Frdate Subdur Todate Minutes:*mn C Eval Diff=%Char(Hours) + ':' + %editc (Minutes:'x')