blob: 89960ce83be5a4115ddab4233389cb8f9e74f9bb [file] [log] [blame]
Bertrik Sikken727e8aa2012-03-08 21:21:31 +01001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2012 by Bertrik Sikken
11 *
12 * Based on code from: rtc_as3514.c
13 * Copyright (C) 2007 by Barry Wardell
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24#include <stdbool.h>
Rafaël Carréd2aafd12012-03-11 17:15:56 -040025#include <stdint.h>
Bertrik Sikken727e8aa2012-03-08 21:21:31 +010026#include "time.h"
27
28#define MINUTE_SECONDS 60
29#define HOUR_SECONDS 3600
30#define DAY_SECONDS 86400
31#define WEEK_SECONDS 604800
32#define YEAR_SECONDS 31536000
33#define LEAP_YEAR_SECONDS 31622400
34
35/* Days in each month */
Rafaël Carréd2aafd12012-03-11 17:15:56 -040036static uint8_t days_in_month[] =
Bertrik Sikken727e8aa2012-03-08 21:21:31 +010037 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
38
39static inline bool is_leapyear(int year)
40{
41 return (((year%4)==0) && (((year%100)!=0) || ((year%400)==0)));
42}
43
44struct tm *gmtime(const time_t *timep)
45{
46 static struct tm time;
47 return gmtime_r(timep, &time);
48}
49
50struct tm *gmtime_r(const time_t *timep, struct tm *tm)
51{
52 time_t seconds = *timep;
53 int year, i, mday, hour, min;
54
55 /* weekday */
56 tm->tm_wday = ((seconds % WEEK_SECONDS) / DAY_SECONDS + 4) % 7;
57
58 /* Year */
59 year = 1970;
60 while (seconds >= LEAP_YEAR_SECONDS)
61 {
62 if (is_leapyear(year)){
63 seconds -= LEAP_YEAR_SECONDS;
64 } else {
65 seconds -= YEAR_SECONDS;
66 }
67
68 year++;
69 }
70
71 if (is_leapyear(year)) {
72 days_in_month[1] = 29;
73 } else {
74 days_in_month[1] = 28;
75 if(seconds>YEAR_SECONDS){
76 year++;
77 seconds -= YEAR_SECONDS;
78 }
79 }
80 tm->tm_year = year%100 + 100;
81
82 /* Month */
83 for (i = 0; i < 12; i++)
84 {
85 if (seconds < days_in_month[i]*DAY_SECONDS){
86 tm->tm_mon = i;
87 break;
88 }
89
90 seconds -= days_in_month[i]*DAY_SECONDS;
91 }
92
93 /* Month Day */
94 mday = seconds/DAY_SECONDS;
95 seconds -= mday*DAY_SECONDS;
96 tm->tm_mday = mday + 1; /* 1 ... 31 */
97
98 /* Hour */
99 hour = seconds/HOUR_SECONDS;
100 seconds -= hour*HOUR_SECONDS;
101 tm->tm_hour = hour;
102
103 /* Minute */
104 min = seconds/MINUTE_SECONDS;
105 seconds -= min*MINUTE_SECONDS;
106 tm->tm_min = min;
107
108 /* Second */
109 tm->tm_sec = seconds;
110
111 return tm;
112}
113