forked from crystal-lang/crystal
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add time zones support (crystal-lang#5324)
* Add cache for last zone to Time::Location#lookup * Implement Time::Location including timezone data loader Remove representation of floating time from `Time` (formerly expressed as `Time::Kind::Unspecified`). Floating time should not be represented as an instance of `Time` to avoid undefined operations through type safety (see crystal-lang#5332). Breaking changes: * Calls to `Time.new` and `Time.now` are now in the local time zone by default. * `Time.parse`, `Time::Format.new` and `Time::Format.parse` don't specify a default location. If none is included in the time format and no default argument is provided, the parse method wil raise an exception because there is no way to know how such a value should be represented as an instance of `Time`. Applications expecting time values without time zone should provide default location to apply in such a case. * Implement custom zip file reader to remove depenencies * Add location cache for `Location.load` * Rename `Location.local` to `.load_local` and make `local` a class property * Fix env ZONEINFO * Fix example code string representation of local Time instance * Time zone implementation for win32 This adds basic support for using the new time zone model on windows. * `Crystal::System::Time.zone_sources` returns an empty array because Windows does not include a copy of the tz database. * `Crystal::System::Time.load_localtime` creates a local time zone `Time::Location` based on data provided by `GetTimeZoneInformation`. * A mapping from Windows time zone names to identifiers used by the IANA timezone database is included as well as an automated generator for that file. * Add stubs for methods with file acces Trying to load a location from a file will fail because `File` is not yet ported to windows.
- Loading branch information
1 parent
6a574f2
commit f3168b6
Showing
27 changed files
with
1,874 additions
and
503 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# This script generates the file src/crystal/system/win32/zone_names.cr | ||
# that contains mappings for windows time zone names based on the values | ||
# found in http://unicode.org/cldr/data/common/supplemental/windowsZones.xml | ||
|
||
require "http/client" | ||
require "xml" | ||
require "../src/compiler/crystal/formatter" | ||
|
||
WINDOWS_ZONE_NAMES_SOURCE = "http://unicode.org/cldr/data/common/supplemental/windowsZones.xml" | ||
TARGET_FILE = File.join(__DIR__, "..", "src", "crystal", "system", "win32", "zone_names.cr") | ||
|
||
response = HTTP::Client.get(WINDOWS_ZONE_NAMES_SOURCE) | ||
|
||
# Simple redirection resolver | ||
# TODO: Needs to be replaced by proper redirect handling that should be provided by `HTTP::Client` | ||
if (300..399).includes?(response.status_code) && (location = response.headers["Location"]?) | ||
response = HTTP::Client.get(location) | ||
end | ||
|
||
xml = XML.parse(response.body) | ||
|
||
nodes = xml.xpath_nodes("/supplementalData/windowsZones/mapTimezones/mapZone[@territory=001]") | ||
|
||
entries = [] of {key: String, zones: {String, String}, tzdata_name: String} | ||
|
||
nodes.each do |node| | ||
location = Time::Location.load(node["type"]) | ||
next unless location | ||
time = Time.now(location).at_beginning_of_year | ||
zone1 = time.zone | ||
zone2 = (time + 6.months).zone | ||
|
||
if zone1.offset > zone2.offset | ||
# southern hemisphere | ||
zones = {zone2.name, zone1.name} | ||
else | ||
# northern hemisphere | ||
zones = {zone1.name, zone2.name} | ||
end | ||
|
||
entries << {key: node["other"], zones: zones, tzdata_name: location.name} | ||
rescue err : Time::Location::InvalidLocationNameError | ||
pp err | ||
end | ||
|
||
# sort by IANA database identifier | ||
entries.sort_by! &.[:tzdata_name] | ||
|
||
hash_items = String.build do |io| | ||
entries.each do |entry| | ||
entry[:key].inspect(io) | ||
io << " => " | ||
entry[:zones].inspect(io) | ||
io << ", # " << entry[:tzdata_name] << "\n" | ||
end | ||
end | ||
|
||
source = <<-CRYSTAL | ||
# This file was automatically generated by running: | ||
# | ||
# scripts/generate_windows_zone_names.cr | ||
# | ||
# DO NOT EDIT | ||
module Crystal::System::Time | ||
# These mappings for windows time zone names are based on | ||
# #{WINDOWS_ZONE_NAMES_SOURCE} | ||
WINDOWS_ZONE_NAMES = { | ||
#{hash_items} | ||
} | ||
end | ||
CRYSTAL | ||
|
||
source = Crystal.format(source) | ||
|
||
File.write(TARGET_FILE, source) |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.