Files
MentOS/mentos/src/klib/time.c
T
2023-08-24 12:17:16 -04:00

115 lines
3.3 KiB
C

/// @file time.c
/// @brief Clock functions.
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "io/debug.h"
#include "drivers/rtc.h"
#include "hardware/timer.h"
#include "io/port_io.h"
#include "stddef.h"
#include "stdio.h"
#include "time.h"
static const char *str_weekdays[] = { "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday" };
static const char *str_months[] = { "January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December" };
time_t sys_time(time_t *time)
{
tm_t curr_time;
gettime(&curr_time);
// January and February are counted as months 13 and 14 of the previous year.
if (curr_time.tm_mon <= 2) {
curr_time.tm_mon += 12;
curr_time.tm_year -= 1;
}
time_t t;
// Convert years to days
t = (365 * curr_time.tm_year) + (curr_time.tm_year / 4) - (curr_time.tm_year / 100) +
(curr_time.tm_year / 400);
// Convert months to days
t += (30 * curr_time.tm_mon) + (3 * (curr_time.tm_mon + 1) / 5) + curr_time.tm_mday;
// Unix time starts on January 1st, 1970
t -= 719561;
// Convert days to seconds
t *= 86400;
// Add hours, minutes and seconds
t += (3600 * curr_time.tm_hour) + (60 * curr_time.tm_min) + curr_time.tm_sec;
if (time) {
(*time) = t;
}
return t;
}
time_t difftime(time_t time1, time_t time2)
{
return time1 - time2;
}
/// @brief Computes day of week
/// @param y Year
/// @param m Month of year (in range 1 to 12)
/// @param d Day of month (in range 1 to 31)
/// @return Day of week (in range 1 to 7)
static inline int day_of_week(unsigned int y, unsigned int m, unsigned int d)
{
int h, j, k;
// January and February are counted as months 13 and 14 of the previous year
if (m <= 2) {
m += 12;
y -= 1;
}
// J is the century
j = (int)(y / 100);
// K the year of the century
k = (int)(y % 100);
// Compute H using Zeller's congruence
h = (int)(d + (26 * (m + 1) / 10) + k + (k / 4) + (5 * j) + (j / 4));
// Return the day of the week
return ((h + 5) % 7) + 1;
}
tm_t *localtime(const time_t *time)
{
static tm_t date;
unsigned int a, b, c, d, e, f;
time_t t = *time;
// Negative Unix time values are not supported
if (t < 1) {
t = 0;
}
//Retrieve hours, minutes and seconds
date.tm_sec = (int)(t % 60);
t /= 60;
date.tm_min = (int)(t % 60);
t /= 60;
date.tm_hour = (int)(t % 24);
t /= 24;
// Convert Unix time to date
a = (unsigned int)((4 * t + 102032) / 146097 + 15);
b = (t + 2442113 + a - (a / 4));
c = (20 * b - 2442) / 7305;
d = b - 365 * c - (c / 4);
e = d * 1000 / 30601;
f = d - e * 30 - e * 601 / 1000;
// January and February are counted as months 13 and 14 of the previous year
if (e <= 13) {
c -= 4716;
e -= 1;
} else {
c -= 4715;
e -= 13;
}
//Retrieve year, month and day
date.tm_year = (int)c;
date.tm_mon = (int)e;
date.tm_mday = (int)f;
// Calculate day of week.
date.tm_wday = day_of_week(date.tm_year, date.tm_mon, date.tm_mday);
return &date;
}