bcs@PRC.Unisys.COM (Barry Silk) (02/07/91)
Could anyone out there in netland please help me out? I'm looking for prolog routines that can do calendar arithmetic. That is, I need routines that can add/subtract an arbitrary number of days to a given date to produce a resultant date. If the calendar arithmetic routines are not available, a routine to convert dates to/from julian dates would be just as useful. Thanks in advance!! --Barry ----------------------------------------------------------------------- Barry Silk bcs@prc.unisys.com Unisys - Center for Advanced Information Technology (215) 648-2509 -----------------------------------------------------------------------
lee@munnari.oz.au (Lee Naish) (02/07/91)
In article <16382@burdvax.PRC.Unisys.COM> bcs@PRC.Unisys.COM (Barry Silk) writes: >Could anyone out there in netland please help me out? I'm looking for >prolog routines that can do calendar arithmetic. I have some NU-Prolog code which might be useful to you. It needs modification for standard Prolog. Dates are represented as strings (eg, "31/12/1991") or structures (eg, date(1991, 12, 31)) more efficient for manipulation/comparison. The code was written with logic and simplicity in mind, rather than efficiency. lee % utilities for handling dates and times % (may change db format for these some time) % subtract a certain number of days from a date % to get a previous date date_minus(Date, ND, PDate) :- date_to_triple(Date, TDate), tdate_minus(TDate, ND, TPDate), date_to_triple(PDate, TPDate). % as above for dates in date(yr, mo, dd) format tdate_minus(date(Y, M, D), ND, date(PY, PM, PD)) :- (if ND < D then % prev day in same month PY = Y, PM = M, PD is D - ND else if M > 1 then % prev month, same year M1 is M - 1, month(M1, _, Y, D1), ND1 is ND - D, tdate_minus(date(Y, M1, D1), ND1, date(PY, PM, PD)) else % prev year Y1 is Y - 1, M1 is 12, month(M1, _, Y1, D1), ND1 is ND - D, tdate_minus(date(Y1, M1, D1), ND1, date(PY, PM, PD)) ). % month numbers, names, year and number of days month(1, "Jan", _, 31). month(2, "Feb", Y, D) :- (if Y mod 4 =:= 0 /* , Y mod 100 =\= 0 */ then % fix! D = 29 else D = 28 ). month(3, "Mar", _, 31). month(4, "Apr", _, 30). month(5, "May", _, 31). month(6, "Jun", _, 30). month(7, "Jul", _, 31). month(8, "Aug", _, 31). month(9, "Sep", _, 30). month(10, "Oct", _, 31). month(11, "Nov", _, 30). month(12, "Dec", _, 31). % convert from/to string date to/from date/3 format % works in both directions (using coroutines) date_to_triple(Date, date(Y, M, D)) :- append(DS, 0'/.MYS, Date), append(MS, 0'/.YS, MYS), intToString(Y, YS), intToString(M, MS), intToString(D, DS). % compare dates date_compare(Date1, Date2, R) :- date_to_triple(Date1, T1), date_to_triple(Date2, T2), termCompare(R, T1, T2). % >= for dates date_ge(Date1, Date2) :- date_compare(Date1, Date2, R), R ~= (<).