diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-07-11 17:24:14 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-07-11 17:24:14 +0000 |
commit | fb117bfced091fd2ee5a32f2ab39b6d7a48e0676 (patch) | |
tree | 5ff18dab2d32ec4643b3d664522b3ed018d0f60c /nuttx/lib | |
parent | 4a528af5569e0385555ac4f5de09677f6bcef754 (diff) | |
download | px4-nuttx-fb117bfced091fd2ee5a32f2ab39b6d7a48e0676.tar.gz px4-nuttx-fb117bfced091fd2ee5a32f2ab39b6d7a48e0676.tar.bz2 px4-nuttx-fb117bfced091fd2ee5a32f2ab39b6d7a48e0676.zip |
mktime/gmtime_r moved and highly simplified
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1973 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/lib')
-rw-r--r-- | nuttx/lib/Makefile | 6 | ||||
-rw-r--r-- | nuttx/lib/lib_gmtimer.c | 310 | ||||
-rw-r--r-- | nuttx/lib/lib_mktime.c | 149 | ||||
-rw-r--r-- | nuttx/lib/lib_timeutils.c | 226 |
4 files changed, 689 insertions, 2 deletions
diff --git a/nuttx/lib/Makefile b/nuttx/lib/Makefile index e00eb5c8c..b2792cdf3 100644 --- a/nuttx/lib/Makefile +++ b/nuttx/lib/Makefile @@ -83,6 +83,8 @@ UNISTD_SRCS += lib_chdir.c lib_getcwd.c endif endif +TIME_SRCS = lib_mktime.c lib_gmtimer.c lib_timeutils.c + NET_SRCS = lib_htons.c lib_htonl.c lib_inetntoa.c lib_etherntoa.c LIBGEN_SRCS = lib_basename.c lib_dirname.c @@ -98,8 +100,8 @@ DQ_SRCS = dq_addlast.c dq_addfirst.c dq_addafter.c dq_addbefore.c \ DBG_SRCS = lib_dbg.c lib_dumpbuffer.c CSRCS = $(MISC_SRCS) $(STRING_SRCS) $(CTYPE_SRCS) $(STDIO_SRCS) $(STDLIB_SRCS) \ - $(MATH_SRCS) $(UNISTD_SRCS) $(NET_SRCS) $(LIBGEN_SRCS) $(REGEX_SRCS) \ - $(SQ_SRCS) $(DQ_SRCS) $(DBG_SRCS) + $(MATH_SRCS) $(UNISTD_SRCS) $(TIME_SRCS) $(NET_SRCS) $(LIBGEN_SRCS) \ + $(REGEX_SRCS) $(SQ_SRCS) $(DQ_SRCS) $(DBG_SRCS) COBJS = $(CSRCS:.c=$(OBJEXT)) SRCS = $(ASRCS) $(CSRCS) diff --git a/nuttx/lib/lib_gmtimer.c b/nuttx/lib/lib_gmtimer.c new file mode 100644 index 000000000..2758acd1a --- /dev/null +++ b/nuttx/lib/lib_gmtimer.c @@ -0,0 +1,310 @@ +/**************************************************************************** + * lib/lib_gmtimer.c + * + * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <sys/types.h> + +#include <time.h> +#include <errno.h> +#include <debug.h> + +#include <nuttx/time.h> + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Calendar/UTC conversion routines */ + +static void clock_utc2calendar(time_t utc, int *year, int *month, int *day); +#ifdef CONFIG_GREGORIAN_TIME +static void clock_utc2gregorian (time_t jdn, int *year, int *month, int *day); + +#ifdef CONFIG_JULIAN_TIME +static void clock_utc2julian(time_t jdn, int *year, int *month, int *day); +#endif /* CONFIG_JULIAN_TIME */ +#endif /* CONFIG_GREGORIAN_TIME */ + +/************************************************************************** + * Public Constant Data + **************************************************************************/ + +/**************************************************************************** + * Public Variables + ****************************************************************************/ + +/************************************************************************** + * Private Variables + **************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: clock_calendar2utc, clock_gregorian2utc, + * and clock_julian2utc + * + * Description: + * Calendar to UTC conversion routines. These conversions + * are based on algorithms from p. 604 of Seidelman, P. K. + * 1992. Explanatory Supplement to the Astronomical + * Almanac. University Science Books, Mill Valley. + * + ****************************************************************************/ + +#ifdef CONFIG_GREGORIAN_TIME +static void clock_utc2calendar(time_t utc, int *year, int *month, int *day) +{ +#ifdef CONFIG_JULIAN_TIME + + if (utc >= GREG_DUTC) + { + clock_utc2gregorian(utc + JD_OF_EPOCH, year, month, day); + } + else + { + clock_utc2julian (utc + JD_OF_EPOCH, year, month, day); + } + +#else /* CONFIG_JULIAN_TIME */ + + clock_utc2gregorian(utc + JD_OF_EPOCH, year, month, day); + +#endif /* CONFIG_JULIAN_TIME */ +} + +static void clock_utc2gregorian(time_t jd, int *year, int *month, int *day) +{ + long l, n, i, j, d, m, y; + + l = jd + 68569; + n = (4*l) / 146097; + l = l - (146097*n + 3)/4; + i = (4000*(l+1))/1461001; + l = l - (1461*i)/4 + 31; + j = (80*l)/2447; + d = l - (2447*j)/80; + l = j/11; + m = j + 2 - 12*l; + y = 100*(n-49) + i + l; + + *year = y; + *month = m; + *day = d; +} + +#ifdef CONFIG_JULIAN_TIME + +static void clock_utc2julian(time_t jd, int *year, int *month, int *day) +{ + long j, k, l, n, d, i, m, y; + + j = jd + 1402; + k = (j-1)/1461; + l = j - 1461*k; + n = (l-1)/365 - l/1461; + i = l - 365*n + 30; + j = (80*i)/2447; + d = i - (2447*j)/80; + i = j/11; + m = j + 2 - 12*i; + y = 4*k + n + i - 4716; + + *year = y; + *month = m; + *day = d; +} + +#endif /* CONFIG_JULIAN_TIME */ +#else/* CONFIG_GREGORIAN_TIME */ + +static void clock_utc2calendar(time_t days, int *year, int *month, int *day) +{ + int value; + int tmp; + boolean leapyear; + + /* There must be a better way to do this than the brute for method below */ + + value = 70; + for (;;) + { + /* Is this year a leap year (we'll need this later too) */ + + leapyear = clock_isleapyear(value + 1900); + + /* Get the number of days in the year */ + + tmp = (leapyear ? 366 : 365); + + /* Do we have that many days? */ + + if (days >= tmp) + { + /* Yes.. bump up the year */ + + value++; + days -= tmp; + } + else + { + /* Nope... then go handle months */ + + break; + } + } + + /* At this point, value has the year and days has number days into this year */ + + *year = value; + + /* Handle the month */ + + value = 0; /* zero-based */ + for (;;) + { + /* Get the number of days that occurred before the beginning of the next month */ + + tmp = g_daysbeforemonth[value + 1]; + if (value >= 2 && leapyear) + { + tmp++; + } + + /* Does that equal or exceed the number of days we have remaining? */ + + if (tmp >= days) + { + /* Yes.. this is the one we want. The 'days' for this number of days that + * occurred before this month. + */ + + days -= g_daysbeforemonth[value]; + break; + } + else + { + /* No... try the next month */ + + value++; + } + } + + /* At this point, value has the month into this year (zero based) and days has + * number of days into this month (zero based) + */ + + *month = value; + *day = days + 1; /* 1-based */ +} + +#endif /* CONFIG_GREGORIAN_TIME */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: gmtime_r + * + * Description: + * Time conversion (based on the POSIX API) + * + ****************************************************************************/ + +struct tm *gmtime_r(const time_t *clock, struct tm *result) +{ + time_t time; + time_t jdn; + int year; + int month; + int day; + int hour; + int min; + int sec; + + /* Get the seconds since the EPOCH */ + + time = *clock; + sdbg("clock=%d\n", (int)time); + + /* Convert to days, hours, minutes, and seconds since the EPOCH */ + + jdn = time / (24*60*60); + time -= (24*60*60) * jdn; + + hour = time / (60*60); + time -= (60*60) * hour; + + min = time / 60; + time -= 60 * min; + + sec = time; + + sdbg("hour=%d min=%d sec=%d\n", + (int)hour, (int)min, (int)sec); + + /* Convert the days since the EPOCH to calendar day */ + + clock_utc2calendar(jdn, &year, &month, &day); + + sdbg("jdn=%d year=%d month=%d day=%d\n", + (int)jdn, (int)year, (int)month, (int)day); + + /* Then return the struct tm contents */ + + result->tm_year = (int)year - 1900; + result->tm_mon = (int)month - 1; + result->tm_mday = (int)day; + result->tm_hour = (int)hour; + result->tm_min = (int)min; + result->tm_sec = (int)sec; + + return result; +} + diff --git a/nuttx/lib/lib_mktime.c b/nuttx/lib/lib_mktime.c new file mode 100644 index 000000000..594a0672b --- /dev/null +++ b/nuttx/lib/lib_mktime.c @@ -0,0 +1,149 @@ +/**************************************************************************** + * lib/lib_mktime.c + * + * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <sys/types.h> + +#include <time.h> +#include <debug.h> + +#include <nuttx/time.h> + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Public Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: mktime + * + * Description: + * Time conversion (based on the POSIX API) + * + ****************************************************************************/ + +#ifdef CONFIG_GREGORIAN_TIME +time_t mktime(struct tm *tp) +{ + time_t ret; + time_t jdn; + + /* Get the EPOCH-relative julian date from the calendar year, + * month, and date + */ + + jdn = clock_calendar2utc(tp->tm_year+1900, tp->tm_mon+1, tp->tm_mday); + sdbg("jdn=%d tm_year=%d tm_mon=%d tm_mday=%d\n", + (int)jdn, tp->tm_year, tp->tm_mon, tp->tm_mday); + + /* Return the seconds into the julian day. */ + + ret = ((jdn*24 + tp->tm_hour)*60 + tp->tm_min)*60 + tp->tm_sec; + sdbg("ret=%d tm_hour=%d tm_min=%d tm_sec=%d\n", + (int)ret, tp->tm_hour, tp->tm_min, tp->tm_sec); + + return ret; +} +#else + +/* Simple version that only works for dates within a (relatively) small range + * from the epoch. It does not handle earlier days on longer days where leap + * seconds, etc. apply. + */ + +time_t mktime(struct tm *tp) +{ + unsigned int days; + + /* Years since epoch in units of days (ignoring leap years). */ + + days = (tp->tm_year - 70) * 365; + + /* Add in the extra days for the leap years prior to the current year. */ + + days += (tp->tm_year - 69) >> 2; + + /* Add in the days up to the beginning of this month (ignoring any possible leap day). */ + + days += (time_t)g_daysbeforemonth[tp->tm_mon]; + + /* Add in the leap day for this year (months are zero based) */ + + if (tp->tm_mon >= 2 && clock_isleapyear(tp->tm_year + 1900)) + { + days++; + } + + /* Add in the days since the beginning of this month (days are 1-based). */ + + days += tp->tm_mday - 1; + + /* Then convert the seconds and add in hours, minutes, and seconds */ + + return ((days * 24 + tp->tm_hour) * 60 + tp->tm_min) * 60 + tp->tm_sec; +} +#endif /* CONFIG_GREGORIAN_TIME */ + diff --git a/nuttx/lib/lib_timeutils.c b/nuttx/lib/lib_timeutils.c new file mode 100644 index 000000000..31404edde --- /dev/null +++ b/nuttx/lib/lib_timeutils.c @@ -0,0 +1,226 @@ +/**************************************************************************** + * lib/lib_calendar2utc.c + * + * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <sys/types.h> + +#include <time.h> +#include <debug.h> + +#include <nuttx/time.h> + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Public Variables + ****************************************************************************/ + +#ifndef CONFIG_GREGORIAN_TIME +uint16 g_daysbeforemonth[13] = +{ + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 +}; +#endif + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: clock_gregorian2utc, clock_julian2utc + * + * Description: + * UTC conversion routines. These conversions are based + * on algorithms from p. 604 of Seidelman, P. K. 1992. + * Explanatory Supplement to the Astronomical Almanac. + * University Science Books, Mill Valley. + * + ****************************************************************************/ + +#ifdef CONFIG_GREGORIAN_TIME +static time_t clock_gregorian2utc(int year, int month, int day) +{ + int temp; + + /* temp = (month - 14)/12; */ + + temp = (month <= 2 ? -1:0); + + return (1461*(year + 4800 + temp))/4 + + (367*(month - 2 - 12*temp))/12 + - (3*((year + 4900 + temp)/100))/4 + day - 32075; +} + +#ifdef CONFIG_JULIAN_TIME +static time_t clock_julian2utc(int year, int month, int day) +{ + return 367*year + - (7*(year + 5001 + (month-9)/7))/4 + + (275*month)/9 + + day + 1729777; +} +#endif /* CONFIG_JULIAN_TIME */ +#endif /* CONFIG_GREGORIAN_TIME */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: clock_isleapyear + * + * Description: + * Return true if the specified year is a leap year + * + ****************************************************************************/ + +#ifndef CONFIG_GREGORIAN_TIME +int clock_isleapyear(int year) +{ + return year % 400 ? (year % 100 ? (year % 4 ? 0 : 1) : 0) : 1; +} +#endif /* !CONFIG_GREGORIAN_TIME */ + +/**************************************************************************** + * Function: clock_calendar2utc + * + * Description: + * Calendar/UTC conversion based on algorithms from p. 604 + * of Seidelman, P. K. 1992. Explanatory Supplement to + * the Astronomical Almanac. University Science Books, + * Mill Valley. + * + ****************************************************************************/ + +#ifdef CONFIG_GREGORIAN_TIME +time_t clock_calendar2utc(int year, int month, int day) +{ + int dyear; +#ifdef CONFIG_JULIAN_TIME + int isgreg; +#endif /* CONFIG_JULIAN_TIME */ + + /* Correct year & month ranges. Shift month into range 1-12 */ + + dyear = (month-1) / 12; + month -= 12 * dyear; + year += dyear; + + if (month < 1) + { + month += 12; + year -= 1; + } + +#ifdef CONFIG_JULIAN_TIME + /* Determine which calendar to use */ + + if (year > GREG_YEAR) + { + isgreg = TRUE; + } + else if (year < GREG_YEAR) + { + isgreg = FALSE; + } + else if (month > GREG_MONTH) + { + isgreg = TRUE; + } + else if (month < GREG_MONTH) + { + isgreg = FALSE; + } + else + { + isgreg = (day >= GREG_DAY); + } + + /* Calculate and return date */ + + if (isgreg) + { + return clock_gregorian2utc(year, month, day) - JD_OF_EPOCH; + } + else + { + return clock_julian2utc (year, month, day) - JD_OF_EPOCH; + } + +#else /* CONFIG_JULIAN_TIME */ + + return clock_gregorian2utc(year, month, day) - JD_OF_EPOCH; + +#endif /* CONFIG_JULIAN_TIME */ +} +#else +time_t clock_calendar2utc(int year, int month, int day) +{ + struct tm t; + + /* mktime can (kind of) do this */ + + t.tm_year = year; + t.tm_mon = month; + t.tm_mday = day; + t.tm_hour = 0; + t.tm_min = 0; + t.tm_sec = 0; + return mktime(&t); +} +#endif /* CONFIG_GREGORIAN_TIME */ + |