class TimezoneParser::Timezone

Timezone

Attributes

Locales[RW]
Regions[RW]

Public Class Methods

Locales() click to toggle source

Locales which will be used for Timezone methods if not specified there

Each locale is language identifier based on IETF BCP 47 @return [Array<String>] list containing locale identifiers @see en.wikipedia.org/wiki/IETF_language_tag @see unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers @see www.unicode.org/cldr/charts/latest/supplemental/language_territory_information.html

# File lib/timezone_parser/timezone.rb, line 21
def self.Locales
    @@Locales
end
Regions() click to toggle source

Regions which will be used for Timezone methods if not specified there

Each region is CLDR territory (UN M.49) @return [Array<String>] list containing region identifiers @see www.unicode.org/cldr/charts/latest/supplemental/territory_containment_un_m_49.html

# File lib/timezone_parser/timezone.rb, line 30
def self.Regions
    @@Regions
end
getMetazones(timezone, toTime = nil, fromTime = nil, locales = nil, regions = nil) click to toggle source

Get Metazone identifiers for given Timezone name @param timezone [String] Timezone name @param toTime [DateTime] look for timezones which came into effect before this date, exclusive @param fromTime [DateTime] look for timezones which came into effect at this date, inclusive @param locales [Array<String>] search Timezone name only for these locales @param regions [Array<String>] look for timezones only for these regions @return [Array<String>] list of metazone identifiers @see Locales @see Regions

# File lib/timezone_parser/timezone.rb, line 122
def self.getMetazones(timezone, toTime = nil, fromTime = nil, locales = nil, regions = nil)
    self.new(timezone).setTime(toTime, fromTime).set(locales, regions).getMetazones
end
getOffsets(timezone, toTime = nil, fromTime = nil, locales = nil, regions = nil) click to toggle source

Get UTC offsets in seconds for given Timezone name @param timezone [String] Timezone name @param toTime [DateTime] look for offsets which came into effect before this date, exclusive @param fromTime [DateTime] look for offsets which came into effect at this date, inclusive @param locales [Array<String>] search Timezone name only for these locales @param regions [Array<String>] look for offsets only for these regions @return [Array<Fixnum>] list of timezone offsets in seconds @see Locales @see Regions

# File lib/timezone_parser/timezone.rb, line 96
def self.getOffsets(timezone, toTime = nil, fromTime = nil, locales = nil, regions = nil)
    self.new(timezone).setTime(toTime, fromTime).set(locales, regions).getOffsets
end
getTimezones(timezone, toTime = nil, fromTime = nil, locales = nil, regions = nil) click to toggle source

Get Timezone identifiers for given Timezone name @param timezone [String] Timezone name @param toTime [DateTime] look for timezones which came into effect before this date, exclusive @param fromTime [DateTime] look for timezones which came into effect at this date, inclusive @param locales [Array<String>] search Timezone name only for these locales @param regions [Array<String>] look for timezones only for these regions @return [Array<String>] list of timezone identifiers @see Locales @see Regions

# File lib/timezone_parser/timezone.rb, line 109
def self.getTimezones(timezone, toTime = nil, fromTime = nil, locales = nil, regions = nil)
    self.new(timezone).setTime(toTime, fromTime).set(locales, regions).getTimezones
end
isValid?(timezone, locales = nil) click to toggle source

Check if given Timezone name is a valid timezone @param timezone [String] Timezone name @param locales [Array<String>] search Timezone name only for these locales @return [Boolean] whether Timezone is valid @see Locales

# File lib/timezone_parser/timezone.rb, line 83
def self.isValid?(timezone, locales = nil)
    self.new(timezone).set(locales).isValid?
end
new(timezone) click to toggle source

Timezone instance @param timezone [String] Timezone name

# File lib/timezone_parser/timezone.rb, line 39
def initialize(timezone)
    @Timezone = timezone
    @Valid = nil
    setTime
    set(@@Locales.dup, @@Regions.dup)
end

Public Instance Methods

isValid?() click to toggle source

Check if timezone is valid @return [Boolean] whether timezone is valid

# File lib/timezone_parser/timezone.rb, line 58
def isValid?
    if @Valid.nil?
        params = []
        joins = ''
        where = ''

        if not @Locales.empty?
            joins += ' LEFT JOIN `Locales` AS L ON TN.Locale = L.ID'
            where = 'L.Name COLLATE NOCASE IN (' + Array.new(@Locales.count, '?').join(',') + ') AND '
            params += @Locales
        end

        sql = "SELECT 1 FROM `TimezoneNames` TN #{joins} WHERE #{where}TN.NameLowercase = ? COLLATE NOCASE LIMIT 1"
        params << @Timezone.downcase

        @Valid = Data::Storage.getStatement(sql).execute(*params).count > 0
    end
    @Valid
