Documentation

TimezoneUpdater
in package

Updates SMF's time zone data.

Table of Contents

Constants

CLDR_TZNAMES_URL  = 'https://raw.githubusercontent.com/unicode-org/cldr-json/main/cldr-json/cldr-dates-full/main/en/timeZoneNames.json'
URL where we can get nice English labels for tzids.
DATE_MAX  = 'January 1 + 100 years UTC'
Used in places where a latest date is required.
DATE_MIN  = '1582-10-15 00:00:00 UTC'
Used in places where an earliest date is required.
DATE_SOON  = 'January 1 + 2 years UTC'
Used in places where a date in the next year or so is required.
TZDB_CURR_TAG  = ''
Git tag of the most recent version of the TZDB to check against.
TZDB_FILE_URL  = 'https://raw.githubusercontent.com/eggert/tz/{COMMIT}/{FILE}'
URL template to fetch raw data files for the TZDB
TZDB_PREV_TAG  = '2020d'
Git tag of the earliest version of the TZDB to check against.
TZDB_TAGS_URL  = 'https://api.github.com/repos/eggert/tz/tags?per_page=1000'
URL where we can get a list of tagged releases of the TZDB.

Properties

$curr_commit  : string
Git commit hash associated with TZDB_CURR_TAG.
$files_updated  : bool
This keeps track of whether any files actually changed.
$new_metazones  : array<string|int, mixed>
Info about any new meta-zones.
$prev_commit  : string
Git commit hash associated with TZDB_PREV_TAG.
$transitions  : array<string|int, mixed>
Compiled information about all time zone transitions.
$tz_data  : array<string|int, mixed>
A multidimensional array of time zone identifiers, grouped into different information blocks.
$tzdb_tags  : array<string|int, mixed>
Tags from the TZDB's GitHub repository.
$zones  : array<string|int, mixed>
Compiled information about all time zones in the TZDB.

Methods

__construct()  : mixed
Constructor.
execute()  : mixed
Does the job.
buildFallbacks()  : array<string|int, mixed>
Builds fallback information for new time zones.
buildPossibleFallbackZones()  : array<string|int, mixed>
Identifies time zones that might work as fallbacks for a given tzid.
buildRecurrenceRule()  : string
Builds an iCalendar recurrence rule based on TZDB rule data.
buildRecurrenceRuleStart()  : string
Returns the start date (in local time) for an iCalendar recurrence rule based on TZDB rule data.
buildRecurrenceRuleUntil()  : string
Returns the until date (in local time) for an iCalendar recurrence rule based on TZDB rule data.
buildTransitions()  : void
Populates $this->transitions with time zone transition information similar to PHP's timezone_transitions_get(), except that the array is built from the TZDB source as it existed at whatever version is defined as 'current' via self::TZDB_CURR_TAG & $this->curr_commit.
buildVTimeZoneClasses()  : void
Builds the SMF\Calendar\VTimeZone class and sub-classes.
buildZones()  : void
Compiles information about all time zones in the TZDB, including transitions, location data, what other zones it links to or that link to it, and whether it is new (where "new" means not present in the earliest version of the TZDB that we are considering).
fetchTzdbFile()  : string
Simply fetches the full contents of a file for the specified version of the TZDB.
fetchTzdbTags()  : void
Returns a list of Git tags and the associated commit hashes for each release of the TZDB available on GitHub.
fetchTzdbUpdates()  : void
Builds an array of information about the time zone identifiers in two different versions of the TZDB, including information about what changed between the two.
findFallbacks()  : array<string|int, mixed>
Finds a viable fallback for an entry in a time zone's list of transition rule changes. In some cases, the returned value will consist of a series of fallbacks for different times during the overall period of the entry.
generateFullFallbackCode()  : string
Generates PHP code to insert into TimeZone::$fallbacks for new tzids.
generateRenameFallbackCode()  : string
Generates PHP code to insert into TimeZone::$fallbacks for renamed tzids.
getApplicableRuleTransitions()  : array<string|int, mixed>
Gets rule-based transitions for a time zone entry.
getBacklinks()  : array<string|int, mixed>
Builds an array of backward compatibility time zone identifiers.
getBackzones()  : array<string|int, mixed>
Similar to getPrimaryZones() in all respects, except that it returns the pre-1970 data contained in the TZDB's backzone file rather than the main data files.
getCcForTzid()  : string
Gets the ISO-3166 country code for a time zone identifier as defined in the specified version of the TZDB.
getDistanceFrom()  : float
Calculates the distance between the locations of two time zones.
getPrimaryZones()  : array<string|int, mixed>
Builds an array of canonical and linked time zone identifiers.
getRules()  : array<string|int, mixed>
Compiles all the daylight saving rules in the TZDB.
getTzidLabel()  : array<string|int, mixed>
Returns a nice English label for the given time zone identifier.
offsetToDateInterval()  : DateInterval
Given an offset value such as '+3:00' or '-05:23:37', returns a \DateInterval that corresponds to the indicated amount of time.
rewriteDateString()  : string
Rewrites date strings from TZDB format to a PHP-parseable format.
updateMetazones()  : string
This figures out if we need any new meta-zones. If we do, this (1) populates $this->new_metazones variable for use in update_language_file(), and (2) inserts the new meta-zones into $file_contents for TimeZone.php.
updateTimezoneClass()  : void
Updates the contents of ./Sources/TimeZone.php with any changes required to reflect changes in the TZDB.
updateTimezonesLangfile()  : void
Updates the contents of the Timezones.php language file with any changes required to reflect changes in the TZDB.

