home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v941.tgz
/
icon.v941src.tar
/
icon.v941src
/
ipl
/
progs
/
daystil.icn
< prev
next >
Wrap
Text File
|
2000-07-29
|
6KB
|
231 lines
############################################################################
#
# File: daystil.icn
#
# Subject: Program to calculate the number of days until a given date
#
# Author: Nevin Liber
#
# Date: June 29, 1994
#
###########################################################################
#
# This file is in the public domain.
#
############################################################################
#
# Usage: daystil sMonth iDay
#
# Returns:
# 0 number of days written on &output
# 1 Usage message on &errout (bad parameters)
#
# Revision History:
# <1> njl 6/29/94 9:50 PM First written
#
# This program calculates the number of days between the current date
# and the date specified on the command line, and writes this number to
# &output. This is useful if you want to know how many days it is
# until a birthday, wedding day, etc.
#
# The date on the command line can be specified in a variety of ways.
# For instance, if you wanted to know how many days it is until
# August 12 (my birthday), you could specify it as "August 12", "Aug 12",
# "12 August", or "12 aUGuS", among others. The match is case
# insensitive, and the arguments will be accepted as long as exactly
# one of them is an integer, and if there are exactly two arguments.
#
###########################################################################
#
# NumberOfDays(sMonth, iDay, iYear) : iNumberOfDays
#
# NumberOfDays() returns the number of days into iYear that sMonth/iDay
# occurs. For instance, NumberOfDays("February", 28) returns 59, since
# it is the 59th day into any year. Leap years from 1901 until 2099
# are taken into account. It fails if any parameters are bad.
#
# Defaults:
# sMonth current month
# iDay current day of the current month
# iYear current year
#
############################################################################
procedure NumberOfDays(sMonth, iDay, iYear)
static LMonths
static LDays
static sThisMonth
static iThisDay
static iThisYear
local iDays
local i
initial {
LMonths := [
"january",
"february",
"march",
"april",
"may",
"june",
"july",
"august",
"september",
"october",
"november",
"december"
]
LDays := [
31,
28,
31,
30,
31,
30,
31,
31,
30,
31,
30
]
&dateline ? {
&pos := find(" ") + 1
sThisMonth := tab(find(" "))
&pos +:= 1
iThisDay := integer(tab(find(",")))
&pos +:= 2
iThisYear := integer(move(4))
}
}
/sMonth := sThisMonth
/iDay := iThisDay
/iYear := iThisYear
sMonth := string(sMonth) | fail
iDay := integer(iDay) | fail
iYear := integer(iYear) | fail
if 0 ~= iYear % 4 then {
LDays[2] := 28
} else {
LDays[2] := 29
}
iDays := iDay
every i := 1 to *LMonths do {
if CaselessMatch(sMonth, LMonths[i]) then {
return iDays
}
iDays +:= LDays[i]
}
end
############################################################################
#
# CaselessMatch(s1, s2, i1, i2) : i3 caseless match of initial string
#
# CaselessMatch(s1, s2, i1, i2) produces i1 + *s1 if
# map(s1) == map(s2[i1+:*s1]) but fails otherwise.
#
# This is the same as the built-in function match(), except the
# comparisons are done without regard to case.
#
# Defaults:
# s2 &subject
# i1 &pos if s2 is defaulted, otherwise 1
# i2 0
#
# Errors:
# 101 i1 or i2 not integer
# 103 s1 or s2 not string
#
############################################################################
procedure CaselessMatch(s1, s2, i1, i2)
s1 := map(string(s1))
/i1 := (/s2 & &pos)
s2 := map(string(s2) | (/s2 & &subject))
return match(s1, s2, i1, i2)
end
############################################################################
#
# Usage(fErrout, iStatus) write usage message to fErrout and exit
#
# Usage(fErrout, iStatus) writes the usage message to file fErrout
# and exits with exit status code iStatus
#
# Defaults:
# fErrout &errout
# iStatus 1
#
############################################################################
procedure Usage(fErrout, iStatus)
/fErrout := &errout
iStatus := (integer(iStatus) | 1)
write(fErrout, "Usage: DaysTil sMonth iDay")
exit(iStatus)
end
############################################################################
#
# main(LArguments)
#
# main(LArguments) checks to make sure there are two arguments, exactly
# one of which is an integer. If so, it tries to calculate the number
# of days between the current date and the date specified, taking into
# account if the specified date occurs after today's date only in the
# following year. On a parameter error, it writes the usage message
# to &errout and exits with status 1. Otherwise, it writes the number
# of days to &output and exits with status 0.
#
############################################################################
procedure main(LArguments)
local sArgument
local sMonth
local iDay
local iToday
local iNumberOfDays
if 2 ~= *LArguments then {
Usage()
}
every sArgument := !LArguments do {
(iDay := integer(sArgument)) | (sMonth := sArgument)
}
if /iDay | /sMonth then {
Usage()
}
iToday := NumberOfDays()
iNumberOfDays := NumberOfDays(sMonth, iDay) | Usage()
if iNumberOfDays < iToday then {
iNumberOfDays := NumberOfDays("december", 31) + NumberOfDays(sMonth, iDay, integer(&date[1+:4]) + 1)
}
write(iNumberOfDays - iToday)
end