summaryrefslogtreecommitdiff
path: root/firmware/libc/gmtime.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/libc/gmtime.c')
-rw-r--r--firmware/libc/gmtime.c112
1 files changed, 112 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 @@
1/***************************************************************************
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>
25#include "time.h"
26
27#define MINUTE_SECONDS 60
28#define HOUR_SECONDS 3600
29#define DAY_SECONDS 86400
30#define WEEK_SECONDS 604800
31#define YEAR_SECONDS 31536000
32#define LEAP_YEAR_SECONDS 31622400
33
34/* Days in each month */
35static int days_in_month[] =
36 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
37
38static inline bool is_leapyear(int year)
39{
40 return (((year%4)==0) && (((year%100)!=0) || ((year%400)==0)));
41}
42
43struct tm *gmtime(const time_t *timep)
44{
45 static struct tm time;
46 return gmtime_r(timep, &time);
47}
48
49struct tm *gmtime_r(const time_t *timep, struct tm *tm)
50{
51 time_t seconds = *timep;
52 int year, i, mday, hour, min;
53
54 /* weekday */
55 tm->tm_wday = ((seconds % WEEK_SECONDS) / DAY_SECONDS + 4) % 7;
56
57 /* Year */
58 year = 1970;
59 while (seconds >= LEAP_YEAR_SECONDS)
60 {
61 if (is_leapyear(year)){
62 seconds -= LEAP_YEAR_SECONDS;
63 } else {
64 seconds -= YEAR_SECONDS;
65 }
66
67 year++;
68 }
69
70 if (is_leapyear(year)) {
71 days_in_month[1] = 29;
72 } else {
73 days_in_month[1] = 28;
74 if(seconds>YEAR_SECONDS){
75 year++;
76 seconds -= YEAR_SECONDS;
77 }
78 }
79 tm->tm_year = year%100 + 100;
80
81 /* Month */
82 for (i = 0; i < 12; i++)
83 {
84 if (seconds < days_in_month[i]*DAY_SECONDS){
85 tm->tm_mon = i;
86 break;
87 }
88
89 seconds -= days_in_month[i]*DAY_SECONDS;
90 }
91
92 /* Month Day */
93 mday = seconds/DAY_SECONDS;
94 seconds -= mday*DAY_SECONDS;
95 tm->tm_mday = mday + 1; /* 1 ... 31 */
96
97 /* Hour */
98 hour = seconds/HOUR_SECONDS;
99 seconds -= hour*HOUR_SECONDS;
100 tm->tm_hour = hour;
101
102 /* Minute */
103 min = seconds/MINUTE_SECONDS;
104 seconds -= min*MINUTE_SECONDS;
105 tm->tm_min = min;
106
107 /* Second */
108 tm->tm_sec = seconds;
109
110 return tm;
111}
112