Skip to content

Commit

Permalink
Got specific locations working
Browse files Browse the repository at this point in the history
  • Loading branch information
camertron committed Nov 20, 2019
1 parent 9319fe7 commit f4e9220
Show file tree
Hide file tree
Showing 100 changed files with 105,881 additions and 400 deletions.
61 changes: 44 additions & 17 deletions lib/twitter_cldr/formatters/calendars/date_time_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@ class DateTimeFormatter < Formatter
'S' => :second_fraction,
'z' => :timezone,
'Z' => :timezone,
'v' => :timezone, # should eventually be :timezone_generic_non_location
'V' => :timezone # should eventually be :timezone_metazone
'O' => :timezone,
'v' => :timezone,
'V' => :timezone,
'x' => :timezone,
'X' => :timezone
}

protected
Expand Down Expand Up @@ -241,24 +244,48 @@ def second_fraction(time, pattern, length, options = {})

def timezone(time, pattern, length, options = {})
# ruby is dumb and doesn't let you set non-UTC timezones in dates/times, so we have to pass it as an option instead
timezone_info = TZInfo::Timezone.get(options[:timezone] || "UTC")

case length
when 1..3
timezone_info.current_period.abbreviation.to_s
else
hours = (timezone_info.current_period.utc_offset.to_f / 60 ** 2).abs
divisor = hours.to_i
minutes = (hours % (divisor == 0 ? 1 : divisor)) * 60
sign = timezone_info.current_period.utc_offset < 0 ? "-" : "+"
"UTC #{sign}#{divisor.to_s.rjust(2, "0")}:#{minutes.floor.to_s.rjust(2, "0")}"
tz = TwitterCldr::Timezones::Timezone.instance(
options[:timezone] || 'Etc/Unknown', data_reader.locale
)

case pattern
when 'z', 'zz', 'zzz'
# short specific non-location format
when 'zzzz'
# long specific non-location format
when 'Z', 'ZZ', 'ZZZ'
# ISO8601 basic format with hour, min, sec (equiv RFC 822)
when 'ZZZZ', 'OOOO'
# long localized GMT format
when 'ZZZZZ', 'XXXXX'
# ISO8601 extended format: hours, minutes, seconds
when 'O'
# short localized GMT format
when 'v'
# short generic non-location format
when 'vvvv'
# long generic non-location format
when 'V'
# short timezone ID
when 'VV'
# long timezone ID
when 'VVV'
# exemplar city
when 'VVVV'
# generic location format
when 'X'
# ISO8601 format: hours and optional minutes
when 'XX'
# ISO8601 format: hours and minutes
when 'XXX'
# ISO8601 extended format: hours and minutes
when 'XXXX'
# ISO8601 basic format: hours, minutes, optional seconds
when 'x', 'xx', 'xxx', 'xxxx', 'xxxxx'
# same as uppercase, but without the 'Z' character
end
end

def timezone_generic_non_location(time, pattern, length, options = {})
raise NotImplementedError, 'requires timezone translation data'
end

# ported from icu4j 64.2
def week_fields_for(date)
week_data_cache[date] ||= begin
Expand Down
4 changes: 3 additions & 1 deletion lib/twitter_cldr/resources/timezone_tests_importer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ class TimezoneTestsImporter < Importer
:LOCALIZED_GMT_SHORT,
:GENERIC_LOCATION,
:GENERIC_LONG,
:GENERIC_SHORT
:GENERIC_SHORT,
:SPECIFIC_LONG,
:SPECIFIC_SHORT
]

def execute
Expand Down
31 changes: 2 additions & 29 deletions lib/twitter_cldr/timezones.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,11 @@

module TwitterCldr
module Timezones
autoload :GmtLocation, 'twitter_cldr/timezones/gmt_location'
# autoload :Iso8601Timezone, 'twitter_cldr/timezones/iso8601_timezone'
autoload :GenericLocation, 'twitter_cldr/timezones/generic_location'
# autoload :NonLocationTimezone, 'twitter_cldr/timezones/non_location_timezone'
autoload :GmtLocation, 'twitter_cldr/timezones/gmt_location'
autoload :Iso8601Location, 'twitter_cldr/timezones/iso8601_location'
autoload :Location, 'twitter_cldr/timezones/location'
autoload :Timezone, 'twitter_cldr/timezones/timezone'
autoload :ZoneMeta, 'twitter_cldr/timezones/zone_meta'

class << self
# def generic_non_location(tz_id, locale = TwitterCldr.locale)
# NonLocationTimezone.new(tz_id, locale)
# end

# def specific_non_location(tz_id, locale = TwitterCldr.locale)
# NonLocationTimezone.new(tz_id, locale)
# end

# def generic_partial_location(tz_id, locale = TwitterCldr.locale)
# # @TODO: what is this?
# end

def generic_location(tz_id, locale = TwitterCldr.locale)
GenericLocationTimezone.new(tz_id, locale)
end

