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-2025 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.5.0
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 parameter is optional
98  if(str == NULL)
99  {
100  str = buffer;
101  }
102 
103  //Format system time
104  if(hours > 0)
105  {
106  osSprintf(str, "%" PRIu16 "h %02" PRIu8 "min %02" PRIu8 "s %03" PRIu16 "ms",
107  hours, minutes, seconds, milliseconds);
108  }
109  else if(minutes > 0)
110  {
111  osSprintf(str, "%" PRIu8 "min %02" PRIu8 "s %03" PRIu16 "ms",
112  minutes, seconds, milliseconds);
113  }
114  else if(seconds > 0)
115  {
116  osSprintf(str, "%" PRIu8 "s %03" PRIu16 "ms", seconds, milliseconds);
117  }
118  else
119  {
120  osSprintf(str, "%" PRIu16 "ms", milliseconds);
121  }
122 
123  //Return a pointer to the formatted string
124  return str;
125 }
126 
127 
128 /**
129  * @brief Format date
130  * @param[in] date Pointer to a structure representing the date
131  * @param[out] str NULL-terminated string representing the specified date
132  * @return Pointer to the formatted string
133  **/
134 
135 const char_t *formatDate(const DateTime *date, char_t *str)
136 {
137  static char_t buffer[40];
138 
139  //The parameter is optional
140  if(str == NULL)
141  {
142  str = buffer;
143  }
144 
145  //Format date
146  if(date->dayOfWeek)
147  {
148  osSprintf(str, "%s, %s %" PRIu8 ", %" PRIu16 " %02" PRIu8 ":%02" PRIu8 ":%02" PRIu8,
149  days[MIN(date->dayOfWeek, 7)], months[MIN(date->month, 12)], date->day,
150  date->year, date->hours, date->minutes, date->seconds);
151  }
152  else
153  {
154  osSprintf(str, "%s %" PRIu8 ", %" PRIu16 " %02" PRIu8 ":%02" PRIu8 ":%02" PRIu8,
155  months[MIN(date->month, 12)], date->day, date->year,
156  date->hours, date->minutes, date->seconds);
157  }
158 
159  //Return a pointer to the formatted string
160  return str;
161 }
162 
163 
164 /**
165  * @brief Get current date and time
166  * @param[out] date Pointer to a structure representing the date and time
167  **/
168 
170 {
171  time_t time;
172 
173  //Retrieve current time
175 
176  //Convert Unix timestamp to date
178 }
179 
180 
181 /**
182  * @brief Get current time
183  * @return Unix timestamp
184  **/
185 
186 __weak_func time_t getCurrentUnixTime(void)
187 {
188 #if defined(_WIN32)
189  //Retrieve current time
190  return time(NULL);
191 #else
192  //Not implemented
193  return 0;
194 #endif
195 }
196 
197 
198 /**
199  * @brief Convert Unix timestamp to date
200  * @param[in] t Unix timestamp
201  * @param[out] date Pointer to a structure representing the date and time
202  **/
203 
204 void convertUnixTimeToDate(time_t t, DateTime *date)
205 {
206  uint32_t a;
207  uint32_t b;
208  uint32_t c;
209  uint32_t d;
210  uint32_t e;
211  uint32_t f;
212 
213  //Negative Unix time values are not supported
214  if(t < 1)
215  {
216  t = 0;
217  }
218 
219  //Clear milliseconds
220  date->milliseconds = 0;
221 
222  //Retrieve hours, minutes and seconds
223  date->seconds = t % 60;
224  t /= 60;
225  date->minutes = t % 60;
226  t /= 60;
227  date->hours = t % 24;
228  t /= 24;
229 
230  //Convert Unix time to date
231  a = (uint32_t) ((4 * t + 102032) / 146097 + 15);
232  b = (uint32_t) (t + 2442113 + a - (a / 4));
233  c = (20 * b - 2442) / 7305;
234  d = b - 365 * c - (c / 4);
235  e = d * 1000 / 30601;
236  f = d - e * 30 - e * 601 / 1000;
237 
238  //January and February are counted as months 13 and 14 of the previous year
239  if(e <= 13)
240  {
241  c -= 4716;
242  e -= 1;
243  }
244  else
245  {
246  c -= 4715;
247  e -= 13;
248  }
249 
250  //Retrieve year, month and day
251  date->year = c;
252  date->month = e;
253  date->day = f;
254 
255  //Calculate day of week
256  date->dayOfWeek = computeDayOfWeek(c, e, f);
257 }
258 
259 
260 /**
261  * @brief Convert date to Unix timestamp
262  * @param[in] date Pointer to a structure representing the date and time
263  * @return Unix timestamp
264  **/
265 
266 time_t convertDateToUnixTime(const DateTime *date)
267 {
268  uint_t y;
269  uint_t m;
270  uint_t d;
271  time_t t;
272 
273  //Year
274  y = date->year;
275  //Month of year
276  m = date->month;
277  //Day of month
278  d = date->day;
279 
280  //January and February are counted as months 13 and 14 of the previous year
281  if(m <= 2)
282  {
283  m += 12;
284  y -= 1;
285  }
286 
287  //Convert years to days
288  t = (365 * y) + (y / 4) - (y / 100) + (y / 400);
289  //Convert months to days
290  t += (30 * m) + (3 * (m + 1) / 5) + d;
291  //Unix time starts on January 1st, 1970
292  t -= 719561;
293  //Convert days to seconds
294  t *= 86400;
295  //Add hours, minutes and seconds
296  t += (3600 * date->hours) + (60 * date->minutes) + date->seconds;
297 
298  //Return Unix time
299  return t;
300 }
301 
302 
303 /**
304  * @brief Compare dates
305  * @param[in] date1 Pointer to the first date
306  * @param[in] date2 Pointer to the second date
307  * @return Comparison result
308  **/
309 
310 int_t compareDateTime(const DateTime *date1, const DateTime *date2)
311 {
312  int_t res;
313 
314  //Perform comparison
315  if(date1->year < date2->year)
316  {
317  res = -1;
318  }
319  else if(date1->year > date2->year)
320  {
321  res = 1;
322  }
323  else if(date1->month < date2->month)
324  {
325  res = -1;
326  }
327  else if(date1->month > date2->month)
328  {
329  res = 1;
330  }
331  else if(date1->day < date2->day)
332  {
333  res = -1;
334  }
335  else if(date1->day > date2->day)
336  {
337  res = 1;
338  }
339  else if(date1->hours < date2->hours)
340  {
341  res = -1;
342  }
343  else if(date1->hours > date2->hours)
344  {
345  res = 1;
346  }
347  else if(date1->minutes < date2->minutes)
348  {
349  res = -1;
350  }
351  else if(date1->minutes > date2->minutes)
352  {
353  res = 1;
354  }
355  else if(date1->seconds < date2->seconds)
356  {
357  res = -1;
358  }
359  else if(date1->seconds > date2->seconds)
360  {
361  res = 1;
362  }
363  else if(date1->milliseconds < date2->milliseconds)
364  {
365  res = -1;
366  }
367  else if(date1->milliseconds > date2->milliseconds)
368  {
369  res = 1;
370  }
371  else
372  {
373  res = 0;
374  }
375 
376  //Return comparison result
377  return res;
378 }
379 
380 
381 /**
382  * @brief Calculate day of week
383  * @param[in] y Year
384  * @param[in] m Month of year (in range 1 to 12)
385  * @param[in] d Day of month (in range 1 to 31)
386  * @return Day of week (in range 1 to 7)
387  **/
388 
389 uint8_t computeDayOfWeek(uint16_t y, uint8_t m, uint8_t d)
390 {
391  uint_t h;
392  uint_t j;
393  uint_t k;
394 
395  //January and February are counted as months 13 and 14 of the previous year
396  if(m <= 2)
397  {
398  m += 12;
399  y -= 1;
400  }
401 
402  //J is the century
403  j = y / 100;
404  //K the year of the century
405  k = y % 100;
406 
407  //Compute H using Zeller's congruence
408  h = d + (26 * (m + 1) / 10) + k + (k / 4) + (5 * j) + (j / 4);
409 
410  //Return the day of the week
411  return ((h + 5) % 7) + 1;
412 }
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:56
time_t convertDateToUnixTime(const DateTime *date)
Convert date to Unix timestamp.
Definition: date_time.c:266
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:204
uint8_t computeDayOfWeek(uint16_t y, uint8_t m, uint8_t d)
Calculate day of week.
Definition: date_time.c:389
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:234
void getCurrentDate(DateTime *date)
Get current date and time.
Definition: date_time.c:169
const char_t * formatDate(const DateTime *date, char_t *str)
Format date.
Definition: date_time.c:135
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:55
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:57
__weak_func time_t getCurrentUnixTime(void)
Get current time.
Definition: date_time.c:186
uint8_t c
Definition: ndp.h:514
int_t compareDateTime(const DateTime *date1, const DateTime *date2)
Compare dates.
Definition: date_time.c:310