Class: ICU::TimeFormatting::DateTimeFormatter

Inherits:
BaseFormatter show all
Defined in:
lib/ffi-icu/time_formatting.rb

Instance Method Summary collapse

Methods inherited from BaseFormatter

#set_attributes

Constructor Details

#initialize(options = {}) ⇒ DateTimeFormatter

Returns a new instance of DateTimeFormatter.



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/ffi-icu/time_formatting.rb', line 106

def initialize(options={})
  time_style  = options[:time]   || :short
  date_style  = options[:date]   || :short
  @locale     = options[:locale] || 'C'
  tz_style    = options[:tz_style]
  time_zone   = options[:zone]
  skeleton    = options[:skeleton]
  @hour_cycle = options[:hour_cycle]

  if @hour_cycle && !HOUR_CYCLE_SYMS.keys.include?(@hour_cycle)
    raise ICU::Error.new("Unknown hour cycle #{@hour_cycle}")
  end

  @f = make_formatter(time_style, date_style, @locale, time_zone, skeleton)
  if tz_style
    f0 = date_format(true)
    f1 = update_tz_format(f0, tz_style)    
    if f1 != f0
      set_date_format(true, f1)
    end
  end

  replace_hour_symbol!
end

Instance Method Details

#date_format(localized = true) ⇒ Object



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/ffi-icu/time_formatting.rb', line 179

def date_format(localized=true)
  needed_length = 0
  out_ptr = UCharPointer.new(needed_length)

  retried = false

  begin
    Lib.check_error do |error|
      needed_length = Lib.udat_toPattern(@f, localized, out_ptr, needed_length, error)
    end

    out_ptr.string
  rescue BufferOverflowError
    raise BufferOverflowError, "needed: #{needed_length}" if retried
    out_ptr = out_ptr.resized_to needed_length
    retried = true
    retry
  end
end

#format(dt) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/ffi-icu/time_formatting.rb', line 140

def format(dt)
  needed_length = 0
  out_ptr = UCharPointer.new(needed_length)

  retried = false

  begin
    Lib.check_error do |error|
      case dt
      when Date
        needed_length = Lib.udat_format(@f, Time.mktime( dt.year, dt.month, dt.day, 0, 0, 0, 0 ).to_f * 1000.0, out_ptr, needed_length, nil, error)
      when Time
        needed_length = Lib.udat_format(@f, dt.to_f * 1000.0, out_ptr, needed_length, nil, error)
      end
    end

    out_ptr.string
  rescue BufferOverflowError
    raise BufferOverflowError, "needed: #{needed_length}" if retried
    out_ptr = out_ptr.resized_to needed_length
    retried = true
    retry
  end
end

#parse(str) ⇒ Object



131
132
133
134
135
136
137
138
# File 'lib/ffi-icu/time_formatting.rb', line 131

def parse(str)
    str_u = UCharPointer.from_string(str)
    str_l = str.size
    Lib.check_error do |error|
      ret = Lib.udat_parse(@f, str_u, str_l, nil, error)
      Time.at(ret / 1000.0)
    end
end

#set_date_format(localized, pattern_str) ⇒ Object



199
200
201
202
203
204
205
# File 'lib/ffi-icu/time_formatting.rb', line 199

def set_date_format(localized, pattern_str)
  set_date_format_impl(localized, pattern_str)

  # After setting the date format string, we need to ensure that any hour
  # symbols were properly localised according to @hour_cycle.
  replace_hour_symbol!
end

#skeleton_format(skeleton_pattern_str, locale) ⇒ Object



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/ffi-icu/time_formatting.rb', line 207

def skeleton_format(skeleton_pattern_str, locale)
    skeleton_pattern_ptr = UCharPointer.from_string(skeleton_pattern_str)
    skeleton_pattern_len = skeleton_pattern_str.size

    needed_length = 0
    pattern_ptr = UCharPointer.new(needed_length)

    udatpg_ptr = Lib.check_error { |error| Lib.udatpg_open(locale, error) }
    generator = FFI::AutoPointer.new(udatpg_ptr, Lib.method(:udatpg_close))

    retried = false

  begin
    Lib.check_error do |error|
      needed_length = Lib.udatpg_getBestPattern(generator, skeleton_pattern_ptr, skeleton_pattern_len, pattern_ptr, needed_length, error)
    end

    return needed_length, pattern_ptr
  rescue BufferOverflowError
    raise BufferOverflowError, "needed: #{needed_length}" if retried
    pattern_ptr = pattern_ptr.resized_to needed_length
    retried = true
    retry
  end
end

#update_tz_format(format, tz_style) ⇒ Object

time-zone formating



166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/ffi-icu/time_formatting.rb', line 166

def update_tz_format(format, tz_style)
  return format if format !~ /(.*?)(\s*(?:[zZOVV]+\s*))(.*?)/
  pre, tz, suff = $1, $2, $3
  if tz_style == :none
    tz = ((tz =~ /\s/) && !pre.empty? && !suff.empty?) ? ' ' : ''
  else
    repl = TZ_MAP[tz_style]
    raise 'no such tz_style' unless repl
    tz.gsub!(/^(\s*)(.*?)(\s*)$/, '\1'+repl+'\3')
  end
  pre + tz + suff
end