Constants

CLDR_TZNAMES_URL

URL where we can get nice English labels for tzids.

public mixed CLDR_TZNAMES_URL = 'https://raw.githubusercontent.com/unicode-org/cldr-json/main/cldr-json/cldr-dates-full/main/en/timeZoneNames.json'

DATE_MAX

Used in places where a latest date is required.

public mixed DATE_MAX = 'January 1 + 100 years UTC'

DATE_MIN

Used in places where an earliest date is required.

public mixed DATE_MIN = '1582-10-15 00:00:00 UTC'

To support 32-bit PHP builds, use '1901-12-13 20:45:52 UTC'

DATE_SOON

Used in places where a date in the next year or so is required.

public mixed DATE_SOON = 'January 1 + 2 years UTC'

TZDB_CURR_TAG

Git tag of the most recent version of the TZDB to check against.

public mixed TZDB_CURR_TAG = ''

Leave blank to use the latest release of the TZDB.

TZDB_FILE_URL

URL template to fetch raw data files for the TZDB

public mixed TZDB_FILE_URL = 'https://raw.githubusercontent.com/eggert/tz/{COMMIT}/{FILE}'

TZDB_PREV_TAG

Git tag of the earliest version of the TZDB to check against.

public mixed TZDB_PREV_TAG = '2020d'

This can be set to the TZDB version that was included in the earliest version of PHP that SMF supports, e.g. 2015g (a.k.a. 2015.7) for PHP 7.0. Leave blank to use the earliest release available.

TZDB_TAGS_URL

URL where we can get a list of tagged releases of the TZDB.

public mixed TZDB_TAGS_URL = 'https://api.github.com/repos/eggert/tz/tags?per_page=1000'

Properties

$curr_commit

Git commit hash associated with TZDB_CURR_TAG.

public string $curr_commit

$files_updated

This keeps track of whether any files actually changed.

public bool $files_updated = false

$new_metazones

Info about any new meta-zones.

public array<string|int, mixed> $new_metazones = []

$prev_commit

Git commit hash associated with TZDB_PREV_TAG.

public string $prev_commit

$transitions

Compiled information about all time zone transitions.

public array<string|int, mixed> $transitions

This is similar to return value of PHP's timezone_transitions_get(), except that the array is built from the TZDB source as it existed at whatever version is defined as 'current' via self::TZDB_CURR_TAG.

$tz_data

A multidimensional array of time zone identifiers, grouped into different information blocks.

public array<string|int, mixed> $tz_data = []

$tzdb_tags

Tags from the TZDB's GitHub repository.

public array<string|int, mixed> $tzdb_tags = []

$zones

Compiled information about all time zones in the TZDB.

public array<string|int, mixed> $zones = []

Methods

buildFallbacks()

Builds fallback information for new time zones.

private buildFallbacks() : array<string|int, mixed>
Return values
array<string|int, mixed>

Fallback info for the new time zones.

buildPossibleFallbackZones()

Identifies time zones that might work as fallbacks for a given tzid.

private buildPossibleFallbackZones(array<string|int, mixed> $new_tzid) : array<string|int, mixed>
Parameters
$new_tzid : array<string|int, mixed>

A time zone identifier

Return values
array<string|int, mixed>

A subset of $this->zones that might work as fallbacks for $new_tzid

buildRecurrenceRule()

Builds an iCalendar recurrence rule based on TZDB rule data.

private buildRecurrenceRule(array<string|int, mixed> $rule) : string
Parameters
$rule : array<string|int, mixed>

One line from a TZDB rule.

Return values
string

An iCalendar recurrence rule.

buildRecurrenceRuleStart()

Returns the start date (in local time) for an iCalendar recurrence rule based on TZDB rule data.

private buildRecurrenceRuleStart(array<string|int, mixed> $rule) : string
Parameters
$rule : array<string|int, mixed>

