1864c0d50cda714d73fa70e3600ec36b5db8a835aMathias Agopian#include "TimeUtils.h" 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/tztime.h> 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdump(const Time& t) 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #ifdef HAVE_TM_GMTOFF 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long tm_gmtoff = t.t.tm_gmtoff; 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #else 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long tm_gmtoff = 0; 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #endif 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("%04d-%02d-%02d %02d:%02d:%02d (%d,%ld,%d,%d)\n", 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.t.tm_year+1900, t.t.tm_mon+1, t.t.tm_mday, 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.t.tm_hour, t.t.tm_min, t.t.tm_sec, 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.t.tm_isdst, tm_gmtoff, t.t.tm_wday, t.t.tm_yday); 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectTime::Time() 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.tm_sec = 0; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.tm_min = 0; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.tm_hour = 0; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.tm_mday = 0; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.tm_mon = 0; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.tm_year = 0; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.tm_wday = 0; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.tm_yday = 0; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.tm_isdst = -1; // we don't know, so let the C library determine 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #ifdef HAVE_TM_GMTOFF 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.tm_gmtoff = 0; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #endif 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define COMPARE_FIELD(field) do { \ 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int diff = a.t.field - b.t.field; \ 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (diff != 0) return diff; \ 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while(0) 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectTime::compare(Time& a, Time& b) 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (0 == strcmp(a.timezone, b.timezone)) { 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the timezones are the same, we can easily compare the two 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // times. Otherwise, convert to milliseconds and compare that. 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This requires that object be normalized. 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project COMPARE_FIELD(tm_year); 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project COMPARE_FIELD(tm_mon); 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project COMPARE_FIELD(tm_mday); 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project COMPARE_FIELD(tm_hour); 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project COMPARE_FIELD(tm_min); 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project COMPARE_FIELD(tm_sec); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int64_t am = a.toMillis(false /* use isDst */); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int64_t bm = b.toMillis(false /* use isDst */); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int64_t diff = am-bm; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (diff < 0) ? -1 : ((diff > 0) ? 1 : 0); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const int DAYS_PER_MONTH[] = { 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline int days_this_month(int year, int month) 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int n = DAYS_PER_MONTH[month]; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n != 28) { 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return n; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int y = year; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ((y%4)==0&&((y%100)!=0||(y%400)==0)) ? 29 : 28; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectTime::switchTimezone(const char* timezone) 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time_t seconds = mktime_tz(&(this->t), this->timezone); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project localtime_tz(&seconds, &(this->t), timezone); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectTime::format(const char *format, const struct strftime_locale *locale) const 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char buf[257]; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int n = strftime_tz(buf, 257, format, &(this->t), locale); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n > 0) { 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(buf); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return String8(); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline short 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttochar(int n) 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (n >= 0 && n <= 9) ? ('0'+n) : ' '; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline short 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnext_char(int *m, int k) 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int n = *m / k; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *m = *m % k; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return tochar(n); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectTime::format2445(short* buf, bool hasTime) const 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int n; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = t.tm_year+1900; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[0] = next_char(&n, 1000); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[1] = next_char(&n, 100); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[2] = next_char(&n, 10); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[3] = tochar(n); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = t.tm_mon+1; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[4] = next_char(&n, 10); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[5] = tochar(n); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = t.tm_mday; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[6] = next_char(&n, 10); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[7] = tochar(n); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hasTime) { 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[8] = 'T'; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = t.tm_hour; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[9] = next_char(&n, 10); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[10] = tochar(n); 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = t.tm_min; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[11] = next_char(&n, 10); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[12] = tochar(n); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = t.tm_sec; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[13] = next_char(&n, 10); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[14] = tochar(n); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool inUtc = strcmp("UTC", timezone) == 0; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inUtc) { 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[15] = 'Z'; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectTime::toString() const 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 str; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char* s = str.lockBuffer(150); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #ifdef HAVE_TM_GMTOFF 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long tm_gmtoff = t.tm_gmtoff; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #else 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long tm_gmtoff = 0; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #endif 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(s, "%04d%02d%02dT%02d%02d%02d%s(%d,%d,%ld,%d,%d)", 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.tm_sec, timezone, t.tm_wday, t.tm_yday, tm_gmtoff, t.tm_isdst, 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (int)(((Time*)this)->toMillis(false /* use isDst */)/1000)); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project str.unlockBuffer(); 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return str; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectTime::setToNow() 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time_t seconds; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time(&seconds); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project localtime_tz(&seconds, &(this->t), this->timezone); 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint64_t 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectTime::toMillis(bool ignoreDst) 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ignoreDst) { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this->t.tm_isdst = -1; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int64_t r = mktime_tz(&(this->t), this->timezone); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r == -1) 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return r * 1000; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectTime::set(int64_t millis) 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time_t seconds = millis / 1000; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project localtime_tz(&seconds, &(this->t), this->timezone); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 200