end
set(locales = nil, regions = nil) click to toggle source

Set locales and regions @param locales [Array<String>] search only in these locales @param regions [Array<String>] filter for these regions @return [Timezone] self

# File lib/timezone_parser/timezone.rb, line 50
def set(locales = nil, regions = nil)
    @Locales = locales unless locales.nil?
    @Regions = regions unless regions.nil?
    self
end

Protected Instance Methods

getFilteredData(dataType) click to toggle source
# File lib/timezone_parser/timezone.rb, line 128
def getFilteredData(dataType)
    params = []
    column = nil
    joins = ''
    regionJoins = ''
    useTimeFilter = false
    useRegionFilter = !@Regions.nil? && !@Regions.empty?
    case dataType
    when :Offsets, :Timezones
        column = '`Timezones`.`Name`'
        if dataType == :Offsets
            column += ', TN.`Types`'
        end
        joins += ' LEFT JOIN `TimezoneName_Timezones` AS T ON T.Name = TN.ID'
        joins += ' LEFT JOIN `TimezoneName_Metazones` AS M ON M.Name = TN.ID'
        joins += ' LEFT JOIN `MetazonePeriods` MP ON M.Metazone = MP.Metazone'
        joins += ' LEFT JOIN `MetazonePeriod_Timezones` MPT ON MPT.MetazonePeriod = MP.ID'
        joins += ' INNER JOIN `Timezones` ON (T.Timezone = Timezones.ID OR MPT.Timezone = Timezones.ID)'
        regionJoins += ' LEFT JOIN `TimezoneTerritories` ON (TimezoneTerritories.Timezone = T.Timezone OR TimezoneTerritories.Timezone = MPT.Timezone)'
        regionJoins += ' LEFT JOIN `Territories` ON TimezoneTerritories.Territory = Territories.ID'
        useTimeFilter = true
    when :Metazones
        column = '`Metazones`.`Name`'
        joins += ' LEFT JOIN `TimezoneName_Metazones` AS M ON M.Name = TN.ID'
        joins += ' INNER JOIN `Metazones` ON M.Metazone = Metazones.ID'
        regionJoins += ' LEFT JOIN `TimezoneName_Timezones` AS T ON T.Name = TN.ID'
        regionJoins += ' LEFT JOIN `TimezoneTerritories` ON TimezoneTerritories.Timezone = T.Timezone'
        regionJoins += ' LEFT JOIN `Territories` ON TimezoneTerritories.Territory = Territories.ID'
    when :Types
         column = 'TN.Types'
         useRegionFilter = false
    else
        raise StandardError, "Unkown dataType '#{dataType}'"
    end

    if not @Locales.empty?
        joins += ' LEFT JOIN `Locales` AS L ON TN.Locale = L.ID'
        where = 'L.Name COLLATE NOCASE IN (' + Array.new(@Locales.count, '?').join(',')  + ') AND '
        params += @Locales
    end

    sql = 'SELECT DISTINCT ' + column + ' FROM `TimezoneNames` AS TN'
    sql += joins
    if useRegionFilter
        sql += regionJoins
    end

    sql += " WHERE #{where}TN.NameLowercase = ?"
    params << @Timezone.downcase
    if useTimeFilter and not @FromTime.nil?
        fromsql = '((MP.`From` IS NULL AND MP.`To` > ?) OR (MP.`To` IS NULL AND MP.`From` <= ?) OR (MP.`From` <= ? AND MP.`To` > ?) OR (MP.`From` IS NULL AND MP.`To` IS NULL))'
        params += Array.new(4, @FromTime.to_s)
        if @ToTime.nil?
            sql += ' AND ' + fromsql
        end
    end
    if useTimeFilter and not @ToTime.nil?
        tosql = '((MP.`From` IS NULL AND MP.`To` >= ?) OR (MP.`To` IS NULL AND MP.`From` < ?) OR (MP.`From` < ? AND MP.`To` >= ?) OR (MP.`From` IS NULL AND MP.`To` IS NULL))'
        params += Array.new(4, @ToTime.to_s)
        if not @FromTime.nil?
            sql += ' AND ((' + fromsql + ') OR (' + tosql + '))'
        else
            sql += ' AND ' + tosql
        end
    end
    if useRegionFilter
        sql += ' AND Territories.Territory IN (' + Array.new(@Regions.count, '?').join(',')  + ')'
        params += @Regions
    end
    sql += ' ORDER BY ' + column

    if dataType == :Offsets
        result = self.class.findOffsetsFromTimezonesTypes(Data::Storage.getStatement(sql).execute(*params), @ToTime, @FromTime, nil)
    else
        result = Data::Storage.getStatement(sql).execute(*params).collect { |row| row.first }
        result = self.class.convertTypes(result) if dataType == :Types
    end
    result
end