diff options
author | Bertrik Sikken <bertrik@sikken.nl> | 2012-03-08 21:21:31 +0100 |
---|---|---|
committer | Rafaël Carré <rafael.carre@gmail.com> | 2012-03-11 22:10:54 +0100 |
commit | 727e8aa6817be8816bc32184f2e2eb36b90b4a9e (patch) | |
tree | a5e8f7c50ba68bdd4a6ca60c2bdfdbde6a6d6bfd /firmware/libc | |
parent | 3448f5b6ad25f59e01ece347cb06e09652915e30 (diff) |
Introduce gmtime.c and use it in the AS3514 RTC driver
Change-Id: I00a09ae28a68f8153fb8fa854fea741ddfb0bf09
Reviewed-on: http://gerrit.rockbox.org/175
Tested-by: Bertrik Sikken <bertrik@sikken.nl>
Reviewed-by: Michael Sevakis <jethead71@rockbox.org>
Reviewed-by: Rafaël Carré <rafael.carre@gmail.com>
Diffstat (limited to 'firmware/libc')
-rw-r--r-- | firmware/libc/gmtime.c | 112 | ||||
-rw-r--r-- | firmware/libc/include/time.h | 2 |
2 files changed, 114 insertions, 0 deletions
diff --git a/firmware/libc/gmtime.c b/firmware/libc/gmtime.c new file mode 100644 index 0000000000..23b9c7b247 --- /dev/null +++ b/firmware/libc/gmtime.c @@ -0,0 +1,112 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2012 by Bertrik Sikken + * + * Based on code from: rtc_as3514.c + * Copyright (C) 2007 by Barry Wardell + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include <stdbool.h> +#include "time.h" + +#define MINUTE_SECONDS 60 +#define HOUR_SECONDS 3600 +#define DAY_SECONDS 86400 +#define WEEK_SECONDS 604800 +#define YEAR_SECONDS 31536000 +#define LEAP_YEAR_SECONDS 31622400 + +/* Days in each month */ +static int days_in_month[] = + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +static inline bool is_leapyear(int year) +{ + return (((year%4)==0) && (((year%100)!=0) || ((year%400)==0))); +} + +struct tm *gmtime(const time_t *timep) +{ + static struct tm time; + return gmtime_r(timep, &time); +} + +struct tm *gmtime_r(const time_t *timep, struct tm *tm) +{ + time_t seconds = *timep; + int year, i, mday, hour, min; + + /* weekday */ + tm->tm_wday = ((seconds % WEEK_SECONDS) / DAY_SECONDS + 4) % 7; + + /* Year */ + year = 1970; + while (seconds >= LEAP_YEAR_SECONDS) + { + if (is_leapyear(year)){ + seconds -= LEAP_YEAR_SECONDS; + } else { + seconds -= YEAR_SECONDS; + } + + year++; + } + + if (is_leapyear(year)) { + days_in_month[1] = 29; + } else { + days_in_month[1] = 28; + if(seconds>YEAR_SECONDS){ + year++; + seconds -= YEAR_SECONDS; + } + } + tm->tm_year = year%100 + 100; + + /* Month */ + for (i = 0; i < 12; i++) + { + if (seconds < days_in_month[i]*DAY_SECONDS){ + tm->tm_mon = i; + break; + } + + seconds -= days_in_month[i]*DAY_SECONDS; + } + + /* Month Day */ + mday = seconds/DAY_SECONDS; + seconds -= mday*DAY_SECONDS; + tm->tm_mday = mday + 1; /* 1 ... 31 */ + + /* Hour */ + hour = seconds/HOUR_SECONDS; + seconds -= hour*HOUR_SECONDS; + tm->tm_hour = hour; + + /* Minute */ + min = seconds/MINUTE_SECONDS; + seconds -= min*MINUTE_SECONDS; + tm->tm_min = min; + + /* Second */ + tm->tm_sec = seconds; + + return tm; +} + diff --git a/firmware/libc/include/time.h b/firmware/libc/include/time.h index 912fafe7ca..4796b8b083 100644 --- a/firmware/libc/include/time.h +++ b/firmware/libc/include/time.h @@ -34,6 +34,8 @@ typedef long time_t; #define _TIME_T_DECLARED time_t time(time_t *t); struct tm *localtime(const time_t *timep); +struct tm *gmtime(const time_t *timep); +struct tm *gmtime_r(const time_t *timep, struct tm *result); time_t mktime(struct tm *t); #endif /* SIMULATOR */ |