@@ -36,7 +36,7 @@ Here is the dependency diagram among these projects.
3636 AceTimeTools --------
3737 ^ ^ ^ \ artransformer.py
3838 creating / | \ creating \ -> bufestimator.py
39- zonedb[x] / | \ zonedbpy \ -> zone_processor.py
39+ zonedb[x] / | \ zonedb \ -> zone_processor.py
4040 / | \ v
4141 AceTime | AceTimePython
4242 ^ ^ | ^
@@ -54,7 +54,7 @@ the buffer sizes needed by the C++ `ExtendedZoneProcessor` class. The
5454module to calculate those buffer sizes.
5555
5656On the other hand, AceTimePython needs AceTimeTools to generate the zoneinfo
57- files under ` AceTimePython/zonedbpy ` , which are consumed by the ` acetz.py `
57+ files under ` AceTimePython/zonedb ` , which are consumed by the ` acetz.py `
5858module. Fortunately, AceTimePython does * not* need AceTimeTools during runtime,
5959so 3rd party consumers can incorporate AceTimePython without pulling in
6060AceTimeTools.
@@ -289,31 +289,60 @@ SAVE (15-min resolution)
289289<a name =" ExtendedZoneProcessor " ></a >
290290## ExtendedZoneProcessor
291291
292- To save memory, the ` ExtendedZoneProcessor ` class calculates the ` Transition `
293- objects on the fly when the ` initForEpochSeconds(acetime_t) ` or
294- ` initForYear(int16_t) ` method is called. The alternative used by most Date-Time
295- libraries to precalculate the Transitions for all Zones, for a certain range of
296- years. Precalculation is definitely faster, and easier because the logic for
297- calculating the Transition objects resides in only a single place. However, the
298- expansion of the Transition objects consumes too much memory on an embedded
299- microcontrollers.
300-
301- When a request to create a ` ZonedDateTime ` object comes in, the
302- ` ExtendedZoneProcessor.findTransition(epochSeconds) ` method is called. It scans
303- the list of Transitions calculated above, looking for a match. The matching
304- Transition object contains the relevant standard offset and DST offset of that
305- Zone.
306-
307- The calculation of the Transitions is very complex, and I find that I can no
308- longer understand my own code after a few months away of this code base. So here
309- are some notes to help my future-self. The code is in
310- ` Transition::initForYear(int16_t) ` and is organized into 5 steps as described
311- below.
292+ There are 2 fundamental ways that a ` ZonedDateTime ` can be constructed:
293+
294+ 1 ) Using its human-readable components and its timezone through the
295+ ` ZonedDateTime::forComponents() ` factory method. The human-readable date can be:
296+ * An undefined time in a DST gap, or
297+ * A duplicate time during a DST overlap.
298+ 2 ) Using the epochSeconds and its timezone through the
299+ ` ZoneDateTime::forEpochSeconds() ` factory method.
300+ * The epochSeconds always specifies a well-defined unique time.
301+
302+ The call stack of the first method looks like this:
303+
304+ ```
305+ ZoneDateTime::forComponents()
306+ -> TimeZone::getOffsetDateTime(LocalDateTime&)
307+ -> ExtendeZoneProcessor::getOffsetDateTime(LocalDateTime&)
308+ -> TransitionStorage::findTransitionForDateTime(LocalDateTime&)
309+ ```
310+
311+ The call stack of the second method looks like this:
312+
313+ ```
314+ ZoneDateTime::forEpochSeconds(acetime_t)
315+ -> TimeZone::getUtcOffset(acetime_t)
316+ -> ExtendedZoneProcessor::getUtcOffset(acetime_t)
317+ -> TransitionStorage::findTransitionForSeconds(acetime_t)
318+ ```
319+
320+ Both the ` findTransitionForDateTime() ` and ` findTransitionForSeconds() ` methods
321+ search the list of Transitions of the specified TimeZone for a matching
322+ Transition. Most Date-Time libraries precalculate these Transitions for all
323+ Zones, for a certain range of years. Precalculation is definitely faster, and
324+ easier because the logic for calculating the Transition objects resides in only
325+ a single place.
326+
327+ The precalculation of Transition objects for all zones and years consumes too
328+ much memory on an embedded microcontrollers. To save memory, the
329+ ` ExtendedZoneProcessor ` class in the AceTime library calculates the ` Transition `
330+ objects lazily, for only a single zone and for a single year (technically, for a
331+ 14-month interval covering the 12 months of the specified year) when the
332+ ` initForEpochSeconds(acetime_t) ` or ` initForYear(int16_t) ` method is called. The
333+ list of Transitions for a single year is cached, so that subsequent requests in
334+ the same year avoid the work of recalculating the Transitions.
335+
336+ The calculation of the Transitions for a given zone and year is very complex,
337+ and I find that I can no longer understand my own code after a few months away
338+ of this code base. So here are some notes to help my future-self. The code is in
339+ ` ExtendedZoneProcessor::initForYear(int16_t) ` and is organized into 5 steps as
340+ described below.
312341
313342<a name =" Step1FindMatches " ></a >
314343### Step 1: Find Matches
315344
316- The ` ExtendedZoneProcessor. findMatches() ` finds all ` ZoneEra ` objects which
345+ The ` ExtendedZoneProcessor:: findMatches() ` finds all ` ZoneEra ` objects which
317346overlap with the 14-month interval from Dec 1 of the prior year until Feb 1 of
318347the following year. For example, ` initForYear(2010) ` means that the interval is
319348from 2009-12-01T00:00 until 2011-02-01T00:00.
@@ -574,12 +603,11 @@ available.
574603 * ` $ make `
575604 * ` $ ./ExtendedHinnantDateTest.out | grep failed `
576605 * There should be no failures.
577- * Update the zoneinfo files for AceTimePython (needed by BasicAcetzTest and
606+ * Update the zonedb files for AceTimePython (needed by BasicAcetzTest and
578607 ExtendedAcetzTest):
579- * ``zonedbpy`
580- * ` $ cd AceTimePython/src/acetime/zonedbpy `
581- * Edit the ` Makefile ` and update the ` TZ_VERSION ` .
582- * ` $ make `
608+ * ` $ cd AceTimePython/src/acetime/zonedb `
609+ * Edit the ` Makefile ` and update the ` TZ_VERSION ` .
610+ * ` $ make `
583611* Verify that the ` AceTime ` library and the ` AceTimePython ` library agree with
584612 each other using the same TZDB version. This requires going into the
585613 [ AceTimeValidation] ( https://github.com/bxparks/AceTimeValidation ) project.
0 commit comments