One line from a TZDB rule.

Return values
string

A date string in iCalendar format ('Ymd\THis').

buildRecurrenceRuleUntil()

Returns the until date (in local time) for an iCalendar recurrence rule based on TZDB rule data.

private buildRecurrenceRuleUntil(array<string|int, mixed> $rule) : string
Parameters
$rule : array<string|int, mixed>

One line from a TZDB rule.

Return values
string

A date string in iCalendar format ('Ymd\THis'), or an empty string if the rule doesn't have an expiry date.

buildTransitions()

Populates $this->transitions with time zone transition information similar to PHP's timezone_transitions_get(), except that the array is built from the TZDB source as it existed at whatever version is defined as 'current' via self::TZDB_CURR_TAG & $this->curr_commit.

private buildTransitions([bool $rebuild = false ]) : void

Also updates the entries for every tzid in $this->zones with unambiguous UTC timestamps for their start and end values.

Parameters
$rebuild : bool = false

If true, force a rebuild.

buildVTimeZoneClasses()

Builds the SMF\Calendar\VTimeZone class and sub-classes.

private buildVTimeZoneClasses() : void

buildZones()

Compiles information about all time zones in the TZDB, including transitions, location data, what other zones it links to or that link to it, and whether it is new (where "new" means not present in the earliest version of the TZDB that we are considering).

private buildZones() : void

fetchTzdbFile()

Simply fetches the full contents of a file for the specified version of the TZDB.

private fetchTzdbFile(string $filename, string $commit) : string
Parameters
$filename : string

File name.

$commit : string

Git commit hash of a specific TZDB version.

Return values
string

The content of the file.

fetchTzdbTags()

Returns a list of Git tags and the associated commit hashes for each release of the TZDB available on GitHub.

private fetchTzdbTags() : void

fetchTzdbUpdates()

Builds an array of information about the time zone identifiers in two different versions of the TZDB, including information about what changed between the two.

private fetchTzdbUpdates() : void

The data is saved in $this->tz_data.

findFallbacks()

Finds a viable fallback for an entry in a time zone's list of transition rule changes. In some cases, the returned value will consist of a series of fallbacks for different times during the overall period of the entry.

private findFallbacks(array<string|int, mixed> $pfzs, array<string|int, mixed> $entry, string $tzid, string $prev_fallback_tzid, array<string|int, mixed> $skip_tzids) : array<string|int, mixed>
Parameters
$pfzs : array<string|int, mixed>

Array returned from buildPossibleFallbackZones()

$entry : array<string|int, mixed>

An element from $this->zones[$tzid]['entries']

$tzid : string

A time zone identifier

$prev_fallback_tzid : string

A time zone identifier

$skip_tzids : array<string|int, mixed>

Tzids that should not be used as fallbacks.

Return values
array<string|int, mixed>

Fallback data for the entry.

generateFullFallbackCode()

Generates PHP code to insert into TimeZone::$fallbacks for new tzids.

private generateFullFallbackCode(array<string|int, mixed> $fallbacks) : string

Uses the fallback data created by $this->buildFallbacks() to do so.

Parameters
$fallbacks : array<string|int, mixed>

Fallback info for tzids.

Return values
string

PHP code to insert into TimeZone::$fallbacks

generateRenameFallbackCode()

Generates PHP code to insert into TimeZone::$fallbacks for renamed tzids.

private generateRenameFallbackCode(array<string|int, mixed> $renamed_tzids) : string
Parameters
$renamed_tzids : array<string|int, mixed>

Key-value pairs of renamed tzids.

Return values
string

PHP code to insert into TimeZone::$fallbacks

getApplicableRuleTransitions()

Gets rule-based transitions for a time zone entry.

private getApplicableRuleTransitions(string $rule_name, array<string|int, mixed> $unadjusted_date_strings, int $std_offset, string $prev_save) : array<string|int, mixed>
Parameters
$rule_name : string

The name of a time zone rule.

$unadjusted_date_strings : array<string|int, mixed>

Dates for $entry_start and $entry_end.

$std_offset : int

The standard time offset for this time zone entry.

$prev_save : string

The daylight saving value that applied just before $entry_start.

Return values
array<string|int, mixed>

Transition rules.

Builds an array of backward compatibility time zone identifiers.

private getBacklinks(string $commit) : array<string|int, mixed>

These supplement the linked tzids supplied by getPrimaryZones() and are formatted the same way (i.e. 'link' => 'target')

Parameters
$commit : string

Git commit hash of a specific TZDB version.

Return values
array<string|int, mixed>

Linked time zone identifiers.

getBackzones()

Similar to getPrimaryZones() in all respects, except that it returns the pre-1970 data contained in the TZDB's backzone file rather than the main data files.

