[comp.sys.ibm.pc] calendar code

) (06/27/89)

I tried sending this out earlier, but don't think it
made it...so here goes: donahue vs. net (round 2)...

I'm looking for a Turbo C function that, when given
an arbitrary date, will return the day of the week that the date
falls on.

E.G.  given 11 6 1991 [nov 6, 1991], the function
      returns WEDNESDAY (or 3, if SUNDAY = 0).

Pls email any code or pointers to code. Thanks in advance.

dd <insert cute trailer here>

conan@vax1.acs.udel.EDU (Robert B Carroll) (06/28/89)

In article <82362@ti-csl.csc.ti.com> Donahue@TILDE (Them bats is smart; they use radar!) writes:
>E.G.  given 11 6 1991 [nov 6, 1991], the function
>      returns WEDNESDAY (or 3, if SUNDAY = 0).
>

I have the code you want(with the fixed leap year stuff 4/100/400).
Send me your internet address if you want it.


-- 
conan@vax1.acs.udel.edu OR conan@192.5.57.1
CONAN THE BARBARIAN of Cimmeria

jwright@atanasoff.cs.iastate.edu (Jim Wright) (06/28/89)

In article <82362@ti-csl.csc.ti.com> Donahue@TILDE (Them bats is smart; they use radar!) writes:
| I'm looking for a Turbo C function that, when given
| an arbitrary date, will return the day of the week that the date
| falls on.

I've got a section of code that does just this.  However, it's written
in TeX!  Probably not much good to you, but if you get desperate, let
me know.  :-)

-- 
Jim Wright
jwright@atanasoff.cs.iastate.edu

hughes@math.Berkeley.EDU (Eric Hughes) (06/28/89)

In article <82362@ti-csl.csc.ti.com>, Donahue@TILDE (Them bats is smart; they use radar!) writes:
>
>I'm looking for a Turbo C function that, when given
>an arbitrary date, will return the day of the week that the date
>falls on.

DOS call 42 (2A hex), which gets the date, also returns the day of the
week in register CX.  So first get the current date and save it, then
set the date, get the date, get your answer, and reset the date.  The
DOS set date call is 43 (2B hex).

I don't do this myself, but the idea is from Peter Norton's book
_Programmer's Guide to the IBM PC_.

Eric Hughes
hughes@math.berkeley.edu   ucbvax!math!hughes

pats@cup.portal.com (Pat T Shea) (06/29/89)

'think this is what ur looking for. . . . /pats.
 
/***********************************************************************
 *
 *          int  dmy2dow( int iDay, int iMon, int iYear ) - This is my
 *             implementation of the Zeller function.  It takes day/
 *             month/year and returns the day of the week as an int
 *             with Sunday being 0.....etc.
 *  /pats @Psi!
 *  11/05/85
 ******/
int dmy2dow( int day, int mon, int year )
{
   int adj_mo, adj_yr, cent, cent_yrs;
 
   adj_mo = ( mon > 2 ) ? mon - 2 : mon + 10;
   adj_yr = ( mon > 2 ) ? year    : year - 1;
   cent = adj_yr / 100;
   cent_yrs = adj_yr % 100;
   return((((( 13 * adj_mo - 1 ) / 5 ) + day + cent_yrs +
             ( cent_yrs / 4 ) + ( cent / 4 ) - 2 * cent + 77 ) % 7 ));
}

kirkenda@psueea.uucp (Steve Kirkendall) (07/01/89)

	Sorry for posting this, But I had trouble sending email.

	Although I suppose this is probably of general interest anyway...

In article <82362@ti-csl.csc.ti.com> Donahue@TILDE (Them bats is smart; they use radar!) writes:
>
>I'm looking for a Turbo C function that, when given
>an arbitrary date, will return the day of the week that the date
>falls on.
>
>E.G.  given 11 6 1991 [nov 6, 1991], the function
>      returns WEDNESDAY (or 3, if SUNDAY = 0).

