/*************************************************************************** * __________ __ ___. * 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 #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; }