Code Monkey home page Code Monkey logo

globaldatetime's Introduction

GlobalDateTime

tests codecov Codacy Badge

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

Package includes

  • 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 calculated
  • LocalDateTime.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 calculated
  • ZonedDateTime.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 calculation
  • TimeZoneNames.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

Features

  • 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

Trade-offs

  • 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.

Add as CPM project dependency

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)

Usage

Single include for all features

Note: see package description if only particular implementations needed

  #include "GlobalDateTime.h"

Get current date and time

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();

Get current date at UTC

  ZonedDateTime zDateTime = zonedDateTimeNow(&UTC); // zoned date-time creation with time zone alignment and predefined UTC zone

Create instant from epoch seconds

  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

Create a time (hour, minute, second, millis)

  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

Create a time from Instant

  Instant instant = instantOfEpochSeconds(1654540212); // GMT: Monday, 6 June 2022 year, 18:30:12
  Time time = timeOfInstant(&instant, &UTC);     // 18:30:12

Create a time from seconds, millis and micros of day

  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

Create a date (year, month, day)

  Date date = dateOf(2014, 7, 23);
  Date date = dateOf(2014, JULY, 23);  // with predefined month

Create a date (additional functions)

  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

Create a date from Instant

  Instant instant = instantOfEpochSeconds(1654540212); // GMT: Monday, 6 June 2022 year, 18:30:12
  Date date = dateOfInstant(&instant, &UTC); // 2022.06.06 Monday

Create a date-time (year, month, day, hour, minute, second, millisecond)

  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);

Create a date-time from Date and Time

  Date date = dateOf(2008, JUNE, 23);
  Time time = timeOf(14, 6, 45);
  DateTime dateTime = dateTimeFrom(&date, &time); // 2008.06.23 Monday 14:06:45

Create a date-time from Instant

  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

Create a date-time from epoch seconds, micro adjustment and time zone offset

  DateTime dateTime = dateTimeOfEpochSeconds(1654540212, 1000000, UTC.utcOffset); // 2022.06.06 Monday 18:30:13

Create a date-time at midnight

  Date date = dateOf(2008, JUNE, 23);
  DateTime dateTime = dateTimeAtStartOfDay(&date);   // 2008.06.23 Monday 00:00:00

Create time zone

  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

Create a zoned date-time

  TimeZone zone = timeZoneOf("Europe/Paris");
  ZonedDateTime zonedDateTime = zonedDateTimeOf(2014, AUGUST, 23, 16, 3, 56, 456, &zone);  // 2014.08.23 Saturday 16:03:56:456

Create a zoned date-time from Date and Time

  Date date = dateOf(2008, JUNE, 23);
  Time time = timeOf(14, 6, 45);
  TimeZone zone = timeZoneOf("-0800");
  ZonedDateTime zonedDateTime = zonedDateTimeFrom(&date, &time, &zone);

Create a zoned date-time from DateTime

  DateTime dateTime = dateTimeOf(2008, JUNE, 23, 14, 6);
  ZonedDateTime zonedDateTime = zonedDateTimeOfDateTime(&dateTime, &UTC);

Create a zoned date-time from Instant

  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

Instant manipulations

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

Date-time manipulations

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

Date-time between

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");

Formatting date-time and parsing string(Date, Time, DateTime, ZonedDateTime, TimeZone)

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);
  }

Zoned date-time feature (DST rules support)

  • 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

Supported format operators

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

Supported string parse operators

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

globaldatetime's People

Contributors

ximtech avatar

Stargazers

 avatar  avatar

Watchers

 avatar

Forkers

pinkyparadise

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.