This is slight overkill, but the rest of this message is a shar archive which
contains an implementation of the UNIX SysV localtime() function, and another
function called cvtdate() which converts and ASCII date string to UNIX format.

Cvtdate() is called with two arguments: the date in "YYMMDD" format, and the
time in "hhmm" format.  It returns a long int value which is the number of
seconds since time began (i.e. Jan 1, 1970).

Localtime() is called with a single argument: a pointer to a long int variable
which contains a time value.  It returns a pointer to a structure which breaks
the time down into year, month, day of year, day of month, day of week, hours
minutes, and seconds.  This structure type is called "struct tm" and is declared
in time.h (included).

An example:
	#include "time.h"
	extern long	cvtdate();

	main()
	{
		long		when;
		struct tm	*tptr;


		when = cvtdate("911106", "0000");
		tptr = localtime(&when);
		printf("Day of week = %d\n", tptr->tm_wday);
	}

If all you really care about is day-of-week, you could modify cvtdate to count
days instead of seconds, and take (days % 7) to get the day of the week.


#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	cvtdate.c
#	localtime.c
#	time.h
# This archive created: Thu Jun 29 14:54:18 1989
cat << \SHAR_EOF > cvtdate.c
/* cvtdate.c */

/* This file contains the cvtdate() function, which converts a date string
 * into a UNIX-style time value.
 */