def gmt(tz_id, locale = TwitterCldr.locale)
GmtTimezone.new(tz_id, locale)
end

def iso_8601(tz_id, locale = TwitterCldr.locale)
Iso8601Timezone.new(tz_id, locale)
end
end
end
end
71 changes: 48 additions & 23 deletions lib/twitter_cldr/timezones/generic_location.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,29 @@ module Timezones
class GenericLocation < Location
DEFAULT_CITY_EXCLUSION_PATTERN = /Etc\/.*|SystemV\/.*|.*\/Riyadh8[7-9]/
DST_CHECK_RANGE = 184 * 24 * 60 * 60
FORMATS = [:location, :short, :long].freeze
FORMATS = [
:location,
:generic_short,
:generic_long,
:specific_short,
:specific_long
].freeze

Territories = TwitterCldr::Shared::Territories
Utils = TwitterCldr::Utils

def display_name_for(date, fmt = :location)
def display_name_for(date, fmt = :generic_location)
case fmt
when :location
when :generic_location
generic_location_display_name
when :short
when :generic_short
generic_short_display_name(date) || generic_location_display_name
when :long
when :generic_long
generic_long_display_name(date) || generic_location_display_name
when :specific_short
specific_short_display_name(date)
when :specific_long
specific_long_display_name(date)
else
raise ArgumentError, "'#{fmt}' is not a valid generic timezone format, "\
"must be one of #{FORMATS.join(', ')}"
Expand All @@ -45,11 +55,19 @@ def generic_location_display_name
end

def generic_short_display_name(date)
generic_display_name(date, :short)
format_display_name(date, :generic, :short)
end

def generic_long_display_name(date)
generic_display_name(date, :long)
format_display_name(date, :generic, :long)
end

def specific_short_display_name(date)
format_display_name(date, :specific, :short)
end

def specific_long_display_name(date)
format_display_name(date, :specific, :long)
end

# From ICU source, TimeZoneGenericNames.java, formatGenericNonLocationName():
Expand All @@ -64,18 +82,24 @@ def generic_long_display_name(date)
# 4. If a generic non-location string is not available, use generic location
# string.
#
def generic_display_name(date, fmt)
if generic = (timezone_data[fmt] || {})[:generic]
return generic
end

def format_display_name(date, type, fmt)
date_int = date.strftime('%s').to_i
period = tz.period_for_local(date)

flavor = if type == :generic
:generic
elsif type == :specific
period.std_offset > 0 ? :daylight : :standard
end

if explicit = (timezone_data[fmt] || {})[flavor]
return explicit
end

if tz_metazone = ZoneMeta.tz_metazone_for(tz_id, date)
if use_standard?(date_int, period)
std_name = std_name_for(fmt) || mz_std_name_for(fmt, tz_metazone.mz_id)
mz_generic_name = mz_name_for(fmt, tz_metazone.mz_id)
std_name = tz_name_for(fmt, :standard) || mz_name_for(fmt, :standard, tz_metazone.mz_id)
mz_generic_name = mz_name_for(fmt, :generic, tz_metazone.mz_id)

# From ICU source, TimeZoneGenericNames.java, formatGenericNonLocationName():
#
Expand All @@ -85,7 +109,12 @@ def generic_display_name(date, fmt)
return std_name if std_name && std_name != mz_generic_name
end

mz_name = mz_name_for(fmt, tz_metazone.mz_id)
mz_name = mz_name_for(fmt, flavor, tz_metazone.mz_id)

# don't go through all the golden zone logic if we're not computing the
# generic format
return mz_name if type == :specific

golden_zone_id = tz_metazone.metazone.reference_tz_id

if golden_zone_id != tz_id
Expand Down Expand Up @@ -130,16 +159,12 @@ def exemplar_city
@exemplar_city ||= timezone_data[:city] || default_exemplar_city
end

def std_name_for(fmt)
Utils.traverse_hash(timezone_data[:timezones], [tz_id.to_sym, fmt, :standard])
end

def mz_name_for(fmt, mz_id)
Utils.traverse_hash(metazone_data, [mz_id.to_sym, fmt, :generic])
def tz_name_for(fmt, flavor)
Utils.traverse_hash(timezone_data[:timezones], [tz_id.to_sym, fmt, flavor])
end

def mz_std_name_for(fmt, mz_id)
Utils.traverse_hash(metazone_data, [mz_id.to_sym, fmt, :standard])
def mz_name_for(fmt, flavor, mz_id)
Utils.traverse_hash(metazone_data, [mz_id.to_sym, fmt, flavor])
end

def use_standard?(date_int, transition_offset)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

module TwitterCldr
module Timezones
class Iso8601Timezone < Timezone
class Iso8601Location < Location
def to_short_s
"#{sign(offset)}#{offset_hour.to_s.rjust(2, '0')}"
end
Expand Down
36 changes: 0 additions & 36 deletions lib/twitter_cldr/timezones/location_timezone_old.rb

This file was deleted.

Loading

0 comments on commit f4e9220

Please sign in to comment.