class TwitterCldr::Formatters::DateTimeFormatter

Constants

METHODS
TZ_PATTERNS
WEEKDAY_KEYS

Protected Instance Methods

calendar() click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 87
def calendar
  data_reader.calendar
end
day(date, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 200
def day(date, pattern, length, options = {})
  case length
    when 1
      date.day.to_s
    when 2
      date.day.to_s.rjust(length, '0')
  end
end
day_of_week_in_month(date, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 121
def day_of_week_in_month(date, pattern, length, options = {}) # e.g. 2nd Wed in July
  week_fields_for(date)[:day_of_week_in_month].to_s
end
era(date, pattern, length, options = {}) click to toggle source

There is incomplete era data in CLDR for certain locales like Hindi. Fall back if that happens.

# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 93
def era(date, pattern, length, options = {})
  choices = case length
    when 0
      ["", ""]
    when 1..3
      calendar.eras(:abbr)
    else
      calendar.eras(:name)
  end

  if result = choices[date.year < 0 ? 0 : 1]
    result
  else
    era(date, pattern[0..-2], length - 1)
  end
end
format_pattern(token, index, obj, options) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 83
def format_pattern(token, index, obj, options)
  send(METHODS[token.value[0].chr], obj, token.value, token.value.size, options)
end
hour(time, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 260
def hour(time, pattern, length, options = {})
  hour = time.hour
  hour = case pattern[0, 1]
    when 'h' # [1-12]
      hour > 12 ? (hour - 12) : (hour == 0 ? 12 : hour)
    when 'H' # [0-23]
      hour
    when 'K' # [0-11]
      hour > 11 ? hour - 12 : hour
    when 'k' # [1-24]
      hour == 0 ? 24 : hour
  end
  length == 1 ? hour.to_s : hour.to_s.rjust(length, '0')
end
minute(time, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 275
def minute(time, pattern, length, options = {})
  length == 1 ? time.min.to_s : time.min.to_s.rjust(length, '0')
end
month(date, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 165
def month(date, pattern, length, options = {})
  case length
    when 1
      date.month.to_s
    when 2
      date.month.to_s.rjust(length, '0')
    when 3
      calendar.months(:abbreviated, :format)[date.month - 1]
    when 4
      calendar.months(:wide, :format)[date.month - 1]
    when 5
      raise NotImplementedError, 'requires cldr\'s "multiple inheritance"'
      # calendar[:months][:format][:narrow][date.month]
    else
      # raise unknown date format
  end
end
month_stand_alone(date, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 183
def month_stand_alone(date, pattern, length, options = {})
  case length
    when 1
      date.month.to_s
    when 2
      date.month.to_s.rjust(length, '0')
    when 3
      calendar.months(:abbreviated)[date.month - 1]
    when 4
      calendar.months(:wide)[date.month - 1]
    when 5
      calendar.months(:narrow)[date.month - 1]
    else
      # raise unknown date format
  end
end
period(time, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 241
def period(time, pattern, length, options = {})
  if pattern[0] == 'a'
    return calendar.periods(:wide, :format)[time.strftime('%p').downcase.to_sym]
  end

  period_type = TwitterCldr::Shared::DayPeriods
    .instance(data_reader.locale)
    .period_type_for(time)

  if length <= 3
    calendar.periods(:abbreviated, :format)[period_type]
  elsif length == 4 || length > 5
    calendar.periods(:wide, :format)[period_type]
  else
    # length == 5
    calendar.periods(:narrow, :format)[period_type]
  end
end
quarter(date, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 133
def quarter(date, pattern, length, options = {})
  quarter = (date.month.to_i - 1) / 3 + 1
  case length
    when 1
      quarter.to_s
    when 2
      quarter.to_s.rjust(length, '0')
    when 3
      calendar.quarters(:abbreviated, :format)[quarter]
    when 4
      calendar.quarters(:wide, :format)[quarter]
  end
end
quarter_stand_alone(date, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 147
def quarter_stand_alone(date, pattern, length, options = {})
  quarter = (date.month.to_i - 1) / 3 + 1
  case length
    when 1
      quarter.to_s
    when 2
      quarter.to_s.rjust(length, '0')
    when 3
      raise NotImplementedError, 'requires cldr\'s "multiple inheritance"'
      # calendar[:quarters][:'stand-alone'][:abbreviated][key]
    when 4
      raise NotImplementedError, 'requires cldr\'s "multiple inheritance"'
      # calendar[:quarters][:'stand-alone'][:wide][key]
    when 5
      calendar.quarters(:narrow)[quarter]
  end
end
second(time, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 279
def second(time, pattern, length, options = {})
  length == 1 ? time.sec.to_s : time.sec.to_s.rjust(length, '0')
end
second_fraction(time, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 283
def second_fraction(time, pattern, length, options = {})
  raise ArgumentError.new('can not use the S format with more than 6 digits') if length > 6
  (time.usec.to_f / 10 ** (6 - length)).round.to_s.rjust(length, '0')
end
timezone(time, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 288
def timezone(time, pattern, length, options = {})
  tz = TwitterCldr::Timezones::Timezone.instance(
    options[:timezone] || 'UTC', data_reader.locale
  )

  tz.display_name_for(time, TZ_PATTERNS[pattern])
end
week_data_cache() click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 400
def week_data_cache
  @@week_data_cache ||= {}
end
week_fields_for(date) click to toggle source

ported from icu4j 64.2

# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 297
def week_fields_for(date)
  week_data_cache[date] ||= begin
    eyear = date.year
    day_of_week = date.wday + 1
    day_of_year = date.yday

    # this should come from the CLDR's supplemental data set, but we
    # don't have access to it right now
    first_day_of_week = 1  # assume sunday
    minimal_days_in_first_week = 1  # assume US

    # WEEK_OF_YEAR start
    # Compute the week of the year.  For the Gregorian calendar, valid week
    # numbers run from 1 to 52 or 53, depending on the year, the first day
    # of the week, and the minimal days in the first week.  For other
    # calendars, the valid range may be different -- it depends on the year
    # length.  Days at the start of the year may fall into the last week of
    # the previous year; days at the end of the year may fall into the
    # first week of the next year.  ASSUME that the year length is less than
    # 7000 days.
    year_of_week_of_year = eyear
    rel_dow = (day_of_week + 7 - first_day_of_week) % 7 # 0..6
    rel_dow_jan1 = (day_of_week - day_of_year + 7001 - first_day_of_week) % 7 # 0..6
    woy = (day_of_year - 1 + rel_dow_jan1) / 7 # 0..53

    if (7 - rel_dow_jan1) >= minimal_days_in_first_week
      woy += 1
    end

    # Adjust for weeks at the year end that overlap into the previous or
    # next calendar year.
    if woy == 0
      # We are the last week of the previous year.
      # Check to see if we are in the last week; if so, we need
      # to handle the case in which we are the first week of the
      # next year.

      year_length = (Date.new(eyear, 1, 1) - Date.new(eyear - 1, 1, 1)).to_i

      prev_doy = day_of_year + year_length
      woy = week_number(prev_doy, day_of_week)
      year_of_week_of_year -= 1
    else
      last_doy = (Date.new(eyear + 1, 1, 1) - Date.new(eyear, 1, 1)).to_i
      # Fast check: For it to be week 1 of the next year, the DOY
      # must be on or after L-5, where L is yearLength(), then it
      # cannot possibly be week 1 of the next year:
      #          L-5                  L
      # doy: 359 360 361 362 363 364 365 001
      # dow:      1   2   3   4   5   6   7
      if day_of_year >= (last_doy - 5)
        last_rel_dow = (rel_dow + last_doy - day_of_year) % 7

        if (last_rel_dow < 0)
          last_rel_dow += 7
        end

        if ((6 - last_rel_dow) >= minimal_days_in_first_week) && ((day_of_year + 7 - rel_dow) > last_doy)
          woy = 1;
          year_of_week_of_year += 1
        end
      end
    end

    {
      week_of_year: woy,
      year_woy: year_of_week_of_year,
      week_of_month: week_number(date.mday, day_of_week),
      day_of_week_in_month: (date.mday - 1) / 7 + 1
    }
  end
end
week_number(day_of_period, day_of_week) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 370
def week_number(day_of_period, day_of_week)
  # this should come from the CLDR's supplemental data set, but we
  # don't have access to it right now
  first_day_of_week = 1  # assume sunday
  minimal_days_in_first_week = 1  # assume US

  # Determine the day of the week of the first day of the period
  # in question (either a year or a month).  Zero represents the
  # first day of the week on this calendar.
  period_start_day_of_week = (day_of_week - first_day_of_week - day_of_period + 1) % 7

  if (period_start_day_of_week < 0)
    period_start_day_of_week += 7
  end

  # Compute the week number.  Initially, ignore the first week, which
  # may be fractional (or may not be).  We add period_start_day_of_week in
  # order to fill out the first week, if it is fractional.
  week_no = (day_of_period + period_start_day_of_week - 1) / 7

  # If the first week is long enough, then count it.  If
  # the minimal days in the first week is one, or if the period start
  # is zero, we always increment weekNo.
  if (7 - period_start_day_of_week) >= minimal_days_in_first_week
    week_no += 1
  end

  week_no
end
week_of_month(date, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 125
def week_of_month(date, pattern, length, options = {})
  week_fields_for(date)[:week_of_month].to_s
end
week_of_year(date, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 129
def week_of_year(date, pattern, length, options = {})
  week_fields_for(date)[:week_of_year].to_s
end
weekday(date, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 209
def weekday(date, pattern, length, options = {})
  key = WEEKDAY_KEYS[date.wday]
  case length
    when 1..3
      calendar.weekdays(:abbreviated, :format)[key]
    when 4
      calendar.weekdays(:wide, :format)[key]
    when 5
      calendar.weekdays(:narrow)[key]
  end
end
weekday_local(date, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 221
def weekday_local(date, pattern, length, options = {})
  # "Like E except adds a numeric value depending on the local starting day of the week"
  # CLDR does not contain data as to which day is the first day of the week, so we will assume Monday (Ruby default)
  case length
    when 1..2
      date.cwday.to_s
    else
      weekday(date, pattern, length)
  end
end
weekday_local_stand_alone(date, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 232
def weekday_local_stand_alone(date, pattern, length, options = {})
  case length
    when 1
      weekday_local(date, pattern, length)
    else
      weekday(date, pattern, length)
  end
end
year(date, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 110
def year(date, pattern, length, options = {})
  year = date.year.to_s
  year = year.length == 1 ? year : year[-2, 2] if length == 2
  year = year.rjust(length, '0') if length > 1
  year
end
year_of_week_of_year(date, pattern, length, options = {}) click to toggle source
# File lib/twitter_cldr/formatters/calendars/date_time_formatter.rb, line 117
def year_of_week_of_year(date, pattern, length, options = {})
  week_fields_for(date)[:year_woy].to_s
end