1 #include "pico/util/datetime.h"
2 
3 #if !PICO_ON_DEVICE && __APPLE__
4 // if we're compiling with LLVM on Apple, __weak does something else, but we don't care about overriding these anyway on host builds
5 #define __datetime_weak
6 #else
7 #define __datetime_weak __weak
8 #endif
9 
pico_localtime_r(const time_t * time,struct tm * tm)10 __datetime_weak struct tm * pico_localtime_r(const time_t *time, struct tm *tm) {
11     return localtime_r(time, tm);
12 }
13 
pico_mktime(struct tm * tm)14 __datetime_weak time_t pico_mktime(struct tm *tm) {
15     return mktime(tm);
16 }
17 
18 #if PICO_INCLUDE_RTC_DATETIME
19 #include <stdio.h>
20 
21 static const char *DATETIME_MONTHS[12] = {
22         "January",
23         "February",
24         "March",
25         "April",
26         "May",
27         "June",
28         "July",
29         "August",
30         "September",
31         "October",
32         "November",
33         "December"
34 };
35 
36 static const char *DATETIME_DOWS[7] = {
37         "Sunday",
38         "Monday",
39         "Tuesday",
40         "Wednesday",
41         "Thursday",
42         "Friday",
43         "Saturday",
44 };
45 
datetime_to_str(char * buf,uint buf_size,const datetime_t * t)46 void datetime_to_str(char *buf, uint buf_size, const datetime_t *t) {
47     snprintf(buf,
48              buf_size,
49              "%s %d %s %d:%02d:%02d %d",
50              DATETIME_DOWS[t->dotw],
51              t->day,
52              DATETIME_MONTHS[t->month - 1],
53              t->hour,
54              t->min,
55              t->sec,
56              t->year);
57 };
58 
datetime_to_tm(const datetime_t * dt,struct tm * tm)59 void datetime_to_tm(const datetime_t *dt, struct tm *tm) {
60     tm->tm_year = dt->year - 1900;
61     tm->tm_mon = dt->month - 1;
62     tm->tm_mday = dt->day;
63     tm->tm_hour = dt->hour;
64     tm->tm_min = dt->min;
65     tm->tm_sec = dt->sec;
66 }
67 
tm_to_datetime(const struct tm * tm,datetime_t * dt)68 void tm_to_datetime(const struct tm *tm, datetime_t *dt) {
69     dt->year = (int16_t) (tm->tm_year + 1900); // 0..4095
70     dt->month = (int8_t) (tm->tm_mon + 1);     // 1..12, 1 is January
71     dt->day = (int8_t) tm->tm_mday;            // 1..28,29,30,31 depending on month
72     dt->dotw = (int8_t) tm->tm_wday;           // 0..6, 0 is Sunday
73     dt->hour = (int8_t) tm->tm_hour;           // 0..23
74     dt->min = (int8_t) tm->tm_min;             // 0..59
75     dt->sec = (int8_t) tm->tm_sec;             // 0..59
76 }
77 
time_to_datetime(time_t time,datetime_t * dt)78 bool time_to_datetime(time_t time, datetime_t *dt) {
79     struct tm local;
80     if (pico_localtime_r(&time, &local)) {
81         tm_to_datetime(&local, dt);
82         return true;
83     }
84     return false;
85 }
86 
datetime_to_time(const datetime_t * dt,time_t * time)87 bool datetime_to_time(const datetime_t *dt, time_t *time) {
88     struct tm local;
89     datetime_to_tm(dt, &local);
90     *time = pico_mktime(&local);
91     return *time >= 0;
92 }
93 
94 #endif
95 
timespec_to_ms(const struct timespec * ts)96 uint64_t timespec_to_ms(const struct timespec *ts) {
97     int64_t rc = ts->tv_sec * 1000;
98     rc += ts->tv_nsec / 1000000;
99     return (uint64_t) rc;
100 }
101 
ms_to_timespec(uint64_t ms,struct timespec * ts)102 void ms_to_timespec(uint64_t ms, struct timespec *ts) {
103     ts->tv_sec = (time_t)((int64_t)ms / 1000);
104     ts->tv_nsec = ((long)((int64_t)ms % 1000)) * 1000000;
105 }
106 
timespec_to_us(const struct timespec * ts)107 uint64_t timespec_to_us(const struct timespec *ts) {
108     int64_t rc = ts->tv_sec * 1000000;
109     rc += ts->tv_nsec / 1000;
110     return (uint64_t) rc;
111 }
112 
us_to_timespec(uint64_t ms,struct timespec * ts)113 void us_to_timespec(uint64_t ms, struct timespec *ts) {
114     ts->tv_sec = (time_t)((int64_t)ms / 1000000);
115     ts->tv_nsec = ((long)((int64_t)ms % 1000000)) * 1000;
116 }
117 
118