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$ 00037 * Revision 1.8 2008/08/11 06:59:40 haraldkipp 00038 * BSD types replaced by stdint types (feature request #1282721). 00039 * 00040 * Revision 1.7 2005/08/02 17:46:47 haraldkipp 00041 * Major API documentation update. 00042 * 00043 * Revision 1.6 2004/10/14 16:43:00 drsung 00044 * Fixed compiler warning "comparison between signed and unsigned" 00045 * 00046 * Revision 1.5 2003/12/19 22:26:37 drsung 00047 * Dox written. 00048 * 00049 * Revision 1.4 2003/11/27 09:17:18 drsung 00050 * Wrong comment fixed 00051 * 00052 * Revision 1.3 2003/11/26 12:45:20 drsung 00053 * Portability issues ... again 00054 * 00055 * Revision 1.2 2003/11/26 11:13:17 haraldkipp 00056 * Portability issues 00057 * 00058 * Revision 1.1 2003/11/24 18:07:37 drsung 00059 * first release 00060 * 00061 * 00062 */ 00063 00064 #include <stdint.h> 00065 00066 #include <time.h> 00067 #include "ctime.h" 00068 00069 #define __need_NULL 00070 #include <stddef.h> 00071 00072 tm _tb; 00073 00074 /* static arrays used by gmtime to determine date and time 00075 * values. Shows days from being of year. 00076 ***************************************************************/ 00077 int _lpdays[] = { 00078 -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 00079 }; 00080 int _days[] = { 00081 -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 00082 }; 00083 00100 int gmtime_r(CONST time_t * timer, tm * ptm) 00101 { 00102 time_t ctimer = *timer; /* var to calculate with */ 00103 uint8_t isleapyear = 0; /* current year is leap year */ 00104 uint32_t tmptimer; 00105 int *mdays; /* pointer to _numdayslp or _numdays */ 00106 00107 if (ptm == NULL) /* check pointer */ 00108 return -1; 00109 00110 /* 00111 First calculate the number of four-year-interval, so calculation 00112 of leap year will be simple. Btw, because 2000 IS a leap year and 00113 2100 is out of range, this formula is so simple. 00114 */ 00115 tmptimer = (uint32_t) (ctimer / _FOUR_YEAR_SEC); 00116 ctimer -= ((time_t) tmptimer * _FOUR_YEAR_SEC); 00117 00118 /* Determine the correct year within the interval */ 00119 tmptimer = (tmptimer * 4) + 70; /* 1970, 1974, 1978,... */ 00120 if (ctimer >= (time_t)_YEAR_SEC) { 00121 tmptimer++; /* 1971, 1975, 1979,... */ 00122 ctimer -= _YEAR_SEC; 00123 if (ctimer >= (time_t)_YEAR_SEC) { 00124 tmptimer++; /* 1972, 1976, 1980,... (all leap years!) */ 00125 ctimer -= _YEAR_SEC; 00126 /* A leap year has 366 days, so compare to _YEAR_SEC + _DAY_SEC */ 00127 if (ctimer >= (time_t)(_YEAR_SEC + _DAY_SEC)) { 00128 tmptimer++; /* 1973, 1977, 1981,... */ 00129 ctimer -= (_YEAR_SEC + _DAY_SEC); 00130 } else 00131 isleapyear = 1; /*If leap year, set the flag */ 00132 } 00133 } 00134 00135 /* 00136 tmptimer now has the value for tm_year. ctimer now holds the 00137 number of elapsed seconds since the beginning of that year. 00138 */ 00139 ptm->tm_year = tmptimer; 00140 00141 /* 00142 Calculate days since January 1st and store it to tm_yday. 00143 Leave ctimer with number of elapsed seconds in that day. 00144 */ 00145 ptm->tm_yday = (int) (ctimer / _DAY_SEC); 00146 ctimer -= (time_t) (ptm->tm_yday) * _DAY_SEC; 00147 00148 /* 00149 Determine months since January (Note, range is 0 - 11) 00150 and day of month (range: 1 - 31) 00151 */ 00152 if (isleapyear) 00153 mdays = _lpdays; 00154 else 00155 mdays = _days; 00156 00157 00158 for (tmptimer = 1; mdays[tmptimer] < ptm->tm_yday; tmptimer++); 00159 00160 ptm->tm_mon = --tmptimer; 00161 00162 ptm->tm_mday = ptm->tm_yday - mdays[tmptimer]; 00163 00164 /* Calculate day of week. Sunday is 0 */ 00165 ptm->tm_wday = ((int) (*timer / _DAY_SEC) + _BASE_DOW) % 7; 00166 00167 /* Calculate the time of day from the remaining seconds */ 00168 ptm->tm_hour = (int) (ctimer / 3600); 00169 ctimer -= (time_t) ptm->tm_hour * 3600L; 00170 00171 ptm->tm_min = (int) (ctimer / 60); 00172 ptm->tm_sec = (int) (ctimer - (ptm->tm_min) * 60); 00173 00174 ptm->tm_isdst = 0; 00175 return 0; 00176 } 00177 00195 tm *gmtime(CONST time_t * timer) 00196 { 00197 if (gmtime_r(timer, &_tb)) 00198 return NULL; 00199 else 00200 return &_tb; 00201 } 00202