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