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

📄 partime.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * PARTIME		parse date/time string into a TM structure * * Returns: *	0 if parsing failed *	else time values in specified TM structure and zone (unspecified values *		set to TMNULL) * Notes: *	This code is quasi-public; it may be used freely in like software. *	It is not to be sold, nor used in licensed software without *	permission of the author. *	For everyone's benefit, please report bugs and improvements! * 	Copyright 1980 by Ken Harrenstien, SRI International. *	(ARPANET: KLH @ SRI) *//* Hacknotes: *	If parsing changed so that no backup needed, could perhaps modify *		to use a FILE input stream.  Need terminator, though. *	Perhaps should return 0 on success, else a non-zero error val? *//* $Log: partime.c,v $ * Revision 5.6  1991/08/19  03:13:55  eggert * Update timezones. * * Revision 5.5  1991/04/21  11:58:18  eggert * Don't put , just before } in initializer. * * Revision 5.4  1990/10/04  06:30:15  eggert * Remove date vs time heuristics that fail between 2000 and 2400. * Check for overflow when lexing an integer. * Parse 'Jan 10 LT' as 'Jan 10, LT', not 'Jan, 10 LT'. * * Revision 5.3  1990/09/24  18:56:31  eggert * Update timezones. * * Revision 5.2  1990/09/04  08:02:16  eggert * Don't parse two-digit years, because it won't work after 1999/12/31. * Don't permit 'Aug Aug'. * * Revision 5.1  1990/08/29  07:13:49  eggert * Be able to parse our own date format.  Don't assume year<10000. * * Revision 5.0  1990/08/22  08:12:40  eggert * Switch to GMT and fix the bugs exposed thereby.  Update timezones. * Ansify and Posixate.  Fix peekahead and int-size bugs. * * Revision 1.4  89/05/01  14:48:46  narten * fixed #ifdef DEBUG construct *  * Revision 1.3  88/08/28  14:53:40  eggert * Remove unportable "#endif XXX"s. *  * Revision 1.2  87/03/27  14:21:53  jenkins * Port to suns *  * Revision 1.1  82/05/06  11:38:26  wft * Initial revision *  */#include "rcsbase.h"libId(partId, "$Id: partime.c,v 5.6 1991/08/19 03:13:55 eggert Exp $")#define given(v) (0 <= (v))#define TMNULL (-1) /* Items not given are given this value */#define TZ_OFFSET (24*60) /* TMNULL  <  zone_offset - TZ_OFFSET */struct tmwent {	char const *went;	short wval;	char wflgs;	char wtype;};	/* wflgs */#define TWTIME 02	/* Word is a time value (absence implies date) */#define TWDST  04	/* Word is a DST-type timezone */	/* wtype */#define TM_MON	1	/* month name */#define TM_WDAY	2	/* weekday name */#define TM_ZON	3	/* time zone name */#define TM_LT	4	/* local time */#define TM_DST	5	/* daylight savings time */#define TM_12	6	/* AM, PM, NOON, or MIDNIGHT */	/* wval (for wtype==TM_12) */#define T12_AM 1#define T12_PM 2#define T12_NOON 12#define T12_MIDNIGHT 0static struct tmwent const tmwords [] = {	{"january",      0, 0, TM_MON},	{"february",     1, 0, TM_MON},	{"march",        2, 0, TM_MON},	{"april",        3, 0, TM_MON},	{"may",          4, 0, TM_MON},	{"june",         5, 0, TM_MON},	{"july",         6, 0, TM_MON},	{"august",       7, 0, TM_MON},	{"september",    8, 0, TM_MON},	{"october",      9, 0, TM_MON},	{"november",     10, 0, TM_MON},	{"december",     11, 0, TM_MON},	{"sunday",       0, 0, TM_WDAY},	{"monday",       1, 0, TM_WDAY},	{"tuesday",      2, 0, TM_WDAY},	{"wednesday",    3, 0, TM_WDAY},	{"thursday",     4, 0, TM_WDAY},	{"friday",       5, 0, TM_WDAY},	{"saturday",     6, 0, TM_WDAY},	{"gmt",          0*60, TWTIME, TM_ZON},   /* Greenwich */	{"utc",          0*60, TWTIME, TM_ZON},	{"ut",           0*60, TWTIME, TM_ZON},	{"cut",		 0*60, TWTIME, TM_ZON},	{"nzst",        -12*60, TWTIME, TM_ZON},  /* New Zealand */	{"jst",         -9*60, TWTIME, TM_ZON},   /* Japan */	{"kst",         -9*60, TWTIME, TM_ZON},   /* Korea */	{"ist",         -5*60-30, TWTIME, TM_ZON},/* India */	{"eet",         -2*60, TWTIME, TM_ZON},   /* Eastern Europe */	{"cet",         -1*60, TWTIME, TM_ZON},   /* Central Europe */	{"met",         -1*60, TWTIME, TM_ZON},   /* Middle Europe */	{"wet",          0*60, TWTIME, TM_ZON},   /* Western Europe */	{"nst",          3*60+30, TWTIME, TM_ZON},/* Newfoundland */	{"ast",          4*60, TWTIME, TM_ZON},   /* Atlantic */	{"est",          5*60, TWTIME, TM_ZON},   /* Eastern */	{"cst",          6*60, TWTIME, TM_ZON},   /* Central */	{"mst",          7*60, TWTIME, TM_ZON},   /* Mountain */	{"pst",          8*60, TWTIME, TM_ZON},   /* Pacific */	{"akst",         9*60, TWTIME, TM_ZON},   /* Alaska */	{"hast",         10*60, TWTIME, TM_ZON},  /* Hawaii-Aleutian */	{"hst",          10*60, TWTIME, TM_ZON},  /* Hawaii */	{"sst",          11*60, TWTIME, TM_ZON},  /* Samoa */	{"nzdt",        -12*60, TWTIME+TWDST, TM_ZON},    /* New Zealand */	{"kdt",         -9*60, TWTIME+TWDST, TM_ZON},     /* Korea */	{"bst",          0*60, TWTIME+TWDST, TM_ZON},     /* Britain */	{"ndt",		 3*60+30, TWTIME+TWDST, TM_ZON},  /* Newfoundland */	{"adt",          4*60, TWTIME+TWDST, TM_ZON},     /* Atlantic */	{"edt",          5*60, TWTIME+TWDST, TM_ZON},     /* Eastern */	{"cdt",          6*60, TWTIME+TWDST, TM_ZON},     /* Central */	{"mdt",          7*60, TWTIME+TWDST, TM_ZON},     /* Mountain */	{"pdt",          8*60, TWTIME+TWDST, TM_ZON},     /* Pacific */	{"akdt",         9*60, TWTIME+TWDST, TM_ZON},     /* Alaska */	{"hadt",         10*60, TWTIME+TWDST, TM_ZON},    /* Hawaii-Aleutian */#if 0	/*	 * The following names are duplicates or are not well attested.	 * A standard is needed.	 */	{"east",        -10*60, TWTIME, TM_ZON},  /* Eastern Australia */	{"cast",        -9*60-30, TWTIME, TM_ZON},/* Central Australia */	{"cst",         -8*60, TWTIME, TM_ZON},   /* China */	{"hkt",         -8*60, TWTIME, TM_ZON},   /* Hong Kong */	{"sst",         -8*60, TWTIME, TM_ZON},   /* Singapore */	{"wast",        -8*60, TWTIME, TM_ZON},   /* Western Australia */	{"?",		-6*60-30, TWTIME, TM_ZON},/* Burma */	{"?",           -4*60-30, TWTIME, TM_ZON},/* Afghanistan */	{"it",          -3*60-30, TWTIME, TM_ZON},/* Iran */	{"ist",         -2*60, TWTIME, TM_ZON},   /* Israel */	{"mez",		-1*60, TWTIME, TM_ZON},   /* Mittel-Europaeische Zeit */	{"ast",          1*60, TWTIME, TM_ZON},   /* Azores */	{"fst",          2*60, TWTIME, TM_ZON},   /* Fernando de Noronha */	{"bst",          3*60, TWTIME, TM_ZON},   /* Brazil */	{"wst",          4*60, TWTIME, TM_ZON},   /* Western Brazil */	{"ast",          5*60, TWTIME, TM_ZON},   /* Acre Brazil */	{"?",            9*60+30, TWTIME, TM_ZON},/* Marquesas */	{"?",		 12*60, TWTIME, TM_ZON},  /* Kwajalein */	{"eadt",        -10*60, TWTIME+TWDST, TM_ZON},    /* Eastern Australia */	{"cadt",        -9*60-30, TWTIME+TWDST, TM_ZON},  /* Central Australia */	{"cdt",         -8*60, TWTIME+TWDST, TM_ZON},     /* China */	{"wadt",        -8*60, TWTIME+TWDST, TM_ZON},     /* Western Australia */	{"idt",         -2*60, TWTIME+TWDST, TM_ZON},     /* Israel */	{"eest",        -2*60, TWTIME+TWDST, TM_ZON},     /* Eastern Europe */	{"cest",        -1*60, TWTIME+TWDST, TM_ZON},     /* Central Europe */	{"mest",        -1*60, TWTIME+TWDST, TM_ZON},     /* Middle Europe */	{"mesz",	-1*60, TWTIME+TWDST, TM_ZON},	  /* Mittel-Europaeische Sommerzeit */	{"west",         0*60, TWTIME+TWDST, TM_ZON},     /* Western Europe */	{"adt",          1*60, TWTIME+TWDST, TM_ZON},	  /* Azores */	{"fdt",          2*60, TWTIME+TWDST, TM_ZON},     /* Fernando de Noronha */	{"edt",          3*60, TWTIME+TWDST, TM_ZON},     /* Eastern Brazil */	{"wdt",          4*60, TWTIME+TWDST, TM_ZON},     /* Western Brazil */	{"adt",          5*60, TWTIME+TWDST, TM_ZON},     /* Acre Brazil */#endif	{"lt",           0, TWTIME, TM_LT},       /* local time */	{"dst",          1*60, TWTIME, TM_DST},      /* daylight savings time */	{"ddst",         2*60, TWTIME, TM_DST},      /* double dst */	{"am",           T12_AM,	TWTIME, TM_12},	{"pm",           T12_PM,	TWTIME, TM_12},	{"noon",         T12_NOON,	TWTIME, TM_12},	{"midnight",     T12_MIDNIGHT,	TWTIME, TM_12},	{0, 0, 0, 0}	/* Zero entry to terminate searches */};struct token {	char const *tcp;/* pointer to string */	int tcnt;	/* # chars */	char tbrk;	/* "break" char */	char tbrkl;	/* last break char */	char tflg;	/* 0 = alpha, 1 = numeric */	union {         /* Resulting value; */		int tnum;/* either a #, or */		struct tmwent const *ttmw;/* a ptr to a tmwent.  */	} tval;};static struct tmwent const*ptmatchstr P((char const*,int,struct tmwent const*));static int pt12hack P((struct tm *,int));static int ptitoken P((struct token *));static int ptstash P((int *,int));static int pttoken P((struct token *));	static intgoodzone(t, offset, am)	register struct token const *t;	int offset;	int *am;{	register int m;	if (		t->tflg  &&		t->tcnt == 4+offset  &&		(m = t->tval.tnum) <= 2400  &&		isdigit(t->tcp[offset]) &&		(m%=100) < 60	) {		m += t->tval.tnum/100 * 60;		if (t->tcp[offset-1]=='+')			m = -m;		*am = m;		return 1;	}	return 0;}    intpartime(astr, atm, zone)char const *astr;register struct tm *atm;int *zone;{    register int i;    struct token btoken, atoken;    int zone_offset; /* minutes west of GMT, plus TZ_OFFSET */    register char const *cp;    register char ch;    int ord, midnoon;    int *atmfield, dst, m;    int got1 = 0;    atm->tm_sec = TMNULL;    atm->tm_min = TMNULL;    atm->tm_hour = TMNULL;    atm->tm_mday = TMNULL;    atm->tm_mon = TMNULL;    atm->tm_year = TMNULL;    atm->tm_wday = TMNULL;    atm->tm_yday = TMNULL;    midnoon = TMNULL;		/* and our own temp stuff */    zone_offset = TMNULL;    dst = TMNULL;    btoken.tcnt = btoken.tbrk = 0;    btoken.tcp = astr;    for (;; got1=1) {	if (!ptitoken(&btoken))				/* Get a token */	  {     if(btoken.tval.tnum) return(0);         /* Read error? */		if (given(midnoon))			/* EOF, wrap up */			if (!pt12hack(atm, midnoon))				return 0;		if (!given(atm->tm_min))			atm->tm_min = 0;		*zone  =				(given(zone_offset) ? zone_offset-TZ_OFFSET : 0)			-	(given(dst) ? dst : 0);		return got1;	  }	if(btoken.tflg == 0)		/* Alpha? */	  {     i = btoken.tval.ttmw->wval;		switch (btoken.tval.ttmw->wtype) {		  default:			return 0;		  case TM_MON:			atmfield = &atm->tm_mon;			break;		  case TM_WDAY:			atmfield = &atm->tm_wday;			break;		  case TM_DST:			atmfield = &dst;			break;		  case TM_LT:			if (ptstash(&dst, 0))				return 0;			i = 48*60; /* local time magic number -- see maketime() */			/* fall into */		  case TM_ZON:			i += TZ_OFFSET;			if (btoken.tval.ttmw->wflgs & TWDST)				if (ptstash(&dst, 60))					return 0;			/* Peek ahead for offset immediately afterwards. */			if (			    (btoken.tbrk=='-' || btoken.tbrk=='+') &&			    (atoken=btoken, ++atoken.tcnt, ptitoken(&atoken)) &&			    goodzone(&atoken, 0, &m)			) {				i += m;				btoken = atoken;			}			atmfield = &zone_offset;

⌨️ 快捷键说明

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