00001 /* 00002 * Copyright (C) 2001-2003 by egnite Software GmbH. All rights reserved. 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions 00006 * are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the copyright holders nor the names of 00014 * contributors may be used to endorse or promote products derived 00015 * from this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS 00018 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00019 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00020 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE 00021 * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00022 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00023 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00024 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 00025 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00026 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 00027 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00028 * SUCH DAMAGE. 00029 * 00030 * For additional information see http://www.ethernut.de/ 00031 * 00032 * Portions of the following functions are derived from material which is 00033 * Copyright (c) 1985 by Microsoft Corporation. All rights are reserved. 00034 */ 00035 /* 00036 * $Log: gmtime.c,v $ 00037 * Revision 1.7 2005/08/02 17:46:47 haraldkipp 00038 * Major API documentation update. 00039 * 00040 * Revision 1.6 2004/10/14 16:43:00 drsung 00041 * Fixed compiler warning "comparison between signed and unsigned" 00042 * 00043 * Revision 1.5 2003/12/19 22:26:37 drsung 00044 * Dox written. 00045 * 00046 * Revision 1.4 2003/11/27 09:17:18 drsung 00047 * Wrong comment fixed 00048 * 00049 * Revision 1.3 2003/11/26 12:45:20 drsung 00050 * Portability issues ... again 00051 * 00052 * Revision 1.2 2003/11/26 11:13:17 haraldkipp 00053 * Portability issues 00054 * 00055 * Revision 1.1 2003/11/24 18:07:37 drsung 00056 * first release 00057 * 00058 * 00059 */ 00060 00061 #include <time.h> 00062 #include "ctime.h" 00063 00064 #define __need_NULL 00065 #include <stddef.h> 00066 00067 tm _tb; 00068 00069 /* static arrays used by gmtime to determine date and time 00070 * values. Shows days from being of year. 00071 ***************************************************************/ 00072 int _lpdays[] = { 00073 -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 00074 }; 00075 int _days[] = { 00076 -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 00077 }; 00078 00095 int gmtime_r(CONST time_t * timer, tm * ptm) 00096 { 00097 time_t ctimer = *timer; /* var to calculate with */ 00098 u_char isleapyear = 0; /* current year is leap year */ 00099 u_long tmptimer; 00100 int *mdays; /* pointer to _numdayslp or _numdays */ 00101 00102 if (ptm == NULL) /* check pointer */ 00103 return -1; 00104 00105 /* 00106 First calculate the number of four-year-interval, so calculation 00107 of leap year will be simple. Btw, because 2000 IS a leap year and 00108 2100 is out of range, this formula is so simple. 00109 */ 00110 tmptimer = (u_long) (ctimer / _FOUR_YEAR_SEC); 00111 ctimer -= ((time_t) tmptimer * _FOUR_YEAR_SEC); 00112 00113 /* Determine the correct year within the interval */ 00114 tmptimer = (tmptimer * 4) + 70; /* 1970, 1974, 1978,... */ 00115 if (ctimer >= (time_t)_YEAR_SEC) { 00116 tmptimer++; /* 1971, 1975, 1979,... */ 00117 ctimer -= _YEAR_SEC; 00118 if (ctimer >= (time_t)_YEAR_SEC) { 00119 tmptimer++; /* 1972, 1976, 1980,... (all leap years!) */ 00120 ctimer -= _YEAR_SEC; 00121 /* A leap year has 366 days, so compare to _YEAR_SEC + _DAY_SEC */ 00122 if (ctimer >= (time_t)(_YEAR_SEC + _DAY_SEC)) { 00123 tmptimer++; /* 1973, 1977, 1981,... */ 00124 ctimer -= (_YEAR_SEC + _DAY_SEC); 00125 } else 00126 isleapyear = 1; /*If leap year, set the flag */ 00127 } 00128 } 00129 00130 /* 00131 tmptimer now has the value for tm_year. ctimer now holds the 00132 number of elapsed seconds since the beginning of that year. 00133 */ 00134 ptm->tm_year = tmptimer; 00135 00136 /* 00137 Calculate days since January 1st and store it to tm_yday. 00138 Leave ctimer with number of elapsed seconds in that day. 00139 */ 00140 ptm->tm_yday = (int) (ctimer / _DAY_SEC); 00141 ctimer -= (time_t) (ptm->tm_yday) * _DAY_SEC; 00142 00143 /* 00144 Determine months since January (Note, range is 0 - 11) 00145 and day of month (range: 1 - 31) 00146 */ 00147 if (isleapyear) 00148 mdays = _lpdays; 00149 else 00150 mdays = _days; 00151 00152 00153 for (tmptimer = 1; mdays[tmptimer] < ptm->tm_yday; tmptimer++); 00154 00155 ptm->tm_mon = --tmptimer; 00156 00157 ptm->tm_mday = ptm->tm_yday - mdays[tmptimer]; 00158 00159 /* Calculate day of week. Sunday is 0 */ 00160 ptm->tm_wday = ((int) (*timer / _DAY_SEC) + _BASE_DOW) % 7; 00161 00162 /* Calculate the time of day from the remaining seconds */ 00163 ptm->tm_hour = (int) (ctimer / 3600); 00164 ctimer -= (time_t) ptm->tm_hour * 3600L; 00165 00166 ptm->tm_min = (int) (ctimer / 60); 00167 ptm->tm_sec = (int) (ctimer - (ptm->tm_min) * 60); 00168 00169 ptm->tm_isdst = 0; 00170 return 0; 00171 } 00172 00190 tm *gmtime(CONST time_t * timer) 00191 { 00192 if (gmtime_r(timer, &_tb)) 00193 return NULL; 00194 else 00195 return &_tb; 00196 } 00197