/* Offset into the year for 1st of each month (disregarding leap years) */
static int monthoff[12]={ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
static int leapoff[12] ={ 0, 31, 60, 91, 121, 152, 182, 212, 244, 274, 305, 335 };

#define MIN	60L
#define HOUR	(60L*MIN)
#define DAY	(24L*HOUR)
#define YEAR	(365L*DAY) /* adjust for leapyears later */

static int cvt2(digits)
	char	*digits;
{
	return digits[0] * 10 + digits[1] - ('0' * 11);
}

long cvtdate(date, time)
	char	*date;
	char	*time;
{
	long	now;
	int	t;

	/* seconds for each year since 1970 */
	t = cvt2(date);
	if (t < 70)
		t += 100;
	now = (t - 70) * YEAR;

	/* adjust for intervening leapyears */
	now += ((t - 69) >> 2) * DAY;
#ifdef TEST
	printf("%ld + %ld = %ld\n", (t-70)*YEAR, now-(t-70)*YEAR, now);
#endif

	/* add in the month - adjust if this year is leapyear */
	now += ((t&3) ? monthoff : leapoff)[cvt2(date + 2) - 1] * DAY;

	/* add in the day, hour, and minute */
	now += (cvt2(date + 4) - 1) * DAY
	     + cvt2(time) * HOUR
	     + cvt2(time + 2) * MIN;

	return now;
}


#ifdef TEST
extern char *ctime();
main(argc, argv)
	int	argc;
	char	**argv;
{
	long	now;

	if (argc != 3)
	{
		printf("usage: %s yymmdd hhmm\n", argv[0]);
		exit(2);
	}
	
	now = cvtdate(argv[1], argv[2]);
	printf("now = %ld = \"%s\";\n", now, ctime(&now));
}
#endif
SHAR_EOF
cat << \SHAR_EOF > localtime.c
/* localtime.c */

/* This file contains the source to a SysV-compatiple localtime() function
 * Written by Steve Kirkendall, placed in public domain     April,1989
 */


#include <time.h>

/* Offset into the year for 1st of each month (disregarding leap years) */
int monthoff[12]={ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
int leapoff[12] ={ 0, 31, 60, 91, 121, 152, 182, 212, 244, 274, 305, 335 };

#define MIN	60L
#define HOUR	(60L*MIN)
#define DAY	(24L*HOUR)
#define YEAR	(365L*DAY) /* adjust for leapyears later */

struct tm *localtime(clock)
	long *clock;		/* the clock value to convert */
{
	static struct tm t;	/* the returned structure is STATIC!!! */
	long	timeleft;	/* amount of time not consumed in calc so far */
	int	i;

	/* find the current year, allowing for preceding leapyears */
	i = *clock / YEAR;	/* year - accurate formula 'til ~doomsday */
	t.tm_year = i + 1970;	/* add '1970' year offset */
	timeleft= *clock-i*YEAR;/* beginning of year, ignoring leapyears */
	i = (i + 1) / 4;	/* leap days, not including this year's */
	timeleft -= i * DAY;	/* use up all those leap days */

	/* calculate day of the year */
	t.tm_yday = timeleft / DAY;

	/* calculate month and day of month.  This might be a leap year */
	if (t.tm_year % 4 == 0)
	{
		/* use leapoff[] to find month */
		for (i = 11; leapoff[i] > t.tm_yday; i--)
		{
		}
		t.tm_mday = t.tm_yday - leapoff[i] + 1;
	}
	else
	{
		/* use regular monthoff[] table */
		for (i = 11; monthoff[i] > t.tm_yday; i--)
		{
		}
		t.tm_mday = t.tm_yday - monthoff[i] + 1;
	}
	t.tm_mon = i;
	timeleft -= t.tm_yday * DAY;

	/* calculate weekday. */
	t.tm_wday = (*clock / DAY + 4) % 7;

	/* calculate hour, minute, second */
	t.tm_hour = timeleft / HOUR;
	timeleft -= HOUR * t.tm_hour;
	t.tm_min = timeleft / MIN;
	timeleft -= MIN * t.tm_min;
	t.tm_sec = timeleft;

	/* calculate DST flag */
	t.tm_isdst = 0;

	return &t;
}

#ifdef TEST
main(argc, argv)
	int	argc;
	char	**argv;
{
	long	shot;	/* will this time be converted right? */
	struct tm *t;	/* the converted time */

	time(&shot);
	if (argc > 1)
	{
		shot += DAY * atoi(argv[1]);
	}
	t = localtime(&shot);
	printf("ctime() = \"%s\"\n", ctime(&shot));
	printf("tm_sec=%d\ntm_min=%d\ntm_hour=%d\ntm_mday=%d\ntm_mon=%d\n",
	     t->tm_sec, t->tm_min, t->tm_hour, t->tm_mday, t->tm_mon);
	printf("tm_year=%d\ntm_wday=%d\ntm_yday=%d\ntm_isdst=%d\n",
	     t->tm_year, t->tm_wday, t->tm_yday, t->tm_isdst);
}
#endif
SHAR_EOF
cat << \SHAR_EOF > time.h
struct tm {
	int	tm_sec;
	int	tm_min;
	int	tm_hour;
	int	tm_mday;
	int	tm_mon;
	int	tm_year;
	int	tm_wday;
	int	tm_yday;
	int	tm_isdst;
};

extern struct tm *localtime();
SHAR_EOF
#	End of shell archive
exit 0
	-- Steve Kirkendall
	   ...uunet!tektronix!psu-cs!kirkenda

vail@tegra.UUCP (Johnathan Vail) (07/05/89)

In article <82362@ti-csl.csc.ti.com> Donahue@TILDE (Them bats is smart; they use radar!) writes:

   I'm looking for a Turbo C function that, when given
   an arbitrary date, will return the day of the week that the date
   falls on.

   E.G.  given 11 6 1991 [nov 6, 1991], the function
	 returns WEDNESDAY (or 3, if SUNDAY = 0).


There is something called Zeller's Congruence which will do this.  If
there is interest I can dig it up from home and post it.

Stattinger's Law: It works better if you plug it in.
 _____
|     | Johnathan Vail | tegra!N1DXG@ulowell.edu
|Tegra| (508) 663-7435 | N1DXG@145.110-,145.270-,444.2+,448.625-
 -----