📄 time.c
字号:
static long tz_stdoffset = 0;static long tz_dstoffset = 0;static struct rule tz_dststart;static struct rule tz_dstend;static char tz_hasdst;char *tzname[2] = { tz_stdnam, tz_dstnam};/*** Given a POSIX section 8-style TZ string, fill in the rule tables as** appropriate.*/static int tzparse(const char *name){ const char * stdname; const char * dstname; int stdlen; int dstlen; tzname[0] = tz_stdnam; tzname[1] = tz_dstnam; memset(&tz_dststart,0,sizeof(tz_dststart)); memset(&tz_dstend,0,sizeof(tz_dstend)); stdname = name; name = getzname(name); stdlen = name - stdname; if (stdlen < 3 || stdlen >= TZNAME_MAX) return -1; strncpy(tz_stdnam,stdname,stdlen); if (*name == '\0') return -1; name = getoffset(name, &tz_stdoffset); if (name == NULL) return -1; if (*name != '\0') { dstname = name; name = getzname(name); dstlen = name - dstname; /* length of DST zone name */ if (dstlen < 3 || dstlen >= TZNAME_MAX) return -1; strncpy(tz_dstnam,dstname,dstlen); if (*name != '\0' && *name != ',' ) { name = getoffset(name, &tz_dstoffset); if (name == NULL) return -1; } else tz_dstoffset = tz_stdoffset - SECS_PER_HOUR; tz_hasdst = 1; if (*name == ',') { ++name; if ((name = getrule(name, &tz_dststart)) == NULL) return -1; if (*name++ != ',') return -1; if ((name = getrule(name, &tz_dstend)) == NULL) return -1; } if (*name != '\0') return -1; } else { strcpy(tz_dstnam," "); tz_dstoffset = 0; tz_hasdst = 0; } return 0;}/* * reset tz state to the default initial state*/static void tzreset(){ tzparse("UTC0");}void tzset(void){ const char *tz = getenv("TZ"); static char *tz_envval; if(tz && *tz) { if(tz_envval) { if(strcmp(tz_envval,tz) == 0) return; tz_envval = realloc(tz_envval,strlen(tz)+1); strcpy(tz_envval,tz); } else { tz_envval = malloc(strlen(tz)+1); strcpy(tz_envval,tz); } if(tzparse(tz) == 0) return; } if(tz_envval) { free(tz_envval); tz_envval = 0; tzreset(); }}struct tm *localtime(const time_t *tp){ struct tm *tm; time_t tgmt = *tp; int dst; tzset(); if(tz_hasdst) { if(tz_dststart.r_type != RT_NONE) { time_t tjan = 0; time_t tyr = tgmt; time_t yl; time_t stim; time_t etim; int yr; for(yr = EPOCH_YEAR; tyr >= (yl=year_lengths[isleap(yr)] * SECS_PER_DAY); yr++) { tyr -= yl; tjan += yl; } stim = transtime(tjan,yr,&tz_dststart,0); etim = transtime(tjan,yr,&tz_dstend,0); if(stim < etim) { if(tgmt >= stim && tgmt < etim) dst = 1; else dst = 0; } else { if(tgmt >= etim && tgmt < stim) dst = 0; else dst = 1; } } else dst = -1; } else dst = 0; tm = offtime(tp,dst==1?-tz_dstoffset:-tz_stdoffset); tm->tm_isdst = dst; tm->tm_zone = 0; return tm;}time_t gmmktime(const struct tm *tm){ int yr; int mn; time_t secs; if (tm->tm_sec > 61 || tm->tm_min > 59 || tm->tm_hour > 23 || tm->tm_mday > 31 || tm->tm_mon > 12 || tm->tm_year < 70) { return (time_t)-1; } /* * Sum up seconds from beginning of year */ secs = tm->tm_sec; secs += tm->tm_min * SECS_PER_MIN; secs += tm->tm_hour * SECS_PER_HOUR; secs += (tm->tm_mday-1) * SECS_PER_DAY; for (mn = 0; mn < tm->tm_mon; mn++) secs += mon_lengths[isleap(tm->tm_year+1900)][mn] * SECS_PER_DAY; for(yr=1970; yr < tm->tm_year + 1900; yr++) secs += year_lengths[isleap(yr)]*SECS_PER_DAY; return secs;}time_t mktime(struct tm *tm){ int yr; int mn; time_t secs; struct tm *ntm; if (tm->tm_sec > 61 || tm->tm_min > 59 || tm->tm_hour > 23 || tm->tm_mday > 31 || tm->tm_mon > 12 || tm->tm_year < 70) { return (time_t)-1; } /* * Sum up seconds from beginning of year */ secs = tm->tm_sec; secs += tm->tm_min * SECS_PER_MIN; secs += tm->tm_hour * SECS_PER_HOUR; secs += (tm->tm_mday-1) * SECS_PER_DAY; for (mn = 0; mn < tm->tm_mon; mn++) secs += mon_lengths[isleap(tm->tm_year+1900)][mn] * SECS_PER_DAY; for(yr=1970; yr < tm->tm_year + 1900; yr++) secs += year_lengths[isleap(yr)]*SECS_PER_DAY; if(tm->tm_isdst == 0) { secs -= tz_stdoffset; ntm = localtime(&secs); } else if(tm->tm_isdst > 0) { tm->tm_isdst = 1; secs -= tz_dstoffset; ntm = localtime(&secs); } else { /* try to determine if daylight saving was set at this time */ secs -= tz_stdoffset; ntm = localtime(&secs); if(ntm->tm_mday != tm->tm_mday || ntm->tm_hour != tm->tm_hour || ntm->tm_min != tm->tm_min || ntm->tm_sec != tm->tm_sec) { secs += tz_stdoffset; secs -= tz_dstoffset; } } /* work secs back into a tm to get all the fields correct */ if(ntm->tm_year != tm->tm_year || ntm->tm_mon != tm->tm_mon || ntm->tm_mday != tm->tm_mday || ntm->tm_hour != tm->tm_hour || ntm->tm_min != tm->tm_min || ntm->tm_sec != tm->tm_sec || (tm->tm_isdst >= 0 && ntm->tm_isdst != tm->tm_isdst)) return -1; *tm = *ntm; return secs;}#ifdef SIMPLE static int month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};static intyeartoday (int year){ return (year % 4) ? 365 : 366;}time_tmktime (struct tm *tm){ time_t n; int i, days = 0; if (tm->tm_sec > 61 || tm->tm_min > 59 || tm->tm_hour > 23 || tm->tm_mday > 31 || tm->tm_mon > 12 || tm->tm_year < 70) { return (time_t)-1; } n = tm->tm_sec + 60 * tm->tm_min + 3600 * tm->tm_hours; n += (tm->tm_mday - 1) * 3600 * 24; month[1] = (yeartoday(tm->tm_year) == 366) ? 29 : 28; for (i = tm->tm_mon - 2; i >= 0; i--) days += month[i]; for (i = 70; i < tm->tm_year; i++) days += yeartoday(i); n += days * 3600 * 24; return (n);}struct tm *gmtime (const time_t *t){ static struct tm tm; time_t n; n = *t % (3600 * 24); /* hrs+mins+secs */ tm.tm_sec = n % 60; n /= 60; tm.tm_min = n % 60; tm.tm_hour = n / 60; n = *t / (3600 * 24); /* days since 1/1/1970*/ tm.tm_wday = (n + 4) % 7; /* 1/1/70 was Thursday */ for (j = 1970, i = yeartoday(j); n >= i; j++, i = yeartoday(j)) n -= i; tm.tm_yday = n; tm.tm_year = j - 1900; month[1] = (i == 366) ? 29 : 28; for (i = 0; n >= month[i]; i++) n -= month[i]; tm.tm_mon = i + 1; tm.tm_day = n + 1; tm.tm_gmtoff = 0; tm.tm_isdst = 0; tm.tm_zone = "GMT"; return &tm;}#endifstatic const char * const dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };static const char * const monthname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };static int get2 (char *s){ if (s[0] < '0' || s[0] > '9' || s[1] < '0' || s[1] > '9') return -1; return (s[0] - '0') * 10 + (s[1] - '0');}intcmd_date(int argc, char **argv){ struct tm tm; time_t t; t = tgt_gettime (); tm = *localtime (&t); if (argc == 2) { char *s; int hadsecs = 0; int n; s = argv[1]; n = strlen (s); if (n >= 3 && s[n-3] == '.') { /* seconds */ if ((tm.tm_sec = get2 (&s[n-2])) < 0 || tm.tm_sec >= 60) { printf ("bad seconds\n"); return (1); } hadsecs = 1; n -= 3; } if (n >= 2) { /* minutes */ if ((tm.tm_min = get2 (&s[n-2])) < 0 || tm.tm_min >= 60) { printf ("bad minutes\n"); return (1); } n -= 2; if (!hadsecs) tm.tm_sec = 0; } if (n >= 2) { /* hours */ if ((tm.tm_hour = get2 (&s[n-2])) < 0 || tm.tm_hour >= 24) { printf ("bad hours\n"); return (1); } n -= 2; } if (n >= 2) { /* days */ if ((tm.tm_mday = get2 (&s[n-2])) < 0 || tm.tm_mday > 31) { /* test could be more thorough... */ printf ("bad day\n"); return (1); } n -= 2; } if (n >= 2) { /* months */ if ((tm.tm_mon = get2 (&s[n-2])) < 1 || tm.tm_mon > 12) { printf ("bad month\n"); return (1); } tm.tm_mon -= 1; /* zero based */ n -= 2; } if (n >= 2) { /* years */ if ((tm.tm_year = get2 (&s[n-2])) < 0) { printf ("bad year\n"); return (1); } if(n >= 4 && get2(&s[n-4]) == 20) { tm.tm_year += 100; n -= 2; } else if(n >= 4 && get2(&s[n-4]) == 19) { n -= 2; } else if(tm.tm_year < 70) { tm.tm_year += 100; } n -= 2; } if (n != 0) { printf ("%s: bad date syntax\n", argv[1]); return (1); } t = mktime (&tm); if (t != -1) tgt_settime (t); } if (t != -1) { printf ("%s %s %2d %02d:%02d:%02d %d\n", dayname[tm.tm_wday], monthname[tm.tm_mon], tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, TM_YEAR_BASE+tm.tm_year); } else { printf ("invalid date\n"); } return (0);}/* * Command table registration * ========================== */static const Cmd Cmds[] ={ {"Shell"}, {"date", "[yyyymmddhhmm.ss]", 0, "get/set date and time", cmd_date, 1, 2, CMD_REPEAT}, {0, 0}};static void init_cmd __P((void)) __attribute__ ((constructor));voidinit_cmd(){ cmdlist_expand(Cmds, 1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -