class Fluent::Timezone

def self.formatter(timezone, format = nil)

nil is returned.
An Proc object is returned. If the given timezone is invalid,

Create a formatter for a timezone and optionally a format.
def self.formatter(timezone, format = nil)
  if timezone.nil?
    return nil
  end
  # [+-]HH:MM, [+-]HHMM, [+-]HH
  if NUMERIC_PATTERN === timezone
    offset = Time.zone_offset(timezone)
    if format
      return Proc.new {|time|
        Time.at(time).localtime(offset).strftime(format)
      }
    else
      return Proc.new {|time|
        Time.at(time).localtime(offset).iso8601
      }
    end
  end
  # Region/Zone, Region/Zone/Zone
  if NAME_PATTERN === timezone
    begin
      tz = TZInfo::Timezone.get(timezone)
    rescue
      return nil
    end
    if format
      return Proc.new {|time|
        Time.at(time).localtime(tz.period_for_utc(time).utc_total_offset).strftime(format)
      }
    else
      return Proc.new {|time|
        Time.at(time).localtime(tz.period_for_utc(time).utc_total_offset).iso8601
      }
    end
  end
  return nil
end

def self.validate(timezone)

false is returned. When nil is given, false is returned.
When the given timezone is valid, true is returned. Otherwise,

timezone exists in the timezone database.
In the 4th and 5th cases, it is checked whether the specified

5. Region/Zone/Zone (e.g. "America/Argentina/Buenos_Aires")
4. Region/Zone (e.g. "Asia/Tokyo")
3. [+-]HH (e.g. "+09")
2. [+-]HHMM (e.g. "+0900")
1. [+-]HH:MM (e.g. "+09:00")

such as PST and JST are not supported intentionally.
Valid formats are as follows. Note that timezone abbreviations

Validate the format of the specified timezone.
def self.validate(timezone)
  # If the specified timezone is nil.
  if timezone.nil?
    # Invalid.
    return false
  end
  # [+-]HH:MM, [+-]HHMM, [+-]HH
  if NUMERIC_PATTERN === timezone
    # Valid. It can be parsed by Time.zone_offset method.
    return true
  end
  # Region/Zone, Region/Zone/Zone
  if NAME_PATTERN === timezone
    begin
      # Get a Timezone instance for the specified timezone.
      TZInfo::Timezone.get(timezone)
    rescue
      # Invalid. The string does not exist in the timezone database.
      return false
    else
      # Valid. The string was found in the timezone database.
      return true
    end
  else
    # Invalid. Timezone abbreviations are not supported.
    return false
  end
end

def self.validate!(timezone)

method raises a ConfigError.
to check whether the given timezone is valid. When invalid, this
The implementation of this method calls validate(timezone) method

Validate the format of the specified timezone.
def self.validate!(timezone)
  unless validate(timezone)
    raise ConfigError, "Unsupported timezone '#{timezone}'"
  end
end