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
__construct()
Constructor.
public
__construct() : mixed
execute()
Does the job.
public
execute() : mixed
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.
getBacklinks()
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.