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

📄 date.c

📁 操作系统源代码
💻 C
字号:
/* date - Display (or set) the date and time		Author: V. Archer */#include <sys/types.h>#include <ctype.h>#include <stddef.h>#include <stdlib.h>#include <time.h>#include <string.h>#include <unistd.h>#define	MIN	60L		/* # seconds in a minute */#define	HOUR	(60 * MIN)	/* # seconds in an hour */#define	DAY	(24 * HOUR)	/* # seconds in a day */#define	YEAR	(365 * DAY)	/* # seconds in a (non-leap) year */int qflag, uflag, sflag;/* Default output file descriptor. */int outfd = 1;_PROTOTYPE(int main, (int argc, char **argv));_PROTOTYPE(void putchar, (int c));_PROTOTYPE(void pstring, (char *s, int len));_PROTOTYPE(void pldecimal, (unsigned long d, int digits));_PROTOTYPE(void pdecimal, (int d, int digits));_PROTOTYPE(void fmtdate, (char *format, time_t t, struct tm *p));_PROTOTYPE(time_t make_time, (char *t));_PROTOTYPE(void usage, (void));/* Main module. Handles P1003.2 date and system administrator's date. The * date entered should be given GMT, regardless of the system's TZ! */int main(argc, argv)int argc;char **argv;{  time_t t;  char *format;  char time_buf[40];  int n;  int i;  time(&t);  i = 1;  while (i < argc && argv[i][0] == '-') {	char *opt = argv[i++] + 1, *end;	if (opt[0] == '-' && opt[1] == 0) break;	while (*opt != 0) switch (*opt++) {	case 'q':		qflag = 1;		break;	case 's':		sflag = 1;		break;	case 'u':		uflag = 1;		break;	case 't':		if (*opt == 0) {			if (i == argc) usage();			opt = argv[i++];		}		t = strtoul(opt, &end, 10);		if (*end != 0) usage();		opt = "";		break;	}  }  if (!qflag && i < argc && ('0' <= argv[i][0] && argv[i][0] <= '9')) {	t = make_time(argv[i++]);	sflag = 1;  }  format = "%c";  if (i < argc && argv[i][0] == '+') format = argv[i++] + 1;  if (i != argc) usage();  if (qflag) {	pstring("\nPlease enter date: MMDDYYhhmmss. Then hit the RETURN key.\n", -1);	n = read(0, time_buf, sizeof(time_buf));	if (n > 0 && time_buf[n-1] == '\n') n--;	if (n >= 0) time_buf[n] = 0;	t = make_time(time_buf);	sflag = 1;  }  if (sflag && stime(&t) != 0) {	outfd = 2;	pstring("No permission to set time\n", -1);	return(1);  }  fmtdate(format, t, uflag ? gmtime(&t) : localtime(&t));  putchar('\n');  return(0);}/* Replacement for stdio putchar(). */void putchar(c)int c;{  static char buf[1024];  static char *bp = buf;  if (c != 0) *bp++ = c;  if (c == 0 || c == '\n' || bp == buf + sizeof(buf)) {	write(outfd, buf, bp - buf);	bp = buf;  }}/* Internal function that prints a n-digits number. Replaces stdio in our * specific case. */void pldecimal(d, digits)unsigned long d;int digits;{  digits--;  if (d > 9 || digits > 0) pldecimal(d / 10, digits);  putchar('0' + (d % 10));}void pdecimal(d, digits)int d, digits;{  pldecimal((unsigned long) d, digits);}/* Internal function that prints a fixed-size string. Replaces stdio in our * specific case. */void pstring(s, len)char *s;int len;{  while (*s)	if (len--)		putchar(*s++);	else		break;}/* Format the date, using the given locale string. A special case is the * TZ which might be a sign followed by four digits (New format time zone). */void fmtdate(format, t, p)char *format;time_t t;struct tm *p;{  int i;  char *s;  static char *wday[] = {"Sunday", "Monday", "Tuesday", "Wednesday",		       "Thursday", "Friday", "Saturday"};  static char *month[] = {"January", "February", "March", "April",			"May", "June", "July", "August",		    "September", "October", "November", "December"};  p= uflag ? gmtime(&t) : localtime(&t);  while (*format)	if (*format == '%') {		switch (*++format) {		    case 'A':			pstring(wday[p->tm_wday], -1);			break;		    case 'B':			pstring(month[p->tm_mon], -1);			break;		    case 'D':			pdecimal(p->tm_mon + 1, 2);			putchar('/');			pdecimal(p->tm_mday, 2);			putchar('/');		    case 'y':			pdecimal(p->tm_year % 100, 2);			break;		    case 'H':			pdecimal(p->tm_hour, 2);			break;		    case 'I':			i = p->tm_hour % 12;			pdecimal(i ? i : 12, 2);			break;		    case 'M':			pdecimal(p->tm_min, 2);			break;		    case 'X':		    case 'T':			pdecimal(p->tm_hour, 2);			putchar(':');			pdecimal(p->tm_min, 2);			putchar(':');		    case 'S':			pdecimal(p->tm_sec, 2);			break;		    case 'U':			pdecimal((p->tm_yday - p->tm_wday + 13) / 7, 2);			break;		    case 'W':			if (--(p->tm_wday) < 0) p->tm_wday = 6;			pdecimal((p->tm_yday - p->tm_wday + 13) / 7, 2);			if (++(p->tm_wday) > 6) p->tm_wday = 0;			break;		    case 'Y':			pdecimal(p->tm_year + 1900, 4);			break;		    case 'Z':			if (uflag) {				s = "GMT";			} else {				s = (p->tm_isdst == 1) ? tzname[1] : tzname[0];			}			pstring(s, strlen(s));			break;		    case 'a':			pstring(wday[p->tm_wday], 3);			break;		    case 'b':		    case 'h':			pstring(month[p->tm_mon], 3);			break;		    case 'c':			if (!(s = getenv("LC_TIME")))				s = "%a %b %e %T %Z %Y";			fmtdate(s, t, p);			break;		    case 'd':			pdecimal(p->tm_mday, 2);			break;		    case 'e':			if (p->tm_mday < 10) putchar(' ');			pdecimal(p->tm_mday, 1);			break;		    case 'j':			pdecimal(p->tm_yday + 1, 3);			break;		    case 'm':			pdecimal(p->tm_mon + 1, 2);			break;		    case 'n':	putchar('\n');	break;		    case 'p':			if (p->tm_hour < 12)				putchar('A');			else				putchar('P');			putchar('M');			break;		    case 'r':			fmtdate("%I:%M:%S %p", t, p);			break;		    case 's':			pldecimal((unsigned long) t, 0);			break;		    case 't':	putchar('\t');	break;		    case 'w':			putchar('0' + p->tm_wday);			break;		    case 'x':			fmtdate("%B %e %Y", t, p);			break;		    case '%':	putchar('%');	break;		    case '\0':	format--;		}		format++;	} else		putchar(*format++);}/* Convert a local date string into GMT time in seconds. */time_t make_time(t)char *t;{  struct tm tm;				/* user specified time */  time_t now;				/* current time */  int leap;				/* current year is leap year */  int i;				/* general index */  int fld;				/* number of fields */  int f[6];				/* time fields */  static int days_per_month[2][12] = {  { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },  { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }};/* Get current time just in case */  now = time((time_t *) 0);  tm  = *localtime(&now);  tm.tm_sec   = 0;  tm.tm_mon++;  tm.tm_year %= 100;/* Parse the time */#if '0'+1 != '1' || '1'+1 != '2' || '2'+1 != '3' || '3'+1 != '4' || \    '4'+1 != '5' || '5'+1 != '6' || '6'+1 != '7' || '7'+1 != '8' || '8'+1 != '9'  << Code unsuitable for character collating sequence >>#endif  for (fld = 0; fld < sizeof(f)/sizeof(f[0]); fld++) {	if (*t == 0) break;	f[fld] = 0;	for (i = 0; i < 2; i++, t++) {		if (*t < '0' || *t > '9') usage();		f[fld] = f[fld] * 10 + *t - '0';	}  }  switch (fld) {  case 2:	tm.tm_hour = f[0]; tm.tm_min  = f[1]; break;  case 3:	tm.tm_hour = f[0]; tm.tm_min  = f[1]; tm.tm_sec  = f[2];	break;  case 5:  	tm.tm_mon  = f[0]; tm.tm_mday = f[1]; tm.tm_year = f[2];	tm.tm_hour = f[3]; tm.tm_min  = f[4];	break;  case 6:	tm.tm_mon  = f[0]; tm.tm_mday = f[1]; tm.tm_year = f[2];	tm.tm_hour = f[3]; tm.tm_min  = f[4]; tm.tm_sec  = f[5];	break;  default:	usage();  }/* Convert the time into seconds since 1 January 1970 */  if (tm.tm_year < 70)    tm.tm_year += 100;  leap = (tm.tm_year % 4 == 0 && tm.tm_year % 400 != 0);  if (tm.tm_mon  < 1  || tm.tm_mon  > 12 ||      tm.tm_mday < 1  || tm.tm_mday > days_per_month[leap][tm.tm_mon-1] ||      tm.tm_hour > 23 || tm.tm_min  > 59) {    outfd = 2;    pstring("Illegal date format\n", -1);    exit(1);  }/* Convert the time into Minix time - zone independent code */  {    time_t utctime;			/* guess at unix time */    time_t nextbit;			/* next bit to try */    int rv;				/* result of try */    struct tm *tmp;			/* local time conversion */#define COMPARE(a,b)	((a) != (b)) ? ((a) - (b)) :    utctime = 1;    do {      nextbit = utctime;      utctime = nextbit << 1;    } while (utctime >= 1);    for (utctime = 0; ; nextbit >>= 1) {      utctime |= nextbit;      tmp = localtime(&utctime);      if (tmp == 0) continue;      rv = COMPARE(tmp->tm_year,    tm.tm_year)           COMPARE(tmp->tm_mon + 1, tm.tm_mon)	   COMPARE(tmp->tm_mday,    tm.tm_mday)	   COMPARE(tmp->tm_hour,    tm.tm_hour)	   COMPARE(tmp->tm_min,     tm.tm_min)	   COMPARE(tmp->tm_sec,     tm.tm_sec)	   0;      if (rv > 0)        utctime &= ~nextbit;      else if (rv == 0)        break;      if (nextbit == 0) {	uflag = 1;        outfd = 2;        pstring("Inexact conversion to UTC from ", -1);        fmtdate("%c\n", utctime, localtime(&utctime) );	exit(1);      }    }    return utctime;  }}/* (Extended) Posix prototype of date. */void usage(){  outfd = 2;  pstring("Usage: date [-qsu] [-t seconds] [[MMDDYY]hhmm[ss]] [+format]\n", -1);  exit(1);}

⌨️ 快捷键说明

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