Note: This is taken from the Chicken Wiki, where a more recent version could be available.
This egg provides a simple interface for calculating lots of useful information about a date. This information can be used for display purposes (eg, displaying a date in various formats), or for complex date arithmetic (eg, finding the third Thursday in July).
Quite simply, it provides a date record type which contains details of the date according to four different calendar systems:
- Julian day number, being the number of days since Monday, January 1, 4713 BC. This is a single integer number of days, so is great for adding and subtracting numbers of days to to find other dates, or comparing the Julian day numbers of two different dates to find how many days they differ by.
- The conventional year/month/day-of-month date. The record also specifies the number of days in the current month.
- The day of the year, starting from January the 1st (day 1) counting upwards until day 365 (or 366 for a leap year). The record specifies whether this is a leap year or not as a boolean, while also specifying the number of days in the current year as an integer, which may be a more useful rendition of the same information.
- The ISO weekdate. This is a slightly unusual one; it represents the date as a year, a week number within the year, and a day number within the week. Because week boundaries and year boundaries need not coincide, this means that the "week-year" boundary may not coincide with the first of January; the last days of December may in the weekdate calendar, count as the first week of the new year, or the first days of January may count as part of the last week of the old year. See http://en.wikipedia.org/wiki/ISO_week_date for further information. The main use of this is to find the day of the week.
Date records may be created from Julian day numbers, or year/month/day-of-month dates. Support for the other two input calendars will hopefully be implemented one day.
(define my-date (make-date-from-ymd 1979 4 4)) ; 4th April 1979
(printf "Julian day number: ~S\n" (date-jdn my-date))
(printf "ISO date: ~S-~S-~S\n" (date-year my-date) (date-month my-date) (date-day-of-month my-date))
(printf "ISO ordinal date: ~S-~S\n" (date-year my-date) (date-day-of-year my-date))
(printf "ISO week date: ~SW~S-~S\n" (date-week-year my-date) (date-week-of-year my-date) (date-day-of-week my-date))
(printf "The month has ~S days, and the year has ~S days\n" (date-days-in-month my-date) (date-days-in-year my-date))
(if (date-leap-year? my-date)
(printf "~S is a leap year\n" (date-year my-date))
(printf "~S is not a leap year\n" (date-year my-date)))
Alaric Blagrave Snell-Pym of Kitten Technologies
Copyright © 2003-2007, Warhead.org.uk Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the names of Warhead.org.uk Ltd, Snell Systems, nor Kitten Technologies, nor the names of their contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
- (make-date-from-ymd YEAR MONTH DAY)
- Creates a date info record for the given date, represented as a year, month number, and day number.
- (make-date-from-ymd-int YYYYMMDD)
- Creates a date info record for the given date, represented as a year times ten thousand, a month numbers times one hundred, plus a day. Eg, 19790404.
- (make-date-from-jdn JDN)
- Creates a date info record for the given date, represented as a julian day number.
- (date? DATE)
- Returns #t if and only if the argument is a date info record.
- (date-jdn DATE)
- Returns the julian day number
- (date-year DATE)
- Returns the normal calendar year
- (date-month DATE)
- Returns the numeric month (1 = January, etc)
- (date-day-of-month DATE)
- Returns the day of the month
- (date-days-in-month DATE)
- Returns the length of the month (including getting the right number of days in February for leap years)
- (date-day-of-year DATE)
- Returns the day of the year (January the 1st is day 1, and it counts up from there)
- (date-days-in-year DATE)
- Returns the number of days in the year (365, or 366 in a leap year)
- (date-leap-year? DATE)
- Returns #t if and only if the year is a leap year
- (date-yyyymmdd DATE)
- Returns the date as a single integer, composed of the year times ten thousand plus the month number times one hundred plus the day.
- (date-week-year DATE)
- Returns the ISO weekdate year
- (date-week-of-year DATE)
- Returns the ISO weekdate week
- (date-day-of-week DATE)
- Returns the ISO weekdate day (Monday is 1, Sunday is 7)
The egg is based around an existing C library I wrote some time ago, which I have included in the scheme source code as embedded C with little modification, so nothing needs to be installed first.
- Rename the record type from date to date-info since too many other things are called date
- Support constructors from the other two calenders: ordinal date (day-of-year) and ISO weekdate
- Provide a weeks-in-year function to get the number of ISO weeks in the ISO weekyear (52 or 53, depending)
- Support other calenders (Julian calendar, Hebrew calendar, Hindu calendar, Islamic calendar, Persion calendar, etc)
- Other pertinent information (what day number / month&day Easter is that year, phase of the moon on the specified day, astronomical information, etc). Since much of that is probably a function of the JDN, perhaps that should be handled as a seperate optional calculation that take a JDN, to avoid wasting time where that level of information is not required.