date_time.c
Go to the documentation of this file.
1 /**
2  * @file date_time.c
3  * @brief Date and time management
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  *
23  * @author Oryx Embedded SARL (www.oryx-embedded.com)
24  * @version 1.9.0
25  **/
26 
27 //Dependencies
28 #include <stdio.h>
29 #include <string.h>
30 #include "date_time.h"
31 
32 #if defined(_WIN32)
33  #include <time.h>
34 #endif
35 
36 //Days
37 static const char days[8][10] =
38 {
39  "",
40  "Monday",
41  "Tuesday",
42  "Wednesday",
43  "Thursday",
44  "Friday",
45  "Saturday",
46  "Sunday"
47 };
48 
49 //Months
50 static const char months[13][10] =
51 {
52  "",
53  "January",
54  "February",
55  "March",
56  "April",
57  "May",
58  "June",
59  "July",
60  "August",
61  "September",
62  "October",
63  "November",
64  "December"
65 };
66 
67 
68 /**
69  * @brief Format system time
70  * @param[in] time System time
71  * @param[out] str NULL-terminated string representing the specified time
72  * @return Pointer to the formatted string
73  **/
74 
76 {
77  uint16_t hours;
78  uint8_t minutes;
79  uint8_t seconds;
80  uint16_t milliseconds;
81  static char_t buffer[24];
82 
83  //Retrieve milliseconds
84  milliseconds = time % 1000;
85  time /= 1000;
86  //Retrieve seconds
87  seconds = time % 60;
88  time /= 60;
89  //Retrieve minutes
90  minutes = time % 60;
91  time /= 60;
92  //Retrieve hours
93  hours = time;
94 
95  //The str parameter is optional
96  if(!str)
97  str = buffer;
98 
99  //Format system time
100  if(hours > 0)
101  {
102  sprintf(str, "%" PRIu16 "h %02" PRIu8 "min %02" PRIu8 "s %03" PRIu16 "ms",
103  hours, minutes, seconds, milliseconds);
104  }
105  else if(minutes > 0)
106  {
107  sprintf(str, "%" PRIu8 "min %02" PRIu8 "s %03" PRIu16 "ms",
108  minutes, seconds, milliseconds);
109  }
110  else if(seconds > 0)
111  {
112  sprintf(str, "%" PRIu8 "s %03" PRIu16 "ms", seconds, milliseconds);
113  }
114  else
115  {
116  sprintf(str, "%" PRIu16 "ms", milliseconds);
117  }
118 
119  //Return a pointer to the formatted string
120  return str;
121 }
122 
123 
124 /**
125  * @brief Format date
126  * @param[in] date Pointer to a structure representing the date
127  * @param[out] str NULL-terminated string representing the specified date
128  * @return Pointer to the formatted string
129  **/
130 
131 const char_t *formatDate(const DateTime *date, char_t *str)
132 {
133  static char_t buffer[40];
134 
135  //The str parameter is optional
136  if(!str)
137  str = buffer;
138 
139  //Format date
140  if(date->dayOfWeek)
141  {
142  sprintf(str, "%s, %s %" PRIu8 ", %" PRIu16 " %02" PRIu8 ":%02" PRIu8 ":%02" PRIu8,
143  days[MIN(date->dayOfWeek, 7)], months[MIN(date->month, 12)], date->day,
144  date->year, date->hours, date->minutes, date->seconds);
145  }
146  else
147  {
148  sprintf(str, "%s %" PRIu8 ", %" PRIu16 " %02" PRIu8 ":%02" PRIu8 ":%02" PRIu8,
149  months[MIN(date->month, 12)], date->day, date->year,
150  date->hours, date->minutes, date->seconds);
151  }
152 
153  //Return a pointer to the formatted string
154  return str;
155 }
156 
157 
158 /**
159  * @brief Get current date and time
160  * @param[out] date Pointer to a structure representing the date and time
161  **/
162 
164 {
165  //Retrieve current time
166  time_t time = getCurrentUnixTime();
167 
168  //Convert Unix timestamp to date
170 }
171 
172 
173 /**
174  * @brief Get current time
175  * @return Unix timestamp
176  **/
177 
178 time_t getCurrentUnixTime(void)
179 {
180 #if defined(_WIN32)
181  //Retrieve current time
182  return time(NULL);
183 #else
184  //Not implemented
185  return 0;
186 #endif
187 }
188 
189 
190 /**
191  * @brief Convert Unix timestamp to date
192  * @param[in] t Unix timestamp
193  * @param[out] date Pointer to a structure representing the date and time
194  **/
195 
196 void convertUnixTimeToDate(time_t t, DateTime *date)
197 {
198  uint32_t a;
199  uint32_t b;
200  uint32_t c;
201  uint32_t d;
202  uint32_t e;
203  uint32_t f;
204 
205  //Negative Unix time values are not supported
206  if(t < 1)
207  t = 0;
208 
209  //Clear milliseconds
210  date->milliseconds = 0;
211 
212  //Retrieve hours, minutes and seconds
213  date->seconds = t % 60;
214  t /= 60;
215  date->minutes = t % 60;
216  t /= 60;
217  date->hours = t % 24;
218  t /= 24;
219 
220  //Convert Unix time to date
221  a = (uint32_t) ((4 * t + 102032) / 146097 + 15);
222  b = (uint32_t) (t + 2442113 + a - (a / 4));
223  c = (20 * b - 2442) / 7305;
224  d = b - 365 * c - (c / 4);
225  e = d * 1000 / 30601;
226  f = d - e * 30 - e * 601 / 1000;
227 
228  //January and February are counted as months 13 and 14 of the previous year
229  if(e <= 13)
230  {
231  c -= 4716;
232  e -= 1;
233  }
234  else
235  {
236  c -= 4715;
237  e -= 13;
238  }
239 
240  //Retrieve year, month and day
241  date->year = c;
242  date->month = e;
243  date->day = f;
244 
245  //Calculate day of week
246  date->dayOfWeek = computeDayOfWeek(c, e, f);
247 }
248 
249 
250 /**
251  * @brief Convert date to Unix timestamp
252  * @param[in] date Pointer to a structure representing the date and time
253  * @return Unix timestamp
254  **/
255 
256 time_t convertDateToUnixTime(const DateTime *date)
257 {
258  uint_t y;
259  uint_t m;
260  uint_t d;
261  uint32_t t;
262 
263  //Year
264  y = date->year;
265  //Month of year
266  m = date->month;
267  //Day of month
268  d = date->day;
269 
270  //January and February are counted as months 13 and 14 of the previous year
271  if(m <= 2)
272  {
273  m += 12;
274  y -= 1;
275  }
276 
277  //Convert years to days
278  t = (365 * y) + (y / 4) - (y / 100) + (y / 400);
279  //Convert months to days
280  t += (30 * m) + (3 * (m + 1) / 5) + d;
281  //Unix time starts on January 1st, 1970
282  t -= 719561;
283  //Convert days to seconds
284  t *= 86400;
285  //Add hours, minutes and seconds
286  t += (3600 * date->hours) + (60 * date->minutes) + date->seconds;
287 
288  //Return Unix time
289  return t;
290 }
291 
292 
293 /**
294  * @brief Compare dates
295  * @param[in] date1 Pointer to the first date
296  * @param[in] date2 Pointer to the second date
297  * @return Comparison result
298  **/
299 
300 int_t compareDateTime(const DateTime *date1, const DateTime *date2)
301 {
302  int_t res;
303 
304  //Perform comparison
305  if(date1->year < date2->year)
306  res = -1;
307  else if(date1->year > date2->year)
308  res = 1;
309  else if(date1->month < date2->month)
310  res = -1;
311  else if(date1->month > date2->month)
312  res = 1;
313  else if(date1->day < date2->day)
314  res = -1;
315  else if(date1->day > date2->day)
316  res = 1;
317  else if(date1->hours < date2->hours)
318  res = -1;
319  else if(date1->hours > date2->hours)
320  res = 1;
321  else if(date1->minutes < date2->minutes)
322  res = -1;
323  else if(date1->minutes > date2->minutes)
324  res = 1;
325  else if(date1->seconds < date2->seconds)
326  res = -1;
327  else if(date1->seconds > date2->seconds)
328  res = 1;
329  else if(date1->milliseconds < date2->milliseconds)
330  res = -1;
331  else if(date1->milliseconds > date2->milliseconds)
332  res = 1;
333  else
334  res = 0;
335 
336  //Return comparison result
337  return res;
338 }
339 
340 
341 /**
342  * @brief Calculate day of week
343  * @param[in] y Year
344  * @param[in] m Month of year (in range 1 to 12)
345  * @param[in] d Day of month (in range 1 to 31)
346  * @return Day of week (in range 1 to 7)
347  **/
348 
349 uint8_t computeDayOfWeek(uint16_t y, uint8_t m, uint8_t d)
350 {
351  uint_t h;
352  uint_t j;
353  uint_t k;
354 
355  //January and February are counted as months 13 and 14 of the previous year
356  if(m <= 2)
357  {
358  m += 12;
359  y -= 1;
360  }
361 
362  //J is the century
363  j = y / 100;
364  //K the year of the century
365  k = y % 100;
366 
367  //Compute H using Zeller's congruence
368  h = d + (26 * (m + 1) / 10) + k + (k / 4) + (5 * j) + (j / 4);
369 
370  //Return the day of the week
371  return ((h + 5) % 7) + 1;
372 }
uint32_t systime_t
Definition: compiler_port.h:44
uint8_t computeDayOfWeek(uint16_t y, uint8_t m, uint8_t d)
Calculate day of week.
Definition: date_time.c:349
char char_t
Definition: compiler_port.h:41
uint16_t year
Definition: date_time.h:46
uint8_t c
Definition: ndp.h:510
uint32_t time
uint8_t res[]
int_t compareDateTime(const DateTime *date1, const DateTime *date2)
Compare dates.
Definition: date_time.c:300
uint8_t minutes
Definition: date_time.h:51
void getCurrentDate(DateTime *date)
Get current date and time.
Definition: date_time.c:163
uint8_t m
Definition: ndp.h:299
uint8_t a
Definition: ndp.h:407
uint8_t day
Definition: date_time.h:48
const char_t * formatSystemTime(systime_t time, char_t *str)
Format system time.
Definition: date_time.c:75
time_t convertDateToUnixTime(const DateTime *date)
Convert date to Unix timestamp.
Definition: date_time.c:256
signed int int_t
Definition: compiler_port.h:42
uint8_t month
Definition: date_time.h:47
void convertUnixTimeToDate(time_t t, DateTime *date)
Convert Unix timestamp to date.
Definition: date_time.c:196
Date and time management.
uint32_t seconds
Definition: sntp_client.h:127
uint8_t seconds
Definition: date_time.h:52
#define MIN(a, b)
Definition: os_port.h:60
Date and time representation.
Definition: date_time.h:44
time_t getCurrentUnixTime(void)
Get current time.
Definition: date_time.c:178
uint8_t hours
Definition: date_time.h:50
unsigned int uint_t
Definition: compiler_port.h:43
uint8_t dayOfWeek
Definition: date_time.h:49
uint16_t milliseconds
Definition: date_time.h:53
uint8_t h
Definition: ndp.h:297
uint8_t b[6]
Definition: dtls_misc.h:130
const char_t * formatDate(const DateTime *date, char_t *str)
Format date.
Definition: date_time.c:131