AceTime  2.2.0
Date and time classes for Arduino that support timezones from the TZ Database.
EpochConverterHinnant.h
1 /*
2  * MIT License
3  * Copyright (c) 2022 Brian T. Park
4  */
5 
6 #ifndef ACE_TIME_EPOCH_CONVERTER_HINNANT_H
7 #define ACE_TIME_EPOCH_CONVERTER_HINNANT_H
8 
9 #include <stdint.h>
10 
11 namespace ace_time {
12 namespace internal {
13 
20  public:
25  static const int16_t kConverterEpochYear = 2000;
26 
31  static const int32_t kDaysToConverterEpochFromUnixEpoch = 10957;
32 
49  static int32_t toEpochDays(int16_t year, uint8_t month, uint8_t day) {
50  uint16_t yearPrime = year - ((month <= 2) ? 1 : 0);
51  uint16_t era = yearPrime / 400; // [0,24]
52  uint16_t yearOfEra = yearPrime - 400 * era; // [0,399]
53 
54  uint8_t monthPrime = (month <= 2) ? month + 9 : month - 3; // [0,11]
55  uint16_t daysUntilMonthPrime = toDaysUntilMonthPrime(monthPrime);
56  uint16_t dayOfYearPrime = daysUntilMonthPrime + day - 1; // [0,365]
57  uint32_t dayOfEra = (uint32_t) 365 * yearOfEra + (yearOfEra / 4)
58  - (yearOfEra / 100) + dayOfYearPrime; // [0, 146096]
59 
60  int32_t dayOfEpochPrime = dayOfEra + 146097 * era;
61  return dayOfEpochPrime
62  - (kConverterEpochYear / 400) * 146097 /*relative to 2000-03-01*/
63  + 60 /*relative to 2000-01-01, 2000 is a leap year*/;
64  }
65 
77  static void fromEpochDays(int32_t epochDays,
78  int16_t& year, uint8_t& month, uint8_t& day) {
79 
80  int32_t dayOfEpochPrime = epochDays
81  + (kConverterEpochYear / 400) * 146097 - 60;
82  uint16_t era = (uint32_t) dayOfEpochPrime / 146097; // [0,24]
83  uint32_t dayOfEra = dayOfEpochPrime - 146097 * era; // [0,146096]
84  uint16_t yearOfEra = (dayOfEra - dayOfEra / 1460 + dayOfEra / 36524
85  - dayOfEra / 146096) / 365; // [0,399]
86  uint16_t yearPrime = yearOfEra + 400 * era; // [0,9999]
87  uint16_t dayOfYearPrime = dayOfEra - (365 * yearOfEra + yearOfEra/4
88  - yearOfEra/100);
89  uint8_t monthPrime = (5 * dayOfYearPrime + 2) / 153;
90  uint16_t daysUntilMonthPrime = toDaysUntilMonthPrime(monthPrime);
91 
92  day = dayOfYearPrime - daysUntilMonthPrime + 1; // [1,31]
93  month = (monthPrime < 10) ? monthPrime + 3 : monthPrime - 9; // [1,12]
94  year = yearPrime + ((month <= 2) ? 1 : 0); // [1,9999]
95  }
96 
101  static uint16_t toDaysUntilMonthPrime(uint8_t monthPrime) {
102  return (153 * monthPrime + 2) / 5;
103  }
104 };
105 
106 }
107 }
108 
109 #endif
Utility class that converts AceTime epoch days to (year, month, day) in the Gregorian calendar and vi...
static void fromEpochDays(int32_t epochDays, int16_t &year, uint8_t &month, uint8_t &day)
Extract the (year, month, day) fields from AceTime epochDays.
static const int16_t kConverterEpochYear
Epoch year used by this epoch converter.
static uint16_t toDaysUntilMonthPrime(uint8_t monthPrime)
Return the number days before the given monthPrime.
static const int32_t kDaysToConverterEpochFromUnixEpoch
Number of days from Unix epoch (1970-01-01 00:00:00 UTC) to the converter epoch (2000-01-01 00:00:00 ...
static int32_t toEpochDays(int16_t year, uint8_t month, uint8_t day)
Convert (year, month, day) in the Gregorian calendar to days since the converter epoch (2000-01-01 in...