Skip to content

Instantly share code, notes, and snippets.

@MightyPork
Last active May 2, 2023 11:52
Show Gist options
  • Save MightyPork/9be8874c03e92bdc89164f3643ffc32e to your computer and use it in GitHub Desktop.
Save MightyPork/9be8874c03e92bdc89164f3643ffc32e to your computer and use it in GitHub Desktop.
Get weekday from a date, C version
/**
* 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