private getBackzones(string $commit) : array<string|int, mixed>
Parameters
$commit : string

Git commit hash of a specific TZDB version.

Return values
array<string|int, mixed>

Canonical and linked time zone identifiers.

getCcForTzid()

Gets the ISO-3166 country code for a time zone identifier as defined in the specified version of the TZDB.

private getCcForTzid(string $tzid, string $commit) : string
Parameters
$tzid : string

A time zone identifier string.

$commit : string

Git commit hash of a specific TZDB version.

Return values
string

A two-character country code, or '??' if not found.

getDistanceFrom()

Calculates the distance between the locations of two time zones.

private getDistanceFrom(array<string|int, mixed> $this_zone, array<string|int, mixed> $from_zone) : float

This somewhat simplistically treats locations on opposite sides of the antimeridian as maximally distant from each other. But since the antimeridian is approximately the track of the International Date Line, and locations on opposite sides of the IDL can't be fallbacks for each other, it's sufficient. In the unlikely edge case that we ever need to find a fallback for, say, a newly created time zone for an island in Kiribati, the worst that could happen is that we might overlook some better option and therefore end up suggesting a generic Etc/* time zone as a fallback.

Parameters
$this_zone : array<string|int, mixed>

One element from the $this->zones array.

$from_zone : array<string|int, mixed>

Another element from the $this->zones array.

Return values
float

The distance (in degrees) between the two locations.

getPrimaryZones()

Builds an array of canonical and linked time zone identifiers.

private getPrimaryZones([string $commit = 'main' ]) : array<string|int, mixed>

Canonical tzids are a simple list, while linked tzids are given as 'link' => 'target' key-value pairs, where 'target' is a canonical tzid and 'link' is a compatibility tzid that uses the same time zone rules as its canonical target.

Parameters
$commit : string = 'main'

Git commit hash of a specific TZDB version.

Return values
array<string|int, mixed>

Canonical and linked time zone identifiers.

getRules()

Compiles all the daylight saving rules in the TZDB.

private getRules() : array<string|int, mixed>
Return values
array<string|int, mixed>

Compiled rules, indexed by rule name.

getTzidLabel()

Returns a nice English label for the given time zone identifier.

private getTzidLabel(string $tzid) : array<string|int, mixed>
Parameters
$tzid : string

A time zone identifier.

Return values
array<string|int, mixed>

The label text, and possibly an "ACTION NEEDED" message.

offsetToDateInterval()

Given an offset value such as '+3:00' or '-05:23:37', returns a \DateInterval that corresponds to the indicated amount of time.

private offsetToDateInterval(string $offset) : DateInterval

The offset value is always assumed to begin with hours, then minutes, then seconds, with missing values filled in by zeros. For example, passing '+3' will be interpreted as '+03:00:00'.

Parameters
$offset : string

The offset value as a string.

Return values
DateInterval

for the indicated amount of time.

rewriteDateString()

Rewrites date strings from TZDB format to a PHP-parseable format.

private rewriteDateString(string $date_string) : string
Parameters
$date_string : string

A date string in TZDB format.

Return values
string

A date string that can be parsed by strtotime()

updateMetazones()

This figures out if we need any new meta-zones. If we do, this (1) populates $this->new_metazones variable for use in update_language_file(), and (2) inserts the new meta-zones into $file_contents for TimeZone.php.

private updateMetazones(string $file_contents) : string
Parameters
$file_contents : string

String content of TimeZone.php.

Return values
string

Modified copy of $file_contents.

updateTimezoneClass()

Updates the contents of ./Sources/TimeZone.php with any changes required to reflect changes in the TZDB.

private updateTimezoneClass() : void
  • Handles renames of tzids (e.g. Europe/Kiev -> Europe/Kyiv) fully automatically.

  • If a new tzid has been created, adds fallback code for it in TimeZone::$fallbacks, and appends it to the list of tzids for its country in TimeZone::$sorted_tzids.

  • Checks the rules defined in existing fallback code to make sure they are still accurate, and updates any that are not. This is necessary because new versions of the TZDB sometimes contain corrections to previous data.

updateTimezonesLangfile()

Updates the contents of the Timezones.php language file with any changes required to reflect changes in the TZDB.

private updateTimezonesLangfile() : void
  • Handles renames of tzids (e.g. Europe/Kiev -> Europe/Kyiv) fully automatically. For this situation, no further developer work should be needed.

  • If a new tzid has been created, adds a new $txt string for it. We try to fetch a label from the CLDR project, or generate a preliminary label if the CLDR has not yet been updated to include the new tzid.

  • Makes sure that $txt['iso3166'] is up to date, just in case a new country has come into existence since the last update.


        
On this page

Search results