diff --git a/README.md b/README.md index 71bee39..42e97cb 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,12 @@ **ezTime - pronounced "Easy Time" - is a very easy to use Arduino time and date library that provides NTP network time lookups, extensive timezone support, formatted time and date strings, millisecond precision and more.** ->   * limitations may apply, see "[2036 and 2038](#2036-and-2038)" chapter +
* limitations may apply, see "2036 and 2038" chapter
  +
+ ## A brief history of ezTime I was working on [M5ez](https://github.com/ropg/M5ez), an interface library to easily make cool-looking programs for the "M5Stack" ESP32 hardware. The status bar of that needed to display the time. That was all, I swear. I figured I would use [Time](https://github.com/PaulStoffregen/Time), Paul Stoffregen's library to do time things on Arduino. Then I needed to sync that to an NTP server, so I figured I would use [NTPclient](https://github.com/arduino-libraries/NTPClient), one of the existing NTP client libraries. And then I wanted it to show the local time, so I would need some way for the user to set an offset between UTC and local time. @@ -22,7 +24,7 @@ Overlooking the battlefield after implementing some part of this, it seemed like **self-contained**: It only depends on other libraries to get online, but then it doesn't need other libraries for NTP and timezone data lookups. -**precise**: Unlike other libraries, ezTime does not throw away or mangle the fractional second information from the NTP server. An NTP request to pool.ntp.org only takes 40ms round-trip on home DSL these days, so adding sub-second precision to a time library makes sense. ezTime reads the fractional seconds and tries to account for network latency to give you precise time. + **precise**: Unlike other libraries, ezTime does not throw away or mangle the fractional second information from the NTP server. An NTP request to pool.ntp.org only takes 40ms round-trip on home DSL these days, so adding sub-second precision to a time library makes sense. ezTime reads the fractional seconds and tries to account for network latency to give you precise time. **backwards compatible**: Anything written for the existing Arduino time library will still work. You can set which timezone the sketch should be in, or have it be in UTC which is the default. But you can also set and express time referring to multiple timezones, all very easy and intuitive. @@ -197,13 +199,15 @@ For example, if you have set up a timezone called Berlin, `Berlin.isDST(15363142 ## How it all works - + ### What happens when you include the library It all starts when you include the library with `#include `. From that point forward there is an object instance called `ezTime` with methods to control the behaviour of ezTime, as well as a timezone object called `UTC`, and a reference to this object called `defaultTZ` (which you may point to a different timezone later). ### No daemons here + + It is important to understand what ezTime does NOT do. It does not somehow create a background process that keeps time, contacts servers, or whatever. The Arduino does the timekeeping for us with its `millis()` counter, which keeps the time in milliseconds since the Arduino started. All ezTime does when it synchronizes time is to store a time (in seconds since 1970) and the position of the millis counter when that was. By seeing how much the millis counter has advanced and adding that starting point since 1970, ezTime tells time. But that internal clock isn't perfect, it may - very slowly - drift away from the actual time. So periodically when you ask it something, it will discover that it's time to re-synchronize its own clock with the NTP server, and then it'll go out, do that and take, say, 50 ms longer to respond back to your code. But it all happens only when you ask for it. ### But I only just woke up ! @@ -272,9 +276,13 @@ Note that this function is used internally by ezTime, but does not by itself set   -## Timezones, caching and timezoneapi.com +## Timezones -Timezones are objects. They can be created with `Timezone yourTZ`, where `yourTZ` is the name you choose to refer to the timezone. In this manual, this name will be used from now on. But you can naturally choose any name you want. +> *If only it was as uncomplicated as this map suggests. Every band is actually made up of countries that all change to their Daylight Saving Time on different dates, and they even change the rules for when that happens frequently.* + +![](images/timezones.gif) + +Timezones in ezTime are objects. They can be created with `Timezone yourTZ`, where `yourTZ` is the name you choose to refer to the timezone. In this manual, this name will be used from now on. But you can naturally choose any name you want. Internally, ezTime stores everything it knows about a timezone as two strings. One is the official name of the timezone in "Olsen" format (like `Europe/Berlin`). That name is used to then update when needed all the other information needed to represent time in that timezone. This is in another string, in so-called "posix" format. It's often a little longer and for Berlin it is `CET-1CEST,M3.4.0/2,M10.4.0/3`. The elements of this string have the following meanings: @@ -480,6 +488,8 @@ bool yourTZ.minuteChanged(); ## Setting date and time manually +![](images/setting-clock.jpg) + `void yourTZ.setTime(time_t t, uint16_t ms = 0);` `void yourTZ.setTime(const uint8_t hr, const uint8_t min, const uint8_t sec, const uint8_t day, const uint8_t mnth, uint16_t yr)` diff --git a/images/clock-sync.png b/images/clock-sync.png new file mode 100644 index 0000000..c802b9e Binary files /dev/null and b/images/clock-sync.png differ diff --git a/images/moving-clock.gif b/images/moving-clock.gif new file mode 100644 index 0000000..ed84c63 Binary files /dev/null and b/images/moving-clock.gif differ diff --git a/images/setting-clock.jpg b/images/setting-clock.jpg new file mode 100644 index 0000000..a5c1bdc Binary files /dev/null and b/images/setting-clock.jpg differ diff --git a/images/stopwatch.png b/images/stopwatch.png new file mode 100644 index 0000000..778ac79 Binary files /dev/null and b/images/stopwatch.png differ diff --git a/images/timezones.gif b/images/timezones.gif new file mode 100644 index 0000000..6429e13 Binary files /dev/null and b/images/timezones.gif differ diff --git a/keywords.txt b/keywords.txt index b82fd26..a6fd73c 100644 --- a/keywords.txt +++ b/keywords.txt @@ -125,4 +125,34 @@ RFC3339 LITERAL1 RFC3339_EXT LITERAL1 RSS LITERAL1 W3C LITERAL1 - + + +#defines to make code more readable + +SUNDAY LITERAL1 +MONDAY LITERAL1 +TUESDAY LITERAL1 +WEDNESDAY LITERAL1 +THURSDAY LITERAL1 +FRIDAY LITERAL1 +SATURDAY LITERAL1 + +JANUARY LITERAL1 +FEBRUARI LITERAL1 +MARCH LITERAL1 +APRIL LITERAL1 +MAY LITERAL1 +JUNE LITERAL1 +JULY LITERAL1 +AUGUST LITERAL1 +SEPTEMBER LITERAL1 +OCTOBER LITERAL1 +NOVEMBER LITERAL1 +DECEMBER LITERAL1 + +FIRST LITERAL1 +SECOND LITERAL1 +THIRD LITERAL1 +FOURTH LITERAL1 +LAST LITERAL1 + diff --git a/src/ezTime.cpp b/src/ezTime.cpp index 8d84fd8..964d6ea 100644 --- a/src/ezTime.cpp +++ b/src/ezTime.cpp @@ -1304,7 +1304,7 @@ uint16_t Timezone::dayOfYear(time_t t /*= TIME_NOW */, ezLocalOrUTC_t local_or_u // definition for week 01 is the week with the Gregorian year's first Thursday in it. // See https://en.wikipedia.org/wiki/ISO_week_date // -#define startISOyear(args...) ezTime.makeOrdinalTime(0, 0, 0, 1, 5, 1, args) - 3UL * SECS_PER_DAY; +#define startISOyear(year...) ezTime.makeOrdinalTime(0, 0, 0, FIRST, THURSDAY, JANUARY, year) - 3UL * SECS_PER_DAY; uint8_t Timezone::weekISO(time_t t /*= TIME_NOW */, ezLocalOrUTC_t local_or_utc /* = LOCAL_TIME */) { t = tzTime(t, local_or_utc); int16_t yr = year(t); diff --git a/src/ezTime.h b/src/ezTime.h index f71fc1c..68dd353 100644 --- a/src/ezTime.h +++ b/src/ezTime.h @@ -68,6 +68,37 @@ typedef enum { UTC_TIME } ezLocalOrUTC_t; +// Defines that can make your code more readable. For example, if you are looking for the first +// Thursday in a year, you could write: ezTime.makeOrdinalTime(0, 0, 0, JANUARY, FIRST, THURSDAY, year) +// (As is done within ezTime to calculate ISO weeks) + +#define SUNDAY 1 +#define MONDAY 2 +#define TUESDAY 3 +#define WEDNESDAY 4 +#define THURSDAY 5 +#define FRIDAY 6 +#define SATURDAY 7 + +#define JANUARY 1 +#define FEBRUARI 2 +#define MARCH 3 +#define APRIL 4 +#define MAY 5 +#define JUNE 6 +#define JULY 7 +#define AUGUST 8 +#define SEPTEMBER 9 +#define OCTOBER 10 +#define NOVEMBER 11 +#define DECEMBER 12 + +#define FIRST 1 +#define SECOND 2 +#define THIRD 3 +#define FOURTH 4 +#define LAST 5 + #if defined(EZTIME_MAX_DEBUGLEVEL_NONE) #define err(args...) "" #define errln(args...) ""