Java package java.time.*
partition to low-level C library. Fully refactored and memory optimization allow use in small
embedded applications, designed for SMT32 microcontrollers. Written on ANSI C and no external dependencies has been
used
Instant.h
- Single instantaneous point on the time-line. This might be used to record event time-stamps in the application. The epoch-seconds are measured from the standard of 1970-01-01 00:00:00 where instants after the epoch have positive values, and earlier instants have negative values.LocalTime.h
- A time without a time-zone in the ISO-8601 calendar system, such as 10:15:30. Represents a time, often viewed as hour-minute-second. Time is represented to milliseconds precision.LocalDate.h
- A date without a time-zone in the ISO-8601 calendar system, such as 2007-12-03. Represents a date, often viewed as year-month-day. Other date data, such as day-of-year, day-of-week and week-of-year, can also be calculatedLocalDateTime.h
- A date-time without a time-zone in the ISO-8601 calendar system, such as 2007-12-03T10:15:30. Represents a date-time, often viewed as year-month-day-hour-minute-second. Other date and time data, such as day-of-year, day-of-week and week-of-year, can also be calculatedZonedDateTime.h
- A date-time with a time-zone in the ISO-8601 calendar system, such as 2007-12-03T10:15:30+01:00 Europe/Paris. This structure stores all date and time fields, to a precision of milliseconds, and a time-zone, with a zone offset used to handle ambiguous local date-times.TimeZone.h
- Contains a time-zone offset from Greenwich/UTC, such as +02:00, or zone name Europe/Paris. Also contains historic rules for offset calculationTimeZoneNames.h
- Contains all time zone naming conventions, short and full name.TimeZoneRules.h
- The rules defining how the zone offset varies for a single time-zone.ValueRange.h
- Date-time range values, used for data validation.DateTimeMath.h
- Contains date-time calculation functions.GlobalDateTime.h
- All includes in one and also formatter for printing and parsing strings to date-time structs
- User friendly API
- No dynamic or static memory allocations
- All time zone support
- Rich functionality for creating time zones
- Daylight savings with historic rules support
- Epoch date/time functions
- String to date-time and vice versa
- Flexible string parsing to date-time
- No
time.h
library dependencies - Full test coverage
- Historic rules contains giant data capacity and can allocate up to 12Mb of flash memory. Such rules is used for daylight saving time calculation and can be disabled/reduced for memory saving. Also time zones can occupy large amount of memory, so them also can be disabled if not needed. By default, time zones and rules disabled and also rules has been reduced from 50 years to past and 50 years to future. So zone rules file size is not larger than 2.60 MB and can be stored in external memory.
- No locale support at now. So some date-time alignments hasn't implemented.
How to add CPM to the project, check the link
CPMAddPackage(
NAME GlobalDateTime
GITHUB_REPOSITORY ximtech/GlobalDateTime
GIT_TAG origin/main
OPTIONS
"ENABLE_TIME_ZONE_SUPPORT ON"
"ENABLE_TIME_ZONE_HISTORIC_RULES OFF"
)
target_link_libraries(${PROJECT_NAME} GlobalDateTime)
add_executable(${PROJECT_NAME}.elf ${SOURCES} ${LINKER_SCRIPT})
# For Clion STM32 plugin generated Cmake use
target_link_libraries(${PROJECT_NAME}.elf GlobalDateTime)
Note: see package description if only particular implementations needed
#include "GlobalDateTime.h"
Note: those function implementation should be at particular driver (RTC, Tick, Internet time) side.
Time time = timeNow();
Date date = dateNow();
Instant instant = instantNow();
DateTime dateTime = dateTimeNow();
ZonedDateTime zDateTime = zonedDateTimeNow(&UTC); // zoned date-time creation with time zone alignment and predefined UTC zone
Instant instant = instantOfEpochSeconds(1654540212); // Epoch time in seconds. GMT: Monday, 6 June 2022 year, 18:30:12
Instant instant = instantOfEpochSecondsAdjust(1654540212, 28800 * MICROS_PER_SECOND); // plus 8 hour adjustment
Instant instant = instantOfEpochMillis(1654559925246); // Epoch time in millis. UTC: Mon Jun 06 2022 23:58:45
Time time = timeOf(13, 22, 45); // hours, minutes, seconds
Time time = timeOfWithMillis(13, 22, 45, 678); // hours, minutes, seconds, milliseconds
Time time = timeOfHourAndMinutes(13, 22); // hours, minutes
Instant instant = instantOfEpochSeconds(1654540212); // GMT: Monday, 6 June 2022 year, 18:30:12
Time time = timeOfInstant(&instant, &UTC); // 18:30:12
Time time = timeOfSecondOfDay(86300); // 23:58:20:000
Time time = timeOfMillisOfDay(86300 * 1000); // 23:58:20:001
Time time = timeOfMicrosOfDay(86300 * 1000000LL); // 23:58:20:001
Date date = dateOf(2014, 7, 23);
Date date = dateOf(2014, JULY, 23); // with predefined month
Date date = dateOfEpochDay(3567); // 1979.10.08 Monday. Days count from 1970-01-01
Date date = dateOfYearDay(2014, 187); // 2014.07.06 Sunday. Days of year from 1 to 366
Instant instant = instantOfEpochSeconds(1654540212); // GMT: Monday, 6 June 2022 year, 18:30:12
Date date = dateOfInstant(&instant, &UTC); // 2022.06.06 Monday
DateTime dateTime = dateTimeOf(2008, JUNE, 23, 14, 6);
DateTime dateTime = dateTimeOfWithSeconds(2008, JUNE, 23, 14, 6, 45);
DateTime dateTime = dateTimeOfWithMillis(2008, JUNE, 23, 14, 6, 45, 436);
Date date = dateOf(2008, JUNE, 23);
Time time = timeOf(14, 6, 45);
DateTime dateTime = dateTimeFrom(&date, &time); // 2008.06.23 Monday 14:06:45
Instant instant = instantOfEpochSeconds(1654540212); // GMT: Monday, 6 June 2022 year, 18:30:12
DateTime dateTime = dateTimeOfInstant(&instant, &UTC); // 2022.06.06 Monday 18:30:12
DateTime dateTime = dateTimeOfEpochSeconds(1654540212, 1000000, UTC.utcOffset); // 2022.06.06 Monday 18:30:13
Date date = dateOf(2008, JUNE, 23);
DateTime dateTime = dateTimeAtStartOfDay(&date); // 2008.06.23 Monday 00:00:00
TimeZone zone1 = timeZoneOf("Z");
TimeZone zone2 = timeZoneOf("-0800");
TimeZone zone3 = timeZoneOf("+0810");
TimeZone zone4 = timeZoneOf("+08:10");
TimeZone zone5 = timeZoneOf("+08:10:20");
TimeZone zone6 = timeZoneOf("GMT+3");
TimeZone zone7 = timeZoneOf("UTC-8");
TimeZone zone8 = timeZoneOf("GMT+0800");
TimeZone zone9 = timeZoneOf("GMT+0825");
TimeZone zone10 = timeZoneOf("GMT+08:25");
TimeZone zone11 = timeZoneOf("GMT+08:25:10");
TimeZone zone12 = timeZoneOf("Europe/Paris"); // find by full name, also set zone DST rules and names
TimeZone customZone = { "Custom_Zone", 28800/*in seconds*/, UTC_ZONE_NAMES, NULL }; // zone with UTC names, offset of 8 hours and no DST rules
TimeZone zone = timeZoneOf("Europe/Paris");
ZonedDateTime zonedDateTime = zonedDateTimeOf(2014, AUGUST, 23, 16, 3, 56, 456, &zone); // 2014.08.23 Saturday 16:03:56:456
Date date = dateOf(2008, JUNE, 23);
Time time = timeOf(14, 6, 45);
TimeZone zone = timeZoneOf("-0800");
ZonedDateTime zonedDateTime = zonedDateTimeFrom(&date, &time, &zone);
DateTime dateTime = dateTimeOf(2008, JUNE, 23, 14, 6);
ZonedDateTime zonedDateTime = zonedDateTimeOfDateTime(&dateTime, &UTC);
TimeZone zone2 = timeZoneOf("+03:00");
Instant instant = instantOfEpochSeconds(1654540212); // GMT: Monday, 6 June 2022 year, 18:30:12
ZonedDateTime zonedDateTime = zonedDateTimeOfInstant(&instant, &zone2); // 2022.06.06 Monday 18:30:12
Create a zoned date-time from other zoned date-time (date and time adjustment according zone offset and DST rules)
TimeZone zoneParis = timeZoneOf("Europe/Paris");
TimeZone zoneGmt = timeZoneOf("GMT-14");
ZonedDateTime zonedDateTime4 = zonedDateTimeOf(2014, AUGUST, 23, 16, 3, 56, 456, &zoneParis); // UTC: 2014.08.23 Saturday 16:03:56:456
ZonedDateTime gmtDateTime = zonedDateTimeWithSameInstant(&zonedDateTime4, &zoneGmt); // GMT-14: 2014.08.23 Saturday 00:03:56:456
Check header files for full function description
Instant first = instantOfEpochSeconds(1654540212); // GMT: Monday, 6 June 2022 year, 18:30:12
instantPlusSeconds(&first, 1000);
instantPlusMillis(&first, 99999999);
instantMinusMicros(&first, 999999999); // 2022.06.07 22:16:51:999
int64_t epochMillis = instantToEpochMillis(&first);
Instant second = instantOfEpochMillis(epochMillis);
instantMinusMillis(&second, 10000); // 2022.06.07 22:16:41:999
printf("Is first after second: %s\n", isInstantAfter(&first, &second) ? "Yes" : "No"); // Yes
printf("Is second before first: %s\n", isInstantBefore(&second, &first) ? "Yes" : "No"); // Yes
printf("Is first equals second: %s\n", isInstantEquals(&first, &second) ? "Yes" : "No"); // No
Note: Time, Date and ZonedDateTime have same functionality
DateTime first = dateTimeOf(2007, FEBRUARY, 28, 12, 23); // Non leap year
dateTimePlusDays(&first, 1); // February have 28 days. 2007.03.01 12:23
dateTimePlusYears(&first, 1); // Moving to leap year
dateTimeMinusDays(&first, 1); // February have 29 days. 2008.02.29 12:23
dateTimePlusWeeks(&first, -2); // 2008.02.15 12:23
dateTimeMinusMonths(&first, 1); // 2008.01.15 12:23
dateTimePlusHours(&first, 36); // 2008.01.17 00:23
dateTimePlusMinutes(&first, 136); // 2008.01.17 02:39
dateTimePlusMillis(&first, 2345); // 2008.01.17 02:39:02:345
dateTimeMinusMillis(&first, 1000); // 2008.01.17 02:39:01:345
DateTime second = first;
dateTimeMinusWeeks(&second, 4); // Move to the previous year. 2007.12.20 02:39:01:345
printf("Is first after second: %s\n", isDateTimeAfter(&first, &second) ? "Yes" : "No"); // Yes
printf("Is second before first: %s\n", isDateTimeBefore(&second, &first) ? "Yes" : "No"); // Yes
printf("Is first equals second: %s\n", isDateTimeEquals(&first, &second) ? "Yes" : "No"); // No
Note: Time, Date and Instant have same functionality
DateTime baseDt = dateTimeOf(2023, DECEMBER, 7, 9, 0);
DateTime *startDt = dateTimeMinusMinutes(&DATE_TIME_COPY(baseDt), 5); // copy original date-time with macro
DateTime *endDt = dateTimePlusMinutes(&DATE_TIME_COPY(baseDt), 5);
DateTime now = dateTimeOf(2023, DECEMBER, 7, 9, 3);
printf("Is now between start and end: %s\n", isDateTimeBetween(&now, startDt, endDt) ? "Yes" : "No");
See below all available parser and format types
char buffer[64] = {0};
DateTimeFormatter formatter;
parseDateTimePattern(&formatter, "yyyy-MM-dd'T'HH:mm:ss.SSS ZZZZZ");
// ZonedDateTime to string
TimeZone zone = timeZoneOf("UTC+8");
ZonedDateTime zonedDateTime = zonedDateTimeOf(2008, JULY, 23, 14, 34, 23, 456, &zone);
formatZonedDateTime(&zonedDateTime, buffer, 64, &formatter);
printf("%s\n", buffer); // 2008-07-23T14:34:23.456 +08:00
//Convert String to DateTime
char *date = "Mon 2001/07/23 13:44:54:456";
DateTimeFormatter dateParser;
parseDateTimePattern(&dateParser, "EEE yyyy/MM/dd HH:mm:ss:SSS");
DateTime ldt = parseToDateTime(date, &dateParser);
if (isDateTimeValid(&ldt)) { // check that date-time parsed
printf("%s %lld-%02d-%02d %d:%d:%d:%d", // Monday 2001-07-23 13:44:54:456
getWeekDayNameLong(ldt.date.weekDay),
ldt.date.year,
ldt.date.month,
ldt.date.day,
ldt.time.hours,
ldt.time.minutes,
ldt.time.seconds,
ldt.time.millis);
}
- Daylight Saving Time (DST)
- Paris, normally UTC+1, has DST (add one hour = UTC+2) from 27/Mar to 30/Oct 2016. Review the above output, and the API can calculate and handle the DST correctly.
char buffer[64] = {0};
DateTimeFormatter formatter;
parseDateTimePattern(&formatter, "HHmm, dd MMM yyyy ZZZZ");
// Convert String to DateTime
char *date = "2016-08-22 14:30";
DateTimeFormatter dateParser;
parseDateTimePattern(&dateParser, "yyyy-MM-dd HH:mm");
DateTime ldt = parseToDateTime(date, &dateParser);
// Paris, 2016 Apr-Oct = DST, UTC+2, other months UTC+1
TimeZone parisZone = timeZoneOf("Europe/Paris");
ZonedDateTime parisDateTime = zonedDateTimeOfDateTime(&ldt, &parisZone);
// hard code a zone offset like this, UTC-5
TimeZone nyZone = timeZoneOf("-05:00");
ZonedDateTime nyDateTime = zonedDateTimeWithSameInstant(&parisDateTime, &nyZone);
zonedDateTimePlusHours(&nyDateTime, 8);
zonedDateTimePlusMinutes(&nyDateTime, 10);
formatZonedDateTime(&parisDateTime, buffer, 64, &formatter);
printf("Depart : %s\n", buffer); // Depart : 1430, 22 Aug 2016 GMT+02:00
memset(buffer, 0, 64);
formatZonedDateTime(&nyDateTime, buffer, 64, &formatter);
printf("Arrive : %s\n", buffer); // Arrive : 1540, 22 Aug 2016 GMT-05:00
Field Type | Symbol | Field patterns | Examples | Description |
---|---|---|---|---|
Year | y | y | 2, 20, 201, 2017, 20173 | Calendar year (numeric) |
yy | 02, 20, 01, 17, 73 | |||
yyy | 002, 020, 201, 2017, 20173 | |||
yyyy | 0002, 0020, 0201, 2017, 20173 | |||
yyyyy | 00002, 00020, 00201, 02017, 20173 | |||
u | u...uuuu | 4601 | Extended year (numeric). Works same as 'y' pattern | |
Month | M | M | 9, 12 | Month number/name |
MM | 09, 12 | |||
MMM | Sep | |||
MMMM | September | |||
Week | w | w | 8, 27 | Week of Year (numeric) |
ww | 08, 27 | |||
W | W | 3 | Week of Month (numeric) | |
Day | d | d | 1 | Day of month (numeric) |
dd | 01 | |||
D | D...DDD | 345 | Day of year (numeric) | |
F | F | 2 | Day of Week in Month (numeric). The example is for the 2nd Wed in July | |
Week day | E | E...EEE | Tue | Day of week name |
EEEE | Tuesday | |||
EEEEE | T | |||
Period | a | a | AM,PM | Uppercase by default |
Hour | h | h | 1, 12 | Hour [1-12] |
hh | 01, 12 | |||
H | H | 0, 23 | Hour [0-23] | |
HH | 00, 23 | |||
K | K | 0, 11 | Hour [0-11] | |
KK | 00, 11 | |||
k | k | 1, 24 | Hour [1-24] | |
kk | 01, 24 | |||
Minute | m | m | 8, 59 | Minute (numeric) |
mm | 08, 59 | |||
Second | s | s | 8, 12 | Second (numeric) |
ss | 08, 12 | |||
Millisecond | S | S | 1, 56, 678 | Fractional second (numeric) |
SS | 01, 56, 678 | |||
SSS | 001, 056, 678 | |||
Zone | z | z...zzz | PDT | Short non-location format |
zzzz | Pacific Daylight Time | Long non-location format | ||
Z | Z...ZZZ | -0800 | The ISO8601 basic format with hours | |
ZZZZ | GMT-8:00 | The long localized GMT format | ||
ZZZZZ | -08:00, -07:52:58 | The ISO8601 extended format with hours, minutes and optional seconds fields |
Field Type | Symbol | Field patterns | Examples |
---|---|---|---|
Year | y | y | 2 |
yy | 02, 20 | ||
yyy | 002, 020, 201 | ||
yyyy | 0002, 0020, 0201, 2017 | ||
yyyyy | 00002, 00020, 00201, 02017, 23017 | ||
Month | M | M | 9 |
MM | 09, 12 | ||
MMM | Sep | ||
MMMM | September | ||
Day | d | d | 1 |
dd | 01, 23 | ||
Week day | E | E...EEE | Tue |
EEEE | Tuesday | ||
EEEEE | T | ||
Period | a | a | AM, PM, am, pm |
Hour | h | h | 1 |
hh | 01, 12 | ||
H | H | 0 | |
HH | 00, 23 | ||
Minute | m | m | 8 |
mm | 08, 59 | ||
Second | s | s | 8 |
ss | 08, 12 | ||
Millisecond | S | S | 1 |
SS | 01, 56 | ||
SSS | 001, 056, 678 | ||
Zone | Z | Z | Z, GMT +0800, GMT-8:00, -08:00, -07:52:58, America/Los_Angeles |