object
iso8601
ISO 8601 (and European civil calendar) compliant library of date predicates.
logtalk_load(iso8601(loader))
static, context_switching_calls
Scope: This object currently provides a powerful, versatile and efficient set of date-handling predicates, which–thanks to Logtalk–may be used as is on a wide range of Prolog compilers. Besides taking time to familiarize oneself with each predicate, the user should take note of the following information.
Validation of dates: Date parts are not validated–that is the caller’s responsibility! However, not being quite heartless yet, we do provide a predicate for this purpose.
Date arithmetic: Many of the examples illustrate a simplified method of doing date arithmetic. Note, however, that we do not generally recommend this practice–it is all too easy to make mistakes. The safest way of finding the day difference between two dates is to first convert the dates to their Julian day numbers and then subtract one from the other. Similarly, the safe way to add or subtract a day offset to a particular date is to first convert the date to its Julian day number, add or subtract the day offset, and then convert the result to its corresponding date.
BC years: ISO 8601 specifies that the Gregorian calendar be used, yet requires that years prior to 1 AD be handled arithmetically, i.e., the year we know as 1 BC is year 0, 2 BC is year -1, 3 BC is year -2 and so on. We do not follow ISO 8601 with regard to the handling of BC years. Our date predicates will accept and interpret an input year 0 as 1 BC; however, a negative year, Year, should always be interpreted as
abs(Year) =:= Year BC
. We believe that the average person will find our handling of BC years more user-friendly than the ISO 8601 one, but we encourage feedback from users with a view to a possible change in future versions.Week numbers: It is possible for a day (date) to have a week number that belongs to another year. Up to three of the first days of a calendar year may belong to the last week (number) of the prior calendar year, and up to three days of the last days of a calendar year may belong to the first week (number) of the next calendar year. It for this reason that the Week parameter in
date/6-7
is a compound term, namelyweek(WeekNo,ActualYear)
.Computation of Gregorian Easter Sunday: The algorithm is based upon the “Gaussian rule”. Proleptic use is limited to years > 1582 AD, that is, after the introduction of the Gregorian calendar.
Some Christian feast day offsets from Easter Sunday: Carnival Monday: -48 days, Mardi Gras (Shrove Tuesday): -47 days, Ash Wednesday: -46 days, Palm Sunday: -7 days, Easter Friday: -2 days, Easter Saturday: -1 day, Easter Monday: +1 day, Ascension of Christ: +39 days, Whitsunday: +49 days, Whitmonday: +50 days, Feast of Corpus Christi: +60 days.
Public predicates
date/4
Get the system date and/or its Julian Day # or convert a Julian Day # to/from given date parts.
static
date(JD,Year,Month,Day)
JD
- Julian day serial number.Year
- 0 or negative if converted BC year, positive otherwise.Month
- Normally an integer between 1 and 12 inclusive.Day
- Normally an integer between 1 and 31 inclusive depending upon month.date(?integer,?integer,?integer,?integer)
- zero_or_one
date(JD,Year,Month,Day)
JD=2453471,Year=2005,Month=4,Day=10
date(JD,2000,2,29)
JD=2451604
date(2451604,Year,Month,Day)
Year=2000,Month=2,Day=29
date(JD,2000,1,60)
JD=2451604
date(JD,2000,1,0)
JD=2451544
date(JD,2000,1,-59)
JD=2451485
date(JD,1900,2,29)
JD=2415080
date(2415080,Year,Month,Day)
Year=1900,Month=3,Day=1
date/5
Ditto date/4
+ get/check its day-of-week #.
static
date(JD,Year,Month,Day,DoW)
JD
- Julian day serial number.Year
- 0 or negative if converted BC year, positive otherwise.Month
- Normally an integer between 1 and 12 inclusive.Day
- Normally an integer between 1 and 31 inclusive depending upon month.DoW
- Day of week, where Monday=1, Tuesday=2, …, Sunday=7.date(?integer,?integer,?integer,?integer,?integer)
- zero_or_one
date(JD,2000,2,29,DoW)
JD=2451604,DoW=2
date(_,2002,3,5,4)
no
date(JD,2004,2,29,7)
JD=2453065
date(2451545,Year,Month,Day,DoW)
Year=2000,Month=1,Day=1,DoW=6
date/6
Ditto date/5
+ get/check its week #.
static
date(JD,Year,Month,Day,DoW,Week)
JD
- Julian day serial number.Year
- 0 or negative if converted BC year, positive otherwise.Month
- Normally an integer between 1 and 12 inclusive.Day
- Normally an integer between 1 and 31 inclusive depending upon month.DoW
- Day of week, where Monday=1, Tuesday=2, …, Sunday=7.Week
- Compound term, week(WeekNo,ActualYear)
, of a day.date(?integer,?integer,?integer,?integer,?integer,?compound)
- zero_or_one
date(_,2000,1,1,DoW,Week)
DoW=6,Week=week(52,1999)
date(_,_,_,_,_,Week)
Week=week(7,2004)
date(JD,2004,2,29,7,Week)
JD=2453065,Week=week(9,2004)
date(2453066,_,_,_,DoW,Week)
DoW=1,Week=week(10,2004)
date(_,2004,3,1,1,week(10,2004))
yes
date(_,Year,Month,Day,DoW,week(26,2004))
Year=2004,Month=6,Day=21,DoW=1
date(_,Year,Month,Day,7,week(1,2005))
Year=2005,Month=1,Day=9
date(_,Year,Month,Day,9,week(1,2005))
Year=2005,Month=1,Day=11
date(_,Year,Month,Day,4,week(0,2005))
Year=2004,Month=12,Day=30
date(_,Year,Month,Day,2,week(-1,2005))
Year=2004,Month=12,Day=21
date(_,Year,Month,Day,6,week(53,2004))
Year=2005,Month=1,Day=1
date(_,Year,Month,Day,1,week(60,2004))
Year=2005,Month=2,Day=14
date/7
Ditto date/6
+ get/check its day-of-year #.
static
date(JD,Year,Month,Day,DoW,Week,DoY)
JD
- Julian day serial number.Year
- 0 or negative if converted BC year, positive otherwise.Month
- Normally an integer between 1 and 12 inclusive.Day
- Normally an integer between 1 and 31 inclusive depending upon month.DoW
- Day of week, where Monday=1, Tuesday=2, …, Sunday=7.Week
- Compound term, week(WeekNo,ActualYear)
, of a day.DoY
- Day of year (NB! calendar year, not week # year).date(?integer,?integer,?integer,?integer,?integer,?compound,?integer)
- zero_or_one
date(2451649,Year,Month,Day,_,_,DoY)
Year=2000,Month=4,Day=14,DoY=105
date(JD,2004,2,29,7,Week,DoY)
JD=2453065,Week=week(9,2004),DoY=60
date(_,2004,3,1,_,_,61)
yes
date(JD,2004,10,18,DoW,_,DoY)
JD=2453297,DoW=1,DoY=292
date(_,_,_,_,_,_,DoY)
DoY=54
date(_,2004,Month,Day,DoW,Week,60)
Month=2,Day=29,DoW=7,Week=week(9,2004)
date(_,2004,3,Day,DoW,Week,61)
Day=1,DoW=1,Week=week(10,2004)
date(_,2004,_,2,_,_,61)
no
date_string/3
Conversion between an ISO 8601 compliant date string and its components (truncated and expanded date representations are currently unsupported). Note that date components are not validated; that is the caller’s responsibility!
static
date_string(Format,Components,String)
Format
- ISO 8601 format.Components
- When bound and String is free, either a Julian number or a [Year,Month,Day]
term; it binds to the system day/date if free When free and String is bound, it binds to an integer list representing the numeric elements of String.String
- ISO 8601 formatted string correspondent to Components.date_string(+atom,+integer,?atom)
- zero_or_one
date_string(+atom,?list,?atom)
- zero_or_one
date_string('YYYYMMDD',[2004,2,29],String)
String='20040229'
date_string('YYYYMMDD',Components,'20040229')
Components=[2004,2,29]
date_string('YYYY-MM-DD',[2003,12,16],String)
String='2003-12-16'
date_string('YYYY-MM-DD',Components,'2003-12-16')
Components=[2003,12,16]
date_string('YYYY-MM-DD',_,String)
String='2004-02-17'
date_string('YYYY-MM-DD',Components,'2004-02-17')
Components=[2004,2,17]
date_string('YYYY-MM',[2004,9,18],String)
String='2004-09'
date_string('YYYY-MM',Components,'2004-09')
Components=[2004,9]
date_string('YYYY',[1900,7,24],String)
String='1900'
date_string('YYYY',Components,'1900')
Components=[1900]
date_string('YY',2456557,String)
String='20'
date_string('YY',Components,'20')
Components=[20]
date_string('YYYYDDD',[2005,3,25],String)
String='2005084'
date_string('YYYYDDD',Components,'2005084')
Components=[2005,84]
date_string('YYYY-DDD',[1854,12,4],String)
String='1854-338'
date_string('YYYY-DDD',Components,'1854-338')
Components=[1854,338]
date_string('YYYYWwwD',[2000,1,2],String)
String='1999W527'
date_string('YYYYWwwD',Components,'1999W527')
Components=[1999,52,7]
date_string('YYYY-Www-D',[2003,12,29],String)
String='2004-W01-1'
date_string('YYYY-Www-D',Components,'2004-W01-1')
Components=[2004,1,1]
date_string('YYYY-Www-D',2453167,String)
String='2004-W24-4'
date_string('YYYY-Www-D',Components,'2004-W24-4')
Components=[2004,24,4]
date_string('YYYYWww',[2004,2,29],String)
String='2004W09'
date_string('YYYYWww',Components,'2004W09')
Components=[2004,9]
date_string('YYYY-Www',[2004,2,29],String)
String='2004-W09'
date_string('YYYY-Www',Components,'2004-W09')
Components=[2004,9]
valid_date/3
Validate a given date in the Gregorian calendar.
static
valid_date(Year,Month,Day)
valid_date(+integer,+integer,+integer)
- zero_or_one
valid_date(2000,2,29)
yes
valid_date(2004,2,29)
yes
valid_date(2004,4,31)
no
valid_date(-1,2,29)
yes
leap_year/1
Succeed if given year is a leap year in the Gregorian calendar.
static
leap_year(Year)
Year
- The Gregorian calendar year to investigate. If free, it binds to the system year.leap_year(?integer)
- zero_or_one
leap_year(1900)
no
leap_year(2000)
yes
leap_year(Year)
Year=2004
leap_year(_)
yes
leap_year(2100)
no
leap_year(0)
yes
leap_year(-1)
yes
leap_year(-4)
no
leap_year(-5)
yes
calendar_month/3
Compute a calendar month.
static
calendar_month(Year,Month,Calendar)
Year
- The calendar year.Month
- The calendar month.Calendar
- A compound term, m/3
, composed of three main arguments specifying year, month, and a list of week and week day numbers (calendar body).calendar_month(?integer,?integer,-compound)
- zero_or_one
calendar_month(2005,3,Calendar)
Calendar=m(2005,3,[w(9,[0,1,2,3,4,5,6]),w(10,[7,8,9,10,11,12,13]),w(11,[14,15,16,17,18,19,20]),w(12,[21,22,23,24,25,26,27]),w(13,[28,29,30,31,0,0,0]),w(0,[0,0,0,0,0,0,0])])
easter_day/3
Compute a Gregorian Easter Sunday.
static
easter_day(Year,Month,Day)
Year
- Integer specifying the year to be investigated.Month
- Month in which Easter Sunday falls for given year.Day
- Day of month in which Easter Sunday falls for given year.easter_day(?integer,-integer,-integer)
- zero_or_one
easter_day(2006,Month,Day)
Month=4,Day=16
easter_day(Year,Month,Day)
Year=2005,Month=3,Day=27
Protected predicates
(no local declarations; see entity ancestors if any)
Private predicates
(no local declarations; see entity ancestors if any)
Operators
(none)