1da2e3ebdSchin /*********************************************************************** 2da2e3ebdSchin * * 3da2e3ebdSchin * This software is part of the ast package * 4*3e14f97fSRoger A. Faulkner * Copyright (c) 1985-2010 AT&T Intellectual Property * 5da2e3ebdSchin * and is licensed under the * 6da2e3ebdSchin * Common Public License, Version 1.0 * 77c2fbfb3SApril Chin * by AT&T Intellectual Property * 8da2e3ebdSchin * * 9da2e3ebdSchin * A copy of the License is available at * 10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt * 11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12da2e3ebdSchin * * 13da2e3ebdSchin * Information and Software Systems Research * 14da2e3ebdSchin * AT&T Research * 15da2e3ebdSchin * Florham Park NJ * 16da2e3ebdSchin * * 17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> * 18da2e3ebdSchin * David Korn <dgk@research.att.com> * 19da2e3ebdSchin * Phong Vo <kpv@research.att.com> * 20da2e3ebdSchin * * 21da2e3ebdSchin ***********************************************************************/ 22da2e3ebdSchin #pragma prototyped 23da2e3ebdSchin /* 24da2e3ebdSchin * Glenn Fowler 25da2e3ebdSchin * AT&T Research 26da2e3ebdSchin * 27da2e3ebdSchin * time conversion support 28da2e3ebdSchin */ 29da2e3ebdSchin 30da2e3ebdSchin #include <ast.h> 3134f9b3eeSRoland Mainz #include <tmx.h> 32da2e3ebdSchin 33da2e3ebdSchin #define DAYS(p) (tm_data.days[(p)->tm_mon]+((p)->tm_mon==1&&LEAP(p))) 34da2e3ebdSchin #define LEAP(p) (tmisleapyear((p)->tm_year)) 35da2e3ebdSchin 36da2e3ebdSchin /* 37da2e3ebdSchin * correct out of bounds fields in tm 38da2e3ebdSchin * 3934f9b3eeSRoland Mainz * tm_isdst is not changed -- call tmxtm() to get that 40da2e3ebdSchin * 41da2e3ebdSchin * tm is the return value 42da2e3ebdSchin */ 43da2e3ebdSchin 44da2e3ebdSchin Tm_t* tmfix(register Tm_t * tm)45da2e3ebdSchintmfix(register Tm_t* tm) 46da2e3ebdSchin { 47da2e3ebdSchin register int n; 48da2e3ebdSchin register int w; 49da2e3ebdSchin Tm_t* p; 50da2e3ebdSchin time_t t; 51da2e3ebdSchin 52da2e3ebdSchin /* 53da2e3ebdSchin * check for special case that adjusts tm_wday at the end 54da2e3ebdSchin * this happens during 55da2e3ebdSchin * nl_langinfo() => strftime() => tmfmt() 56da2e3ebdSchin */ 57da2e3ebdSchin 58da2e3ebdSchin if (w = !tm->tm_sec && !tm->tm_min && !tm->tm_mday && !tm->tm_year && !tm->tm_yday && !tm->tm_isdst) 59da2e3ebdSchin { 60da2e3ebdSchin tm->tm_year = 99; 61da2e3ebdSchin tm->tm_mday = 2; 62da2e3ebdSchin } 63da2e3ebdSchin 64da2e3ebdSchin /* 65da2e3ebdSchin * adjust from shortest to longest units 66da2e3ebdSchin */ 67da2e3ebdSchin 6834f9b3eeSRoland Mainz if ((n = tm->tm_nsec) < 0) 6934f9b3eeSRoland Mainz { 7034f9b3eeSRoland Mainz tm->tm_sec -= (TMX_RESOLUTION - n) / TMX_RESOLUTION; 7134f9b3eeSRoland Mainz tm->tm_nsec = TMX_RESOLUTION - (-n) % TMX_RESOLUTION; 7234f9b3eeSRoland Mainz } 7334f9b3eeSRoland Mainz else if (n >= TMX_RESOLUTION) 7434f9b3eeSRoland Mainz { 7534f9b3eeSRoland Mainz tm->tm_sec += n / TMX_RESOLUTION; 7634f9b3eeSRoland Mainz tm->tm_nsec %= TMX_RESOLUTION; 7734f9b3eeSRoland Mainz } 78da2e3ebdSchin if ((n = tm->tm_sec) < 0) 79da2e3ebdSchin { 80da2e3ebdSchin tm->tm_min -= (60 - n) / 60; 81da2e3ebdSchin tm->tm_sec = 60 - (-n) % 60; 82da2e3ebdSchin } 83da2e3ebdSchin else if (n > (59 + TM_MAXLEAP)) 84da2e3ebdSchin { 85da2e3ebdSchin tm->tm_min += n / 60; 86da2e3ebdSchin tm->tm_sec %= 60; 87da2e3ebdSchin } 88da2e3ebdSchin if ((n = tm->tm_min) < 0) 89da2e3ebdSchin { 90da2e3ebdSchin tm->tm_hour -= (60 - n) / 60; 91da2e3ebdSchin n = tm->tm_min = 60 - (-n) % 60; 92da2e3ebdSchin } 93da2e3ebdSchin if (n > 59) 94da2e3ebdSchin { 95da2e3ebdSchin tm->tm_hour += n / 60; 96da2e3ebdSchin tm->tm_min %= 60; 97da2e3ebdSchin } 98da2e3ebdSchin if ((n = tm->tm_hour) < 0) 99da2e3ebdSchin { 100da2e3ebdSchin tm->tm_mday -= (23 - n) / 24; 101da2e3ebdSchin tm->tm_hour = 24 - (-n) % 24; 102da2e3ebdSchin } 103da2e3ebdSchin else if (n >= 24) 104da2e3ebdSchin { 105da2e3ebdSchin tm->tm_mday += n / 24; 106da2e3ebdSchin tm->tm_hour %= 24; 107da2e3ebdSchin } 108da2e3ebdSchin if (tm->tm_mon >= 12) 109da2e3ebdSchin { 110da2e3ebdSchin tm->tm_year += tm->tm_mon / 12; 111da2e3ebdSchin tm->tm_mon %= 12; 112da2e3ebdSchin } 113da2e3ebdSchin else if (tm->tm_mon < 0) 114da2e3ebdSchin { 115da2e3ebdSchin tm->tm_year--; 116da2e3ebdSchin if ((tm->tm_mon += 12) < 0) 117da2e3ebdSchin { 118da2e3ebdSchin tm->tm_year += tm->tm_mon / 12; 119da2e3ebdSchin tm->tm_mon = (-tm->tm_mon) % 12; 120da2e3ebdSchin } 121da2e3ebdSchin } 122da2e3ebdSchin while (tm->tm_mday < -365) 123da2e3ebdSchin { 124da2e3ebdSchin tm->tm_year--; 125da2e3ebdSchin tm->tm_mday += 365 + LEAP(tm); 126da2e3ebdSchin } 127da2e3ebdSchin while (tm->tm_mday > 365) 128da2e3ebdSchin { 129da2e3ebdSchin tm->tm_mday -= 365 + LEAP(tm); 130da2e3ebdSchin tm->tm_year++; 131da2e3ebdSchin } 132da2e3ebdSchin while (tm->tm_mday < 1) 133da2e3ebdSchin { 134da2e3ebdSchin if (--tm->tm_mon < 0) 135da2e3ebdSchin { 136da2e3ebdSchin tm->tm_mon = 11; 137da2e3ebdSchin tm->tm_year--; 138da2e3ebdSchin } 139da2e3ebdSchin tm->tm_mday += DAYS(tm); 140da2e3ebdSchin } 141da2e3ebdSchin while (tm->tm_mday > (n = DAYS(tm))) 142da2e3ebdSchin { 143da2e3ebdSchin tm->tm_mday -= n; 144da2e3ebdSchin if (++tm->tm_mon > 11) 145da2e3ebdSchin { 146da2e3ebdSchin tm->tm_mon = 0; 147da2e3ebdSchin tm->tm_year++; 148da2e3ebdSchin } 149da2e3ebdSchin } 150da2e3ebdSchin if (w) 151da2e3ebdSchin { 152da2e3ebdSchin w = tm->tm_wday; 153da2e3ebdSchin t = tmtime(tm, TM_LOCALZONE); 154da2e3ebdSchin p = tmmake(&t); 155da2e3ebdSchin if (w = (w - p->tm_wday)) 156da2e3ebdSchin { 157da2e3ebdSchin if (w < 0) 158da2e3ebdSchin w += 7; 159da2e3ebdSchin tm->tm_wday += w; 160da2e3ebdSchin if ((tm->tm_mday += w) > DAYS(tm)) 161da2e3ebdSchin tm->tm_mday -= 7; 162da2e3ebdSchin } 163da2e3ebdSchin } 164da2e3ebdSchin tm->tm_yday = tm_data.sum[tm->tm_mon] + (tm->tm_mon > 1 && LEAP(tm)) + tm->tm_mday - 1; 165da2e3ebdSchin n = tm->tm_year + 1900 - 1; 166da2e3ebdSchin tm->tm_wday = (n + n / 4 - n / 100 + n / 400 + tm->tm_yday + 1) % 7; 167da2e3ebdSchin 168da2e3ebdSchin /* 169da2e3ebdSchin * tm_isdst is adjusted by tmtime() 170da2e3ebdSchin */ 171da2e3ebdSchin 172da2e3ebdSchin return tm; 173da2e3ebdSchin } 174