11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** This file is in the public domain, so clarified as of 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** 1996-06-05 by Arthur David Olson. 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project*/ 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** Avoid the temptation to punt entirely to strftime; 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** the output of strftime is supposed to be locale specific 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** whereas the output of asctime is supposed to be constant. 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project*/ 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*LINTLIBRARY*/ 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "private.h" 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "tzfile.h" 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** Some systems only handle "%.2d"; others only handle "%02d"; 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** "%02.2d" makes (most) everybody happy. 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** At least some versions of gcc warn about the %02.2d; 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** we conditionalize below to avoid the warning. 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project*/ 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** All years associated with 32-bit time_t values are exactly four digits long; 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** some years associated with 64-bit time_t values are not. 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** Vintage programs are coded for years that are always four digits long 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** and may assume that the newline always lands in the same place. 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** For years that are less than four digits, we pad the output with 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** leading zeroes to get the newline in the traditional place. 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** The -4 ensures that we get four characters of output even if 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** we call a strftime variant that produces fewer characters for some years. 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** The ISO C 1999 and POSIX 1003.1-2004 standards prohibit padding the year, 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** but many implementations pad anyway; most likely the standards are buggy. 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project*/ 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef __GNUC__ 36ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes#define ASCTIME_FMT "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %-4s\n" 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else /* !defined __GNUC__ */ 38ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes#define ASCTIME_FMT "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n" 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* !defined __GNUC__ */ 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** For years that are more than four digits we put extra spaces before the year 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** so that code trying to overwrite the newline won't end up overwriting 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** a digit within a year and truncating the year (operating on the assumption 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** that no output is better than wrong output). 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project*/ 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef __GNUC__ 47ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes#define ASCTIME_FMT_B "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %s\n" 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else /* !defined __GNUC__ */ 49ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes#define ASCTIME_FMT_B "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %s\n" 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* !defined __GNUC__ */ 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 52ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes#define STD_ASCTIME_BUF_SIZE 26 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** Big enough for something such as 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** (two three-character abbreviations, five strings denoting integers, 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** seven explicit spaces, two explicit colons, a newline, 589fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes** and a trailing NUL byte). 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** The values above are for systems where an int is 32 bits and are provided 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** as an example; the define below calculates the maximum for the system at 611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** hand. 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project*/ 63ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes#define MAX_ASCTIME_BUF_SIZE (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1) 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 65ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughesstatic char buf_asctime[MAX_ASCTIME_BUF_SIZE]; 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition. 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project*/ 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectchar * 72ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughesasctime_r(register const struct tm *timeptr, char *buf) 731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 74ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes static const char wday_name[][3] = { 75ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 76ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes }; 77ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes static const char mon_name[][3] = { 78ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes "Jan", "Feb", "Mar", "Apr", "May", "Jun", 79ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 80ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes }; 81ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes register const char * wn; 82ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes register const char * mn; 83ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes char year[INT_STRLEN_MAXIMUM(int) + 2]; 84ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes char result[MAX_ASCTIME_BUF_SIZE]; 851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 86ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes if (timeptr == NULL) { 87ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes errno = EINVAL; 88ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes return strcpy(buf, "??? ??? ?? ??:??:?? ????\n"); 89ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes } 90ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK) 91ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes wn = "???"; 92ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes else wn = wday_name[timeptr->tm_wday]; 93ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR) 94ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes mn = "???"; 95ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes else mn = mon_name[timeptr->tm_mon]; 96ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes /* 97ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes ** Use strftime's %Y to generate the year, to avoid overflow problems 98ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes ** when computing timeptr->tm_year + TM_YEAR_BASE. 99ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes ** Assume that strftime is unaffected by other out-of-range members 100ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes ** (e.g., timeptr->tm_mday) when processing "%Y". 101ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes */ 1029fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes strftime(year, sizeof year, "%Y", timeptr); 103ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes /* 104ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes ** We avoid using snprintf since it's not available on all systems. 105ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes */ 1069fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes snprintf(result, sizeof(result), /* Android change: use snprintf. */ 107ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes ((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B), 108ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes wn, mn, 109ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes timeptr->tm_mday, timeptr->tm_hour, 110ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes timeptr->tm_min, timeptr->tm_sec, 111ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes year); 112ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime) 113ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes return strcpy(buf, result); 114ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes else { 115ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes errno = EOVERFLOW; 116ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes return NULL; 117ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes } 1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition. 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project*/ 1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectchar * 125ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughesasctime(register const struct tm *timeptr) 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 127ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughes return asctime_r(timeptr, buf_asctime); 1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 129