⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 date.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <auth.h>#include "imap4d.h"char *wdayname[7] ={	"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};char *monname[12] ={	"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};static void	time2tm(Tm *tm, char *s);static void	zone2tm(Tm *tm, char *s);static int	dateindex(char *d, char **tab, int n);intrfc822date(char *s, int n, Tm *tm){	char *plus;	int m;	plus = "+";	if(tm->tzoff < 0)		plus = "";	m = 0;	if(0 <= tm->wday && tm->wday < 7){		m = snprint(s, n, "%s, ", wdayname[tm->wday]);		if(m < 0)			return m;	}	return snprint(s+m, n-m, "%.2d %s %.4d %.2d:%.2d:%.2d %s%.4d",		tm->mday, monname[tm->mon], tm->year+1900, tm->hour, tm->min, tm->sec,		plus, (tm->tzoff/3600)*100 + (tm->tzoff/60)%60);}intimap4date(char *s, int n, Tm *tm){	char *plus;	plus = "+";	if(tm->tzoff < 0)		plus = "";	return snprint(s, n, "%2d-%s-%.4d %2.2d:%2.2d:%2.2d %s%4.4d",		tm->mday, monname[tm->mon], tm->year+1900, tm->hour, tm->min, tm->sec, plus, (tm->tzoff/3600)*100 + (tm->tzoff/60)%60);}intimap4Date(Tm *tm, char *date){	char *flds[4];	if(getfields(date, flds, 3, 0, "-") != 3)		return 0;	tm->mday = strtol(flds[0], nil, 10);	tm->mon = dateindex(flds[1], monname, 12);	tm->year = strtol(flds[2], nil, 10) - 1900;	return 1;}/* * parse imap4 dates */ulongimap4DateTime(char *date){	Tm tm;	char *flds[4], *sflds[4];	ulong t;	if(getfields(date, flds, 4, 0, " ") != 3)		return ~0;	if(!imap4Date(&tm, flds[0]))		return ~0;	if(getfields(flds[1], sflds, 3, 0, ":") != 3)		return ~0;	tm.hour = strtol(sflds[0], nil, 10);	tm.min = strtol(sflds[1], nil, 10);	tm.sec = strtol(sflds[2], nil, 10);	strcpy(tm.zone, "GMT");	tm.yday = 0;	t = tm2sec(&tm);	zone2tm(&tm, flds[2]);	t -= tm.tzoff;	return t;}/* * parse dates of formats * [Wkd[,]] DD Mon YYYY HH:MM:SS zone * [Wkd] Mon ( D|DD) HH:MM:SS zone YYYY * plus anything similar * return nil for a failure */Tm*date2tm(Tm *tm, char *date){	Tm gmt, *atm;	char *flds[7], *s, dstr[64];	int n;	/*	 * default date is Thu Jan  1 00:00:00 GMT 1970	 */	tm->wday = 4;	tm->mday = 1;	tm->mon = 1;	tm->hour = 0;	tm->min = 0;	tm->sec = 0;	tm->year = 70;	strcpy(tm->zone, "GMT");	tm->tzoff = 0;	strncpy(dstr, date, sizeof(dstr));	dstr[sizeof(dstr)-1] = '\0';	n = tokenize(dstr, flds, 7);	if(n != 6 && n != 5)		return nil;	if(n == 5){		for(n = 5; n >= 1; n--)			flds[n] = flds[n - 1];		n = 5;	}else{		/*		 * Wday[,]		 */		s = strchr(flds[0], ',');		if(s != nil)			*s = '\0';		tm->wday = dateindex(flds[0], wdayname, 7);		if(tm->wday < 0)			return nil;	}	/*	 * check for the two major formats:	 * Month first or day first	 */	tm->mon = dateindex(flds[1], monname, 12);	if(tm->mon >= 0){		tm->mday = strtoul(flds[2], nil, 10);		time2tm(tm, flds[3]);		zone2tm(tm, flds[4]);		tm->year = strtoul(flds[5], nil, 10);		if(strlen(flds[5]) > 2)			tm->year -= 1900;	}else{		tm->mday = strtoul(flds[1], nil, 10);		tm->mon = dateindex(flds[2], monname, 12);		tm->year = strtoul(flds[3], nil, 10);		if(strlen(flds[3]) > 2)			tm->year -= 1900;		time2tm(tm, flds[4]);		zone2tm(tm, flds[5]);	}	if(n == 5){		gmt = *tm;		strncpy(gmt.zone, "", 4);		gmt.tzoff = 0;		atm = gmtime(tm2sec(&gmt));		tm->wday = atm->wday;	}else{		/*		 * Wday[,]		 */		s = strchr(flds[0], ',');		if(s != nil)			*s = '\0';		tm->wday = dateindex(flds[0], wdayname, 7);		if(tm->wday < 0)			return nil;	}	return tm;}/* * zone	: [A-Za-z][A-Za-z][A-Za-z]	some time zone names *	| [A-IK-Z]			military time; rfc1123 says the rfc822 spec is wrong. *	| "UT"				universal time *	| [+-][0-9][0-9][0-9][0-9] * zones is the rfc-822 list of time zone names */static NamedInt zones[] ={	{"A",	-1 * 3600},	{"B",	-2 * 3600},	{"C",	-3 * 3600},	{"CDT", -5 * 3600},	{"CST", -6 * 3600},	{"D",	-4 * 3600},	{"E",	-5 * 3600},	{"EDT", -4 * 3600},	{"EST", -5 * 3600},	{"F",	-6 * 3600},	{"G",	-7 * 3600},	{"GMT", 0},	{"H",	-8 * 3600},	{"I",	-9 * 3600},	{"K",	-10 * 3600},	{"L",	-11 * 3600},	{"M",	-12 * 3600},	{"MDT", -6 * 3600},	{"MST", -7 * 3600},	{"N",	+1 * 3600},	{"O",	+2 * 3600},	{"P",	+3 * 3600},	{"PDT", -7 * 3600},	{"PST", -8 * 3600},	{"Q",	+4 * 3600},	{"R",	+5 * 3600},	{"S",	+6 * 3600},	{"T",	+7 * 3600},	{"U",	+8 * 3600},	{"UT",	0},	{"V",	+9 * 3600},	{"W",	+10 * 3600},	{"X",	+11 * 3600},	{"Y",	+12 * 3600},	{"Z",	0},	{nil,	0}};static voidzone2tm(Tm *tm, char *s){	Tm aux, *atm;	int i;	if(*s == '+' || *s == '-'){		i = strtol(s, &s, 10);		tm->tzoff = (i / 100) * 3600 + i % 100;		strncpy(tm->zone, "", 4);		return;	}	/*	 * look it up in the standard rfc822 table	 */	strncpy(tm->zone, s, 3);	tm->zone[3] = '\0';	tm->tzoff = 0;	for(i = 0; zones[i].name != nil; i++){		if(cistrcmp(zones[i].name, s) == 0){			tm->tzoff = zones[i].v;			return;		}	}	/*	 * one last try: look it up in the current local timezone	 * probe a couple of times to get daylight/standard time change.	 */	aux = *tm;	memset(aux.zone, 0, 4);	aux.hour--;	for(i = 0; i < 2; i++){		atm = localtime(tm2sec(&aux));		if(cistrcmp(tm->zone, atm->zone) == 0){			tm->tzoff = atm->tzoff;			return;		}		aux.hour++;	}	strncpy(tm->zone, "GMT", 4);	tm->tzoff = 0;}/* * hh[:mm[:ss]] */static voidtime2tm(Tm *tm, char *s){	tm->hour = strtoul(s, &s, 10);	if(*s++ != ':')		return;	tm->min = strtoul(s, &s, 10);	if(*s++ != ':')		return;	tm->sec = strtoul(s, &s, 10);}static intdateindex(char *d, char **tab, int n){	int i;	for(i = 0; i < n; i++)		if(cistrcmp(d, tab[i]) == 0)			return i;	return -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -