/*======================================================================== * Function name : gmt_convert_local * Description : 将格林尼治时间转换为本地时间 * Return type : bool * Argument : * : const char* gmt 格林尼治时间 20091105082121 * : char* local 20091105/162121 ========================================================================*/ bool gmt_convert_local(const char* gmt, char* local) { if ( strlen(gmt) != 14 ) return false; //格林尼治时间转换为本地时间 char year[5]; char month[3]; char day[3]; char hour[3]; char minute[3]; char second[3]; sscanf(gmt, "%4s%2s%2s%2s%2s%2s", year, month, day, hour, minute, second); tm utc_time; tm local_time; utc_time.tm_year = atoi(year); utc_time.tm_mon = atoi(month); utc_time.tm_mday = atoi(day); utc_time.tm_hour = atoi(hour); utc_time.tm_min = atoi(minute); utc_time.tm_sec = atoi(second); time64_t time_second = mktime64(&utc_time, 0);//utc时间, 0 时区 localtime64(&local_time, time_second,8); return true; }
static struct tm *_localtime64_r (const time_t * now, double *_t, struct tm *p) { double tl; time_t t; struct tm tm, tm_localtime, tm_gmtime; _gmtime64_r (now, _t, &tm); if (tm.tm_year > (2037 - 1900)) tm.tm_year = 2037 - 1900; t = mktime64 (&tm); localtime_r (&t, &tm_localtime); gmtime_r (&t, &tm_gmtime); tl = *_t; tl += (mktime64 (&tm_localtime) - mktime64 (&tm_gmtime)); _gmtime64_r (now, &tl, p); p->tm_isdst = tm_localtime.tm_isdst; return p; }
int iso_date(char * p, int flag) { int year, month, day, hour, minute, second, tz; int crtime; year = p[0]; month = p[1]; day = p[2]; hour = p[3]; minute = p[4]; second = p[5]; if (flag == 0) tz = p[6]; /* High sierra has no time zone */ else tz = 0; if (year < 0) { crtime = 0; } else { crtime = mktime64(year+1900, month, day, hour, minute, second); /* sign extend */ if (tz & 0x80) tz |= (-1 << 8); /* * The timezone offset is unreliable on some disks, * so we make a sanity check. In no case is it ever * more than 13 hours from GMT, which is 52*15min. * The time is always stored in localtime with the * timezone offset being what get added to GMT to * get to localtime. Thus we need to subtract the offset * to get to true GMT, which is what we store the time * as internally. On the local system, the user may set * their timezone any way they wish, of course, so GMT * gets converted back to localtime on the receiving * system. * * NOTE: mkisofs in versions prior to mkisofs-1.10 had * the sign wrong on the timezone offset. This has now * been corrected there too, but if you are getting screwy * results this may be the explanation. If enough people * complain, a user configuration option could be added * to add the timezone offset in with the wrong sign * for 'compatibility' with older discs, but I cannot see how * it will matter that much. * * Thanks to [email protected] (Volker Kuhlmann) * for pointing out the sign error. */ if (-52 <= tz && tz <= 52) crtime -= tz * 15 * 60; } return crtime; }
static int line2DeductionNoAdjEvent(char *line,EVENT_INTERFACE *pEvent) { struct tm tm_A; time64_t time64A; long double ratio; memset(&tm_A,'\0',sizeof(tm_A)); tm_A.tm_year=getNum(line,4)-1900; tm_A.tm_mon=getNum(line+4,2)-1; tm_A.tm_mday=global_debt.deductionPerMonDay; time64A=mktime64(&tm_A); sscanf(strstr(line,",")+1,"%Lf",&ratio); event_class_deduction_no_adjust_init(pEvent,time64A,global_debt.deductionPerMonAmount,ratio); return 0; }
static int line2IntrEvent(char *line,EVENT_INTERFACE *pEvent) { struct tm tm_A; time64_t time64A; long double intr; memset(&tm_A,'\0',sizeof(tm_A)); tm_A.tm_year=getNum(line,4)-1900; tm_A.tm_mon=getNum(line+4,2)-1; tm_A.tm_mday=getNum(line+6,2); time64A=mktime64(&tm_A); sscanf(strstr(line,",")+1,"%Lf",&intr); event_class_adjust_intr_init(pEvent,time64A,intr); return 0; }
/** * x509_decode_time - Decode an X.509 time ASN.1 object * @_t: The time to fill in * @hdrlen: The length of the object header * @tag: The object tag * @value: The object value * @vlen: The size of the object value * * Decode an ASN.1 universal time or generalised time field into a struct the * kernel can handle and check it for validity. The time is decoded thus: * * [RFC5280 §4.1.2.5] * CAs conforming to this profile MUST always encode certificate validity * dates through the year 2049 as UTCTime; certificate validity dates in * 2050 or later MUST be encoded as GeneralizedTime. Conforming * applications MUST be able to process validity dates that are encoded in * either UTCTime or GeneralizedTime. */ int x509_decode_time(time64_t *_t, size_t hdrlen, unsigned char tag, const unsigned char *value, size_t vlen) { static const unsigned char month_lengths[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; const unsigned char *p = value; unsigned year, mon, day, hour, min, sec, mon_len; #define dec2bin(X) ({ unsigned char x = (X) - '0'; if (x > 9) goto invalid_time; x; }) #define DD2bin(P) ({ unsigned x = dec2bin(P[0]) * 10 + dec2bin(P[1]); P += 2; x; }) if (tag == ASN1_UNITIM) { /* UTCTime: YYMMDDHHMMSSZ */ if (vlen != 13) goto unsupported_time; year = DD2bin(p); if (year >= 50) year += 1900; else year += 2000; } else if (tag == ASN1_GENTIM) { /* GenTime: YYYYMMDDHHMMSSZ */ if (vlen != 15) goto unsupported_time; year = DD2bin(p) * 100 + DD2bin(p); if (year >= 1950 && year <= 2049) goto invalid_time; } else { goto unsupported_time; } mon = DD2bin(p); day = DD2bin(p); hour = DD2bin(p); min = DD2bin(p); sec = DD2bin(p); if (*p != 'Z') goto unsupported_time; mon_len = month_lengths[mon]; if (mon == 2) { if (year % 4 == 0) { mon_len = 29; if (year % 100 == 0) { year /= 100; if (year % 4 != 0) mon_len = 28; } } } if (year < 1970 || mon < 1 || mon > 12 || day < 1 || day > mon_len || hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || sec > 59) goto invalid_time; *_t = mktime64(year, mon, day, hour, min, sec); return 0; unsupported_time: pr_debug("Got unsupported time [tag %02x]: '%*phN'\n", tag, (int)vlen, value); return -EBADMSG; invalid_time: pr_debug("Got invalid time [tag %02x]: '%*phN'\n", tag, (int)vlen, value); return -EBADMSG; }
/* Because I think mktime() is a crappy name */ Time64_T timelocal64(const struct TM *date) { return mktime64(date); }
/* * rtc_tm_to_time64 - Converts rtc_time to time64_t. * Convert Gregorian date to seconds since 01-01-1970 00:00:00. */ time64_t rtc_tm_to_time64(struct rtc_time *tm) { return mktime64(((unsigned)tm->tm_year + 1900), tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); }
time_t EppUtil::getDate( const char * s, bool dateOnly ) { time_t cal = 0; struct tm tmp; #if defined(win32) /* { */ const char * fmt = dateOnly ? "%4d-%2d-%2d" : "%4d-%2d-%2dT%2d:%2d:%2d.0Z"; #else /* defined(win32) */ /* } { */ #if defined(hpux) /* { */ const char * fmt = dateOnly ? "%Y-%m-%d" : "%Y-%m-%d %H:%M:%S.0Z"; #else /* defined(hpux) */ /* } { */ const char * fmt = dateOnly ? "%Y-%m-%d" : "%Y-%m-%dT%H:%M:%S.0Z"; #endif /* defined(hpux) */ /* } */ #endif /* defined(win32) */ /* } */ if( (s != null) && (*s != '\0') ) { char * buf = ::strdup(s); if( buf != null ) { #if defined(hpux) /* { */ char * cp = buf; while( *cp != '\0' ) { if( *cp == 'T' ) { *cp = ' '; break; } cp++; } #endif /* defined(hpux) */ /* } */ (void) memset((char *) &tmp, '\0', sizeof(tmp)); #if defined(win32) /* { */ char * c = ""; if( dateOnly ) { if( sscanf(buf, fmt, &tmp.tm_year, &tmp.tm_mon, &tmp.tm_mday) != 3 ) { c = null; } } else { if( sscanf(buf, fmt, &tmp.tm_year, &tmp.tm_mon, &tmp.tm_mday, &tmp.tm_hour, &tmp.tm_min, &tmp.tm_sec) != 6 ) { c = null; } } if( c != null ) { tmp.tm_year -= 1900; tmp.tm_mon--; } #else /* defined(win32) */ /* } { */ if ( dateOnly ) { strptime(buf, fmt, &tmp); } else { // Parse the GMT offset if present. struct tm junk; // Values inside are not used. Defined this instead of defining may ints. char tStr[32]; (void) memset(tStr, '\0', sizeof(tStr)); (void) memset((char *) &junk, '\0', sizeof(junk)); // Quick check on whats inside.... if ( sscanf(buf, "%u-%u-%uT%u:%u:%s", &junk.tm_year, &junk.tm_mon, &junk.tm_mday, &junk.tm_hour, &junk.tm_min, tStr) ) { const char * fmt2 = "%Y-%m-%dT%H:%M:%S%z"; char* subPtr; if ( subPtr = strchr(tStr, 'Z') ) { strptime(buf, fmt, &tmp); } else if ( NULL == strchr(tStr, ':') ) // timezone offset is something like +/-hhmm { strptime(buf, fmt2, &tmp); } else // timezone offset is something like +/-hh:mm { std::string input(buf); std::string subString(tStr); for ( int index = input.find(subString); index <input.length(); index++ ) { if ( input[index]==':' ) { input.erase(index, 1); } } strptime(input.c_str(), fmt2, &tmp); } } } #endif /* defined(win32) */ /* } */ #if EPP_SUPPORT_UNSIGNED_TIME_T /* { */ long long t = mktime64(&tmp) - timezone + daylight * 3600; cal = t & 0xFFFFFFFF; #else /* EPP_SUPPORT_UNSIGNED_TIME_T */ /* } */ // if( strptime(buf, fmt, &tmp) == null ) // if( (c == null) || (*c == '\0') ) { cal = mktime(&tmp) - timezone + daylight * 3600; } #endif /* EPP_SUPPORT_UNSIGNED_TIME_T */ /* } */ (void) ::free(buf); } } return cal; }
static char * _fmt(const char *format, const struct tm *t, char *pt, const char *ptlim, int *warnp) { for ( ; *format; ++format) { if (*format == '%') { int modifier = 0; label: switch (*++format) { case '\0': --format; break; case 'A': pt = _add((t->tm_wday < 0 || t->tm_wday >= DAYSPERWEEK) ? "?" : Locale->weekday[t->tm_wday], pt, ptlim, modifier); continue; case 'a': pt = _add((t->tm_wday < 0 || t->tm_wday >= DAYSPERWEEK) ? "?" : Locale->wday[t->tm_wday], pt, ptlim, modifier); continue; case 'B': pt = _add((t->tm_mon < 0 || t->tm_mon >= MONSPERYEAR) ? "?" : Locale->month[t->tm_mon], pt, ptlim, modifier); continue; case 'b': case 'h': pt = _add((t->tm_mon < 0 || t->tm_mon >= MONSPERYEAR) ? "?" : Locale->mon[t->tm_mon], pt, ptlim, modifier); continue; case 'C': /* ** %C used to do a... ** _fmt("%a %b %e %X %Y", t); ** ...whereas now POSIX 1003.2 calls for ** something completely different. ** (ado, 1993-05-24) */ pt = _yconv(t->tm_year, TM_YEAR_BASE, true, false, pt, ptlim, modifier); continue; case 'c': { int warn2 = IN_SOME; pt = _fmt(Locale->c_fmt, t, pt, ptlim, &warn2); if (warn2 == IN_ALL) warn2 = IN_THIS; if (warn2 > *warnp) *warnp = warn2; } continue; case 'D': pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp); continue; case 'd': pt = _conv(t->tm_mday, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim); continue; case 'E': case 'O': /* ** C99 locale modifiers. ** The sequences ** %Ec %EC %Ex %EX %Ey %EY ** %Od %oe %OH %OI %Om %OM ** %OS %Ou %OU %OV %Ow %OW %Oy ** are supposed to provide alternate ** representations. */ goto label; case '_': case '-': case '0': case '^': case '#': modifier = *format; goto label; case 'e': pt = _conv(t->tm_mday, getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim); continue; case 'F': pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp); continue; case 'H': pt = _conv(t->tm_hour, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim); continue; case 'I': pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim); continue; case 'j': pt = _conv(t->tm_yday + 1, getformat(modifier, "%03d", "%3d", "%d", "%03d"), pt, ptlim); continue; case 'k': /* ** This used to be... ** _conv(t->tm_hour % 12 ? ** t->tm_hour % 12 : 12, 2, ' '); ** ...and has been changed to the below to ** match SunOS 4.1.1 and Arnold Robbins' ** strftime version 3.0. That is, "%k" and ** "%l" have been swapped. ** (ado, 1993-05-24) */ pt = _conv(t->tm_hour, getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim); continue; #ifdef KITCHEN_SINK case 'K': /* ** After all this time, still unclaimed! */ pt = _add("kitchen sink", pt, ptlim); continue; #endif /* defined KITCHEN_SINK */ case 'l': /* ** This used to be... ** _conv(t->tm_hour, 2, ' '); ** ...and has been changed to the below to ** match SunOS 4.1.1 and Arnold Robbin's ** strftime version 3.0. That is, "%k" and ** "%l" have been swapped. ** (ado, 1993-05-24) */ pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim); continue; case 'M': pt = _conv(t->tm_min, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim); continue; case 'm': pt = _conv(t->tm_mon + 1, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim); continue; case 'n': pt = _add("\n", pt, ptlim, modifier); continue; case 'P': case 'p': pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ? Locale->pm : Locale->am, pt, ptlim, (*format == 'P') ? FORCE_LOWER_CASE : modifier); continue; case 'R': pt = _fmt("%H:%M", t, pt, ptlim, warnp); continue; case 'r': pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp); continue; case 'S': pt = _conv(t->tm_sec, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim); continue; case 's': { struct tm tm; char buf[INT_STRLEN_MAXIMUM( time64_t) + 1]; time64_t mkt; tm = *t; mkt = mktime64(&tm); if (TYPE_SIGNED(time64_t)) snprintf(buf, sizeof(buf), "%"PRIdMAX, (intmax_t) mkt); else snprintf(buf, sizeof(buf), "%"PRIuMAX, (uintmax_t) mkt); pt = _add(buf, pt, ptlim, modifier); } continue; case 'T': pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp); continue; case 't': pt = _add("\t", pt, ptlim, modifier); continue; case 'U': pt = _conv((t->tm_yday + DAYSPERWEEK - t->tm_wday) / DAYSPERWEEK, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim); continue; case 'u': /* ** From Arnold Robbins' strftime version 3.0: ** "ISO 8601: Weekday as a decimal number ** [1 (Monday) - 7]" ** (ado, 1993-05-24) */ pt = _conv((t->tm_wday == 0) ? DAYSPERWEEK : t->tm_wday, "%d", pt, ptlim); continue; case 'V': /* ISO 8601 week number */ case 'G': /* ISO 8601 year (four digits) */ case 'g': /* ISO 8601 year (two digits) */ /* ** From Arnold Robbins' strftime version 3.0: "the week number of the ** year (the first Monday as the first day of week 1) as a decimal number ** (01-53)." ** (ado, 1993-05-24) ** ** From <http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html> by Markus Kuhn: ** "Week 01 of a year is per definition the first week which has the ** Thursday in this year, which is equivalent to the week which contains ** the fourth day of January. In other words, the first week of a new year ** is the week which has the majority of its days in the new year. Week 01 ** might also contain days from the previous year and the week before week ** 01 of a year is the last week (52 or 53) of the previous year even if ** it contains days from the new year. A week starts with Monday (day 1) ** and ends with Sunday (day 7). For example, the first week of the year ** 1997 lasts from 1996-12-30 to 1997-01-05..." ** (ado, 1996-01-02) */ { int year; int base; int yday; int wday; int w; year = t->tm_year; base = TM_YEAR_BASE; yday = t->tm_yday; wday = t->tm_wday; for ( ; ; ) { int len; int bot; int top; len = isleap_sum(year, base) ? DAYSPERLYEAR : DAYSPERNYEAR; /* ** What yday (-3 ... 3) does ** the ISO year begin on? */ bot = ((yday + 11 - wday) % DAYSPERWEEK) - 3; /* ** What yday does the NEXT ** ISO year begin on? */ top = bot - (len % DAYSPERWEEK); if (top < -3) top += DAYSPERWEEK; top += len; if (yday >= top) { ++base; w = 1; break; } if (yday >= bot) { w = 1 + ((yday - bot) / DAYSPERWEEK); break; } --base; yday += isleap_sum(year, base) ? DAYSPERLYEAR : DAYSPERNYEAR; } #ifdef XPG4_1994_04_09 if ((w == 52 && t->tm_mon == TM_JANUARY) || (w == 1 && t->tm_mon == TM_DECEMBER)) w = 53; #endif /* defined XPG4_1994_04_09 */ if (*format == 'V') pt = _conv(w, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim); else if (*format == 'g') { *warnp = IN_ALL; pt = _yconv(year, base, false, true, pt, ptlim, modifier); } else pt = _yconv(year, base, true, true, pt, ptlim, modifier); } continue; case 'v': /* ** From Arnold Robbins' strftime version 3.0: ** "date as dd-bbb-YYYY" ** (ado, 1993-05-24) */ pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp); continue; case 'W': pt = _conv((t->tm_yday + DAYSPERWEEK - (t->tm_wday ? (t->tm_wday - 1) : (DAYSPERWEEK - 1))) / DAYSPERWEEK, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim); continue; case 'w': pt = _conv(t->tm_wday, "%d", pt, ptlim); continue; case 'X': pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp); continue; case 'x': { int warn2 = IN_SOME; pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2); if (warn2 == IN_ALL) warn2 = IN_THIS; if (warn2 > *warnp) *warnp = warn2; } continue; case 'y': *warnp = IN_ALL; pt = _yconv(t->tm_year, TM_YEAR_BASE, false, true, pt, ptlim, modifier); continue; case 'Y': pt = _yconv(t->tm_year, TM_YEAR_BASE, true, true, pt, ptlim, modifier); continue; case 'Z': #ifdef TM_ZONE // BEGIN: Android-changed. { const char* zone = t->TM_ZONE; if (!zone || !*zone) { // "The value of tm_isdst shall be positive if Daylight Savings Time is // in effect, 0 if Daylight Savings Time is not in effect, and negative // if the information is not available." if (t->tm_isdst == 0) zone = tzname[0]; else if (t->tm_isdst > 0) zone = tzname[1]; // "Replaced by the timezone name or abbreviation, or by no bytes if no // timezone information exists." if (!zone || !*zone) zone = ""; } pt = _add(zone, pt, ptlim, modifier); } // END: Android-changed. #else if (t->tm_isdst >= 0) pt = _add(tzname[t->tm_isdst != 0], pt, ptlim); #endif /* ** C99 says that %Z must be replaced by the ** empty string if the time zone is not ** determinable. */ continue; case 'z': { long diff; char const * sign; if (t->tm_isdst < 0) continue; #ifdef TM_GMTOFF diff = t->TM_GMTOFF; #else /* !defined TM_GMTOFF */ /* ** C99 says that the UT offset must ** be computed by looking only at ** tm_isdst. This requirement is ** incorrect, since it means the code ** must rely on magic (in this case ** altzone and timezone), and the ** magic might not have the correct ** offset. Doing things correctly is ** tricky and requires disobeying C99; ** see GNU C strftime for details. ** For now, punt and conform to the ** standard, even though it's incorrect. ** ** C99 says that %z must be replaced by the ** empty string if the time zone is not ** determinable, so output nothing if the ** appropriate variables are not available. */ if (t->tm_isdst == 0) #ifdef USG_COMPAT diff = -timezone; #else /* !defined USG_COMPAT */ continue; #endif /* !defined USG_COMPAT */ else #ifdef ALTZONE diff = -altzone; #else /* !defined ALTZONE */ continue; #endif /* !defined ALTZONE */ #endif /* !defined TM_GMTOFF */ if (diff < 0) { sign = "-"; diff = -diff; } else sign = "+"; pt = _add(sign, pt, ptlim, modifier); diff /= SECSPERMIN; diff = (diff / MINSPERHOUR) * 100 + (diff % MINSPERHOUR); pt = _conv(diff, getformat(modifier, "%04d", "%4d", "%d", "%04d"), pt, ptlim); } continue; case '+': pt = _fmt(Locale->date_fmt, t, pt, ptlim, warnp); continue; case '%': /* ** X311J/88-090 (4.12.3.5): if conversion char is ** undefined, behavior is undefined. Print out the ** character itself as printf(3) also does. */ default: break; } }