1/*********************************************************************** 2* * 3* This software is part of the ast package * 4* Copyright (c) 1985-2011 AT&T Intellectual Property * 5* and is licensed under the * 6* Eclipse Public License, Version 1.0 * 7* by AT&T Intellectual Property * 8* * 9* A copy of the License is available at * 10* http://www.eclipse.org/org/documents/epl-v10.html * 11* (with md5 checksum b35adb5213ca9657e911e9befb180842) * 12* * 13* Information and Software Systems Research * 14* AT&T Research * 15* Florham Park NJ * 16* * 17* Glenn Fowler <gsf@research.att.com> * 18* David Korn <dgk@research.att.com> * 19* Phong Vo <kpv@research.att.com> * 20* * 21***********************************************************************/ 22#pragma prototyped 23/* 24 * Glenn Fowler 25 * AT&T Research 26 * 27 * Time_t conversion support 28 */ 29 30#include <tmx.h> 31 32#include "FEATURE/tmlib" 33 34/* 35 * convert Tm_t to Time_t 36 * 37 * if west==TM_LOCALZONE then the local timezone is used 38 * otherwise west is the number of minutes west 39 * of GMT with DST taken into account 40 * 41 * this routine works with a copy of Tm_t to avoid clashes 42 * with other tm*() that may return static Tm_t* 43 */ 44 45Time_t 46tmxtime(register Tm_t* tm, int west) 47{ 48 register Time_t t; 49 register Tm_leap_t* lp; 50 register int32_t y; 51 int n; 52 int sec; 53 time_t now; 54 struct tm* tl; 55 Tm_t* to; 56 Tm_t ts; 57 58 ts = *tm; 59 to = tm; 60 tm = &ts; 61 tmset(tm_info.zone); 62 tmfix(tm); 63 y = tm->tm_year; 64 if (y < 69 || y > (TMX_MAXYEAR - 1900)) 65 return TMX_NOTIME; 66 y--; 67 t = y * 365 + y / 4 - y / 100 + (y + (1900 - 1600)) / 400 - (1970 - 1901) * 365 - (1970 - 1901) / 4; 68 if ((n = tm->tm_mon) > 11) 69 n = 11; 70 y += 1901; 71 if (n > 1 && tmisleapyear(y)) 72 t++; 73 t += tm_data.sum[n] + tm->tm_mday - 1; 74 t *= 24; 75 t += tm->tm_hour; 76 t *= 60; 77 t += tm->tm_min; 78 t *= 60; 79 t += sec = tm->tm_sec; 80 if (west != TM_UTCZONE && !(tm_info.flags & TM_UTC)) 81 { 82 /* 83 * time zone adjustments 84 */ 85 86 if (west == TM_LOCALZONE) 87 { 88 t += tm_info.zone->west * 60; 89 if (!tm_info.zone->daylight) 90 tm->tm_isdst = 0; 91 else 92 { 93 y = tm->tm_year; 94 tm->tm_year = tmequiv(tm) - 1900; 95 now = tmxsec(tmxtime(tm, tm_info.zone->west)); 96 tm->tm_year = y; 97 if (!(tl = tmlocaltime(&now))) 98 return TMX_NOTIME; 99 if (tm->tm_isdst = tl->tm_isdst) 100 t += tm_info.zone->dst * 60; 101 } 102 } 103 else 104 { 105 t += west * 60; 106 if (!tm_info.zone->daylight) 107 tm->tm_isdst = 0; 108 else if (tm->tm_isdst < 0) 109 { 110 y = tm->tm_year; 111 tm->tm_year = tmequiv(tm) - 1900; 112 tm->tm_isdst = 0; 113 now = tmxsec(tmxtime(tm, tm_info.zone->west)); 114 tm->tm_year = y; 115 if (!(tl = tmlocaltime(&now))) 116 return TMX_NOTIME; 117 tm->tm_isdst = tl->tm_isdst; 118 } 119 } 120 } 121 else if (tm->tm_isdst) 122 tm->tm_isdst = 0; 123 *to = *tm; 124 if (tm_info.flags & TM_LEAP) 125 { 126 /* 127 * leap second adjustments 128 */ 129 130 for (lp = &tm_data.leap[0]; t < lp->time - (lp+1)->total; lp++); 131 t += lp->total; 132 n = lp->total - (lp+1)->total; 133 if (t <= (lp->time + n) && (n > 0 && sec > 59 || n < 0 && sec > (59 + n) && sec <= 59)) 134 t -= n; 135 } 136 return tmxsns(t, tm->tm_nsec); 137} 138