Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!samsung!munnari.oz.au!lee From: lee@munnari.oz.au (Lee Naish) Newsgroups: comp.lang.prolog Subject: Re: Need calendar arithmetic code Message-ID: <6687@munnari.oz.au> Date: 7 Feb 91 04:36:24 GMT References: <16382@burdvax.PRC.Unisys.COM> Sender: news@cs.mu.oz.au Reply-To: lee@munmurra.UUCP (Lee Naish) Distribution: na Organization: Comp Sci, University of Melbourne Lines: 79 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 ~= (<).