Plan 9 from Bell Labs’s /usr/web/sources/contrib/quanstro/timezone/dateof.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>

static int mtab[]	= {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static int ltab[] 	= {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

static int
leapyear(int y)
{
	if ((0 == y%100 && y%400) || y%4)
		return 0;
	return 1;
}

static int
mdays(int y, int m)
{
	int *tab;

	tab = mtab;
	if(leapyear(y))
		tab = ltab;
	return tab[m];
}

static char *wdaytab[] = {
	"sun",
	"mon",
	"tue",
	"wed",
	"thu",
	"fri",
	"sat",
	0
};

static char *montab[] = {
	"jan",	"feb",	"mar",
	"apr",	"may",	"jun",
	"jul",	"aug",	"sep",
	"oct",	"nov",	"dec",
	0
};

int
strton(char *t, char **tab)
{
	int i;
	char s[4];

	if(strlen(t) != 3)
		return -1;
	for(i=0; i<4; i++)
		s[i] = tolower(t[i]);
	for(i=0; tab[i]; i++)
		if(strcmp(tab[i], s) == 0)
			return i;
	return -1;
}

int
strtomon(char *s)
{
	return strton(s, montab);
}

int
strtowday(char *s)
{
	return strton(s, wdaytab);
}

void
tmset(Tm *t, int year, int mon, int whr)
{
	memset(t, 0, sizeof *t);
	t->year = year - 1900;
	t->mon = mon;
	t->mday = 1;
	t->hour = whr;
	strcpy(t->zone, "GMT");
}

long
nthday(int year, int mon, int wday, int whr, int nth)
{
	Tm t, *u;
	long s, mday;

	tmset(&t, year, mon, whr);
	u = gmtime(s = tm2sec(&t));
	mday = (7-u->wday+wday)%7 + 7*(nth-1);
//fprint(2, "mday = %d, %s", mday, asctime(u));
	if(mday>mdays(year, mon))
		sysfatal("not %ld days in %s %d", mday, montab[mon], year);
	return s+mday*86400;
}

long
lastday(int year, int mon, int wday, int whr)
{
	Tm t, *u;
	long s, mday, nth, o;

	o = whr>0;
	tmset(&t, year, mon, whr);
	u = gmtime(s = tm2sec(&t));
	for(nth = 5; ; nth--){
		mday = (7-u->wday+wday)%7 + 7*(nth-1);
		if(mday+o>mdays(year, mon))
			continue;
		return s+mday*86400;
	}
}

void
usage(void)
{
	fprint(2, "usage: dateof year month wday nth\n");
	exits("usage");
}

int
getn(int (*f)(char*), int max, char *s)
{
	int i;

	if(strlen(s) == 3)
		i = f(s);
	else
		i = atoi(s)-1;	/* humans! */
	if(i<0 || i>max)
		usage();
	return i;
}

void
main(int argc, char **argv)
{
	long year, month, wday, nth, s, whr;

	whr = 2;
	ARGBEGIN {
	case 'w':
		whr = atoi(EARGF(usage()));
		break;
	default:
		usage();
	} ARGEND
	if(argc != 4)
		usage();

	year = atoi(*argv++);
	month = getn(strtomon, 11, *argv++);
	wday = getn(strtowday, 7, *argv++);
	if(strcmp(*argv, "last") == 0)
		s = lastday(year, month, wday, whr);
	else{
		nth = atoi(*argv);
		if(nth<=0 || nth>5)
			usage();
		s = nthday(year, month, wday, whr, nth);
	}

	fprint(1, "%ld\n", s);
	fprint(2, "gm 	= %s", asctime(gmtime(s)));
	fprint(2, "local	= %s", asctime(localtime(s)));
	exits("");
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].