Last active
May 2, 2023 11:52
-
-
Save MightyPork/9be8874c03e92bdc89164f3643ffc32e to your computer and use it in GitHub Desktop.
Get weekday from a date, C version
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Weekday calculation utils. | |
* | |
* Month and weekday are 1-based, 1 is Monday. | |
* The enums may be replaced by ints at the expense of clarity. | |
* | |
* Released to the public domain | |
*/ | |
#include <stdint.h> | |
#include <stdbool.h> | |
// Start year for weekday computation | |
// - reduces loop iteration count if we know older years won't be needed | |
#define DT_START_YEAR 2019 | |
// Weekday on January 1st of DT_START_YEAR | |
#define DT_START_WKDAY TUESDAY | |
enum weekday { | |
MONDAY = 1, | |
TUESDAY, | |
WEDNESDAY, | |
THURSDAY, | |
FRIDAY, | |
SATURDAY, | |
SUNDAY | |
}; | |
enum month { | |
JANUARY = 1, | |
FEBRUARY, | |
MARCH, | |
APRIL, | |
MAY, | |
JUNE, | |
JULY, | |
AUGUST, | |
SEPTEMBER, | |
OCTOBER, | |
NOVEMBER, | |
DECEMBER | |
}; | |
/** Days from Jan 1st to the 1st of a month */ | |
static const uint16_t MONTH_YEARDAYS[] = { | |
[JANUARY]=0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 | |
}; | |
/** Check if a year is leap */ | |
static inline bool is_leap_year(int year) | |
{ | |
return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0); | |
} | |
/** Get weekday */ | |
enum weekday date_weekday(uint16_t year, enum month month, uint8_t day) | |
{ | |
uint16_t i; | |
uint16_t days = (DT_START_WKDAY - MONDAY) + (year - DT_START_YEAR) * 365 + MONTH_YEARDAYS[month] + (day - 1); | |
for (i = DT_START_YEAR; i <= year; i++) { | |
if (is_leap_year(i) && (i < year || month > FEBRUARY)) days++; | |
} | |
return MONDAY + days % 7; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment