home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
prog
/
source
/
dates2.lha
/
dates2.h
next >
Wrap
C/C++ Source or Header
|
1987-07-27
|
9KB
|
277 lines
/******************************************************************************
dates2.h
written by: Kevin Rahe, Reliable Software
special thanks to:
Jim Miles for help with the Macintosh
-------------------------------------------------------------------------------
Functions for date calculation and conversion. Inspired by DATE.C from
John A. Hodgson, and a need for date calculation routines in a personal
project. These routines should be error-free until the beginning of the
22nd century. Please see the text above each routine for notes and comments
on usage. I've spent much time developing and testing these routines.
V2 NOTE: date format changed from JULDATE structure to long integer. This
makes the date functions easier to use and more logical, and the date is
easier to manipulate in this fashion. It also allowed me to remove the
Date_Span function, as all you need to do is subtract one julian date from
another to get the # of days between them when they're in long integer
format.
NOTE #2: Please refer to the text above the function get_date() before
attempting to use this #include file.
Functions:
get_date() - returns the current system date in Julian (long integer)
form.
jultogreg() - converts a Julian date to Gregorian (MM-DD-YYYY) form.
gregtojul() - converts a Gregorian (MM-DD-YY or MM-DD-YYY) date to
Julian form.
dayofweek() - returns the day of week of a Julian date.
datestat() - returns information about a Julian date such as the day of
the month, month number, number of days in the month,
and year.
******************************************************************************/
/* NOTE: Your compiler (ie. Aztec) may not support strchr(), but it may
support index() instead, in which case de-comment the following line */
/* #define strchr index */
#ifdef MAC
#ifndef _OSUTIL
#include <osutil.h>
#endif
#endif
/* # of days preceding each month */
short days_before[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
char *dayname[] = {"Fri","Sat","Sun", "Mon", "Tue", "Wed", "Thu"};
long gregtojul(); /** declared here so it can be used in the Macintosh
version of get_date() **/
/******************************************************************************
FUNCTION: get_date()
This function should return the current system date. It is obviously
going to be very system-dependent, so you may have to dig out your
tech. manuals and write this one yourself. Amiga and Mac versions are
present here, one being used at compilation based on the constants
defined. If AMIGA is defined, the Amiga version is used (Amiga Lattice
defines AMIGA - not sure about Manx). If MAC is defined, then the
Macintosh version is used. Note that they aren't mutually-exclusive. If
both AMIGA *AND* MAC are defined, it will attempt to compile both versions,
resulting in an error. If you write a version for a different system, by
all means add a #ifdef for it, add to this text explaining which constant
should be defined for its use, and of course, add your name to the
credits.
*****************************************************************************/
#ifdef AMIGA
long get_date()
{
long datestmp[3];
DateStamp(&datestmp[0]); /* get the date */
return (datestmp[0] + 722465); /* add 1 for Jan. 1, 1978 */
/** there were 722464 days (since year 0) before Jan. 1, 1978.
Since Amiga's internal date format starts one day (24 hrs)
after the beginning of 1978, we have to add one day so we
can work on even-year boundaries. In other words,
datestamp[0] is the # of days since 12:00am on Jan. 2,
1978. **/
}
#endif
#ifdef MAC
long get_date()
{
DateTimeRec daterec;
char greg_date[11], string[6];
GetTime(&daterec);
sprintf(greg_date, "%d", daterec.month);
strcat(greg_date, "-");
sprintf(string, "%d", daterec.day);
strcat(greg_date, string); /* add day to greg_date */
strcat(greg_date, "-");
sprintf(string, "%d", daterec.year);
strcat(greg_date, string); /* add year to greg_date */
return(gregtojul(greg_date));
}
#endif
/******************************************************************************
This function accepts two arguments: a string pointer and a long integer
(Julian date). The routine will convert the Julian date to Gregorian
(MM-DD-YYYY) format. The string pointer must point to a space at least
11 characters long.
******************************************************************************/
void jultogreg(greg_date, date)
char *greg_date;
long date;
{
short year, month, day;
short julday, leapyears;
char string[6];
year = date / 365;
julday = date % 365;
leapyears = year / 4;
julday -= leapyears;
while (julday < 1)
{
if (year % 4 == 0)
julday += 366;
else
julday += 365;
year -= 1;
}
if ( !(year % 4) && julday > 60) julday -= 1;
/* subtract 1 if we are in a leap year & past Feb. */
for (month = 0; (days_before[month] < julday) && (month < 12); month++);
/* find month */
day = julday - days_before[month-1]; /* get current day */
sprintf(greg_date, "%d", month);
strcat(greg_date, "-");
sprintf(string, "%d", day);
strcat(greg_date, string); /* add day to greg_date */
strcat(greg_date, "-");
sprintf(string, "%d", year);
strcat(greg_date, string); /* add year to greg_date */
}
/******************************************************************************
The following function accepts one argument: A pointer to a string.
It evaluates the string to determine if it is a valid date, then converts
it to Julian form which it returns as a long integer. If the date is
invalid, a 0 will be returned. It is not 100% accurate in its
date-checking, as it only checks to make sure that the date is not greater
than 31, without checking what the maximum value should be for that month.
NOTE: The Gregorian date passed to this routine must be delimited by
slashes '/' or dashes '-', and can be in MM-DD-YY or MM-DD-YYYY
form. The century will be assumed to be the 20th if the form is
the former. (no pun intended)
******************************************************************************/
long gregtojul(greg_date)
char *greg_date;
{
char *strchr();
long month, day, year;
long date = 0;
char *stptr, *temptr;
if ((stptr = strchr(greg_date,'-')) == 0)
stptr = strchr(greg_date,'/'); /* find delimiter */
if (stptr > 0)
{
sscanf(greg_date, "%ld", &month); /* extract month */
if ( month >= 1 && month <= 12)
{
stptr += 1; /* skip delimiter */
sscanf(stptr, "%ld", &day);
if ((temptr = strchr(stptr,'-')) == 0)
temptr = strchr(stptr,'/'); /* 2nd delimiter */
if ( temptr > 0 && day >=1 && day <=31)
{
stptr = temptr + 1; /* skip delimiter */
sscanf(stptr, "%ld", &year);
if ( year > 0 )
{
if ( year < 100 )
year += 1900; /* only 2 digits */
date = year * 365 + year / 4;
date += days_before[month - 1];
date += day;
if ( !(year % 4) && month > 2) /* > Feb */
date += 1; /* leap year */
}
}
}
}
return(date);
}
/******************************************************************************
The following function, supplied with a Julian date in long integer
format, will return a pointer to a 3-letter abbreviation of the day of the
week.
******************************************************************************/
char *dayofweek(date)
long date;
{
return(dayname[date % 7]);
}
/******************************************************************************
The following function accepts a Julian date in long integer form and
returns a short integer that is the day of the month. It also assigns
to num the number of days in the current month, to yr the current year,
and to mn the month #. These 3 parameters are optional. Pass them as
(short) NULL if you don't need them.
******************************************************************************/
short datestat(date, mn, yr, num)
long date;
short *mn, *yr, *num;
{
short month, year, julday, leapyears;
year = date / 365;
julday = date % 365;
leapyears = year / 4;
julday -= leapyears;
while (julday < 1)
{
if (year % 4 == 0)
julday += 366;
else
julday += 365;
year -= 1;
}
if (year % 4 == 0 && julday > 60) julday -= 1;
for (month = 0; (days_before[month] < julday) && (month < 12); month++);
/* find month */
/**** Optional parameter assignments ****/
if (num) /* not = NULL */
{
if (month == 12)
*num = 31;
else
{
*num = days_before[month] - days_before[month - 1];
if (year % 4 == 0 && month == 2)
*num += 1;
}
}
if (mn)
*mn = month;
if (yr)
*yr = year;
return(julday - days_before[month-1]); /** date **/
}