ENTS-tock
Environmental NeTworked Sensor firmware on Tock OS
Loading...
Searching...
No Matches
time.c
Go to the documentation of this file.
1#include "time.h"
2
3#include <libtock/peripherals/rtc.h>
4
5// Days in each month (non-leap year)
6static const uint8_t days_in_month[] = {31, 28, 31, 30, 31, 30,
7 31, 31, 30, 31, 30, 31};
8
9// Check if year is a leap year
10static inline int is_leap_year(uint16_t year) {
11 return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
12}
13
14// Get number of days in February for a given year
15static inline uint8_t get_feb_days(uint16_t year) {
16 return is_leap_year(year) ? 29 : 28;
17}
18
19uint32_t epoch(void) {
20 libtock_rtc_date_t date = {};
21 libtocksync_rtc_get_date(&date);
22 return rtc_date_to_epoch(&date);
23}
24
25void set_epoch(uint32_t epoch) {
26 libtock_rtc_date_t date = {};
28 libtocksync_rtc_set_date(&date);
29}
30
31uint32_t rtc_date_to_epoch(const libtock_rtc_date_t* date) {
32 // Unix epoch is January 1, 1970
33 const uint16_t epoch_year = 1970;
34 uint32_t total_seconds = 0;
35 uint16_t year;
36
37 // Count days from 1970 to the start of the current year
38 for (year = epoch_year; year < date->year; year++) {
39 total_seconds += is_leap_year(year) ? 366 : 365;
40 }
41 total_seconds *= 86400; // Convert days to seconds
42
43 // Count days from start of year to start of current month
44 uint32_t days = 0;
45 for (uint8_t month = 0; month < (date->month - 1); month++) {
46 days += days_in_month[month];
47 // Add leap day if February of a leap year
48 if (month == 1 && is_leap_year(date->year)) {
49 days++;
50 }
51 }
52 total_seconds += days * 86400;
53
54 // Add days of current month (day is 1-indexed, subtract 1)
55 total_seconds += (date->day - 1) * 86400;
56
57 // Add hours, minutes, seconds
58 total_seconds += (uint32_t)date->hour * 3600;
59 total_seconds += (uint32_t)date->minute * 60;
60 total_seconds += date->seconds;
61
62 return total_seconds;
63}
64
65void epoch_to_rtc_date(uint32_t epoch, libtock_rtc_date_t* date) {
66 const uint16_t epoch_year = 1970;
67
68 uint32_t days = epoch / 86400;
69 uint32_t seconds = epoch % 86400;
70
71 // Determine year
72 uint16_t year = epoch_year;
73 while (true) {
74 uint16_t days_in_year = is_leap_year(year) ? 366 : 365;
75 if (days < days_in_year) {
76 break;
77 }
78 days -= days_in_year;
79 year++;
80 }
81 date->year = year;
82
83 // Determine month
84 uint8_t month = 0;
85 while (true) {
86 uint8_t month_days = days_in_month[month];
87 if (month == 1 && is_leap_year(year)) {
88 month_days++;
89 }
90
91 if (days < month_days) {
92 break;
93 }
94
95 days -= month_days;
96 month++;
97 }
98 date->month = month + 1; // Convert to 1-indexed month
99
100 // Day of month (1-indexed)
101 date->day = days + 1;
102
103 // Time of day
104 date->hour = seconds / 3600;
105 seconds %= 3600;
106
107 date->minute = seconds / 60;
108 date->seconds = seconds % 60;
109}
uint32_t epoch(void)
Gets the current unix epoch timestamp.
Definition time.c:19
void set_epoch(uint32_t epoch)
Sets the current unix epoch timestamp.
Definition time.c:25
uint32_t rtc_date_to_epoch(const libtock_rtc_date_t *date)
Converts tock time to unix epoch time.
Definition time.c:31
void epoch_to_rtc_date(uint32_t epoch, libtock_rtc_date_t *date)
Convert unix epoch to tock time.
Definition time.c:65