Module: XlsFunction::Converters::TimeConverter

Defined in:
lib/xls_function/converters/time_converter.rb

Constant Summary collapse

FORMAT_MAP =
{
  'yyyy' => '%Y',
  'yy' => '%y',
  'm' => '%m',
  'mm' => '%m',
  'mmm' => '%b',
  'mmmm' => '%B',
  'mmmmm' => '%B',
  'd' => '%d',
  'dd' => '%d',
  'aaa' => '%w',
  'aaaa' => '%w',
  'ddd' => '%a',
  'dddd' => '%A',
  'e' => '%Jg',
  'ee' => '%Jg',
  'r' => '%Jg',
  'g' => '%Je',
  'gg' => '%Je',
  'ggg' => '%Je',
  'hh' => '%H',
  'h' => '%H',
  'M' => '%M',
  'MM' => '%M',
  's' => '%S',
  'ss' => '%S',
  '.0' => '%1N',
  '.00' => '%2N',
  '.000' => '%3N'
}.freeze
WEEKDAYS_JP =
%w[      ].freeze
WAREKI_ALPHABETS =
{
  '明治' => 'M',
  '大正' => 'T',
  '昭和' => 'S',
  '平成' => 'H',
  '令和' => 'R'
}.freeze

Class Method Summary collapse

Class Method Details

.adjust_elapsed_time(hour, minute, second) ⇒ Object



148
149
150
151
152
153
154
# File 'lib/xls_function/converters/time_converter.rb', line 148

def adjust_elapsed_time(hour, minute, second)
  elapsed_minute, s = second.divmod(60)
  elapsed_hour, m = (minute + elapsed_minute).divmod(60)
  elapsed_day, h = (hour + elapsed_hour).divmod(24)

  { day: elapsed_day, hour: h, minute: m, second: s }
end

.convert(input) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/xls_function/converters/time_converter.rb', line 15

def convert(input)
  case input
  when Time
    input
  when Date
    input.to_time
  when BigDecimal
    NumberConverter.decimal_to_time(input)
  when Numeric
    Time.at(input)
  else
    parse(input)
  end
end

.convert_format(format, ampm_mode: false) ⇒ Object

Raises:

  • (NotImplementedError)


68
69
70
71
72
73
74
# File 'lib/xls_function/converters/time_converter.rb', line 68

def convert_format(format, ampm_mode: false)
  mapped = FORMAT_MAP[format]
  mapped = '%I' if mapped == '%H' && ampm_mode
  raise NotImplementedError, "#{format} is not supported" unless mapped

  mapped
end

.convert_wareki_to_alphabet(gengo) ⇒ Object



90
91
92
# File 'lib/xls_function/converters/time_converter.rb', line 90

def convert_wareki_to_alphabet(gengo)
  WAREKI_ALPHABETS[gengo] || ''
end

.convert_weekday_jp(week_index) ⇒ Object



78
79
80
# File 'lib/xls_function/converters/time_converter.rb', line 78

def convert_weekday_jp(week_index)
  WEEKDAYS_JP[week_index]
end

.convert_with_cache(input, cache) ⇒ Object

Parameters:

  • input (object)
  • cache (Hash)

    context



32
33
34
35
# File 'lib/xls_function/converters/time_converter.rb', line 32

def convert_with_cache(input, cache)
  cache[:cache_convert_time] ||= {}
  cache[:cache_convert_time][input] ||= convert(input)
end

.fix_elapsed_time(time_value, now) ⇒ Object



104
105
106
107
108
109
110
111
112
# File 'lib/xls_function/converters/time_converter.rb', line 104

def fix_elapsed_time(time_value, now)
  h = Date._parse(time_value)
  return :throw if h.key?(:yday) # give up when yday exists.
  return :throw if !h.key?(:sec) && !h.key?(:min) && !h.key?(:hour) # give up when not elapsed time expression.

  time_str, elapsed_day = fixed_time_str(h)
  date_str = fixed_date_str(h, now, elapsed_day)
  "#{date_str} #{time_str}"
end

.fixed_date_str(parsed, now, elapsed_day) ⇒ Object



127
128
129
130
131
132
133
134
# File 'lib/xls_function/converters/time_converter.rb', line 127

def fixed_date_str(parsed, now, elapsed_day)
  year = parsed.fetch(:year, now.year)
  month = parsed.fetch(:mon, now.month)
  day = parsed.fetch(:mday, now.day)
  date = Date.new(year, month, day) + elapsed_day

  "#{date.year}-#{date.month}-#{date.day}"
end

.fixed_time_str(parsed) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/xls_function/converters/time_converter.rb', line 114

def fixed_time_str(parsed)
  sec = parsed.fetch(:sec, 0)
  min = parsed.fetch(:min, 0)
  hour = parsed.fetch(:hour, 0)

  adjusted = adjust_elapsed_time(hour, min, sec)

  [
    "#{adjusted[:hour]}:#{adjusted[:minute]}:#{adjusted[:second]}#{sec_fraction_str(parsed)}#{zone_str(parsed)}",
    adjusted[:day]
  ]
end

.invalid_time(time_value) ⇒ Object



11
12
13
# File 'lib/xls_function/converters/time_converter.rb', line 11

def invalid_time(time_value)
  I18n.t('xls_function.errors.cannot_convert_to_time', source: time_value)
end

.parse(date, now = Time.now, &block) ⇒ Object

Accepts elapsed time expression that Time.parse cannot parse.



95
96
97
98
99
100
101
102
# File 'lib/xls_function/converters/time_converter.rb', line 95

def parse(date, now = Time.now, &block)
  Time.parse(date, now, &block)
rescue ArgumentError
  result = fix_elapsed_time(date, now)
  raise if result == :throw

  Time.parse(result, now, &block)
end

.sec_fraction_str(parsed) ⇒ Object



136
137
138
139
140
# File 'lib/xls_function/converters/time_converter.rb', line 136

def sec_fraction_str(parsed)
  return '' unless parsed.key?(:sec_fraction)

  ".#{(parsed[:sec_fraction] * 1000).to_i.to_s.rjust(3, '0')}"
end

.try_convert(time_value) ⇒ Object



5
6
7
8
9
# File 'lib/xls_function/converters/time_converter.rb', line 5

def try_convert(time_value)
  [true, convert(time_value)]
rescue ArgumentError
  [false, invalid_time(time_value)]
end

.zone_str(parsed) ⇒ Object



142
143
144
145
146
# File 'lib/xls_function/converters/time_converter.rb', line 142

def zone_str(parsed)
  return '' unless parsed.key?(:zone)

  " #{parsed[:zone]}"
end