ffi-icu 0.4.0 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/ffi-icu/lib/util.rb +14 -2
- data/lib/ffi-icu/lib.rb +13 -5
- data/lib/ffi-icu/number_formatting.rb +13 -4
- data/lib/ffi-icu/time_formatting.rb +133 -18
- data/lib/ffi-icu/uchar.rb +4 -0
- data/lib/ffi-icu/version.rb +1 -1
- data/spec/number_formatting_spec.rb +5 -0
- data/spec/time_spec.rb +92 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e05cacd8501af573e102abe908556c1ea0f2eb1990b560271890c9d0827feb09
|
4
|
+
data.tar.gz: 4c5433c4183b376548f20ff533311d1acc61035d395b63a35f8e89a387ca7d98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a40fa82617a2c16aa759b263e5153e4135b5844823666ac5d0b5d205b300819f3ac1cf10d5e8e9f9182c2357080e6ed6add40388287b308ef6eae645f052a38f
|
7
|
+
data.tar.gz: 4d34feb23961b844cc9701d09a52a806f375bc58b10a04622d2230d57a1a97cd015f004ed72239a039041e901d304deb4051f81400191981116b7b055ef8b15b
|
data/lib/ffi-icu/lib/util.rb
CHANGED
@@ -28,7 +28,19 @@ module ICU
|
|
28
28
|
result.read_string(length)
|
29
29
|
end
|
30
30
|
|
31
|
-
def self.read_uchar_buffer(length)
|
31
|
+
def self.read_uchar_buffer(length, &blk)
|
32
|
+
buf, len = read_uchar_buffer_as_ptr_impl(length, &blk)
|
33
|
+
buf.string(len)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.read_uchar_buffer_as_ptr(length, &blk)
|
37
|
+
buf, _ = read_uchar_buffer_as_ptr_impl(length, &blk)
|
38
|
+
buf
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def self.read_uchar_buffer_as_ptr_impl(length)
|
32
44
|
attempts = 0
|
33
45
|
|
34
46
|
begin
|
@@ -40,7 +52,7 @@ module ICU
|
|
40
52
|
raise BufferOverflowError, "needed: #{length}"
|
41
53
|
end
|
42
54
|
|
43
|
-
result
|
55
|
+
[result, length]
|
44
56
|
end
|
45
57
|
end
|
46
58
|
end
|
data/lib/ffi-icu/lib.rb
CHANGED
@@ -19,9 +19,7 @@ module ICU
|
|
19
19
|
'/usr/local/{lib64,lib}',
|
20
20
|
'/opt/local/{lib64,lib}',
|
21
21
|
'/usr/{lib64,lib}',
|
22
|
-
|
23
|
-
'/usr/lib/i386-linux-gnu', # for Debian Multiarch
|
24
|
-
]
|
22
|
+
] + Dir['/usr/lib/*-linux-gnu'] # for Debian Multiarch http://wiki.debian.org/Multiarch
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
@@ -39,8 +37,12 @@ module ICU
|
|
39
37
|
[find_lib("libicui18n.#{FFI::Platform::LIBSUFFIX}.??"),
|
40
38
|
find_lib("libicutu.#{FFI::Platform::LIBSUFFIX}.??")]
|
41
39
|
when :osx
|
42
|
-
|
43
|
-
|
40
|
+
if ENV.key?('FFI_ICU_LIB')
|
41
|
+
# Ensure we look in the user-supplied override dir for a user-compiled libicu
|
42
|
+
[find_lib("libicui18n.??.#{FFI::Platform::LIBSUFFIX}"),
|
43
|
+
find_lib("libicutu.??.#{FFI::Platform::LIBSUFFIX}")]
|
44
|
+
elsif Gem::Version.new(`sw_vers -productVersion`) >= Gem::Version.new('11')
|
45
|
+
# See https://developer.apple.com/documentation/macos-release-notes/macos-big-sur-11_0_1-release-notes (62986286)
|
44
46
|
["libicucore.#{FFI::Platform::LIBSUFFIX}"]
|
45
47
|
else
|
46
48
|
[find_lib("libicucore.#{FFI::Platform::LIBSUFFIX}")]
|
@@ -432,6 +434,10 @@ module ICU
|
|
432
434
|
:medium, 2,
|
433
435
|
:short, 3,
|
434
436
|
]
|
437
|
+
enum :uloc_data_locale_type, [
|
438
|
+
:actual_locale, 0,
|
439
|
+
:valid_locale, 1,
|
440
|
+
]
|
435
441
|
attach_function :udat_open, "udat_open#{suffix}", [:date_format_style, :date_format_style, :string, :pointer, :int32_t, :pointer, :int32_t, :pointer ], :pointer
|
436
442
|
attach_function :udat_close, "unum_close#{suffix}", [:pointer], :void
|
437
443
|
attach_function :udat_format, "udat_format#{suffix}", [:pointer, :double, :pointer, :int32_t, :pointer, :pointer], :int32_t
|
@@ -440,7 +446,9 @@ module ICU
|
|
440
446
|
attach_function :udat_applyPattern, "udat_applyPattern#{suffix}", [:pointer, :bool , :pointer, :int32_t ], :void
|
441
447
|
# skeleton pattern
|
442
448
|
attach_function :udatpg_open, "udatpg_open#{suffix}", [:string, :pointer], :pointer
|
449
|
+
attach_function :udatpg_close, "udatpg_close#{suffix}", [:pointer], :void
|
443
450
|
attach_function :udatpg_getBestPattern, "udatpg_getBestPattern#{suffix}", [:pointer, :pointer, :int32_t, :pointer, :int32_t, :pointer], :int32_t
|
451
|
+
attach_function :udatpg_getSkeleton, "udatpg_getSkeleton#{suffix}", [:pointer, :pointer, :int32_t, :pointer, :int32_t, :pointer], :int32_t
|
444
452
|
# tz
|
445
453
|
attach_function :ucal_setDefaultTimeZone, "ucal_setDefaultTimeZone#{suffix}", [:pointer, :pointer], :int32_t
|
446
454
|
attach_function :ucal_getDefaultTimeZone, "ucal_getDefaultTimeZone#{suffix}", [:pointer, :int32_t, :pointer], :int32_t
|
@@ -68,8 +68,19 @@ module ICU
|
|
68
68
|
case number
|
69
69
|
when Float
|
70
70
|
needed_length = Lib.unum_format_double(@f, number, out_ptr, needed_length, nil, error)
|
71
|
-
when
|
72
|
-
|
71
|
+
when Integer
|
72
|
+
begin
|
73
|
+
# Try doing it fast, for integers that can be marshaled into an int64_t
|
74
|
+
needed_length = Lib.unum_format_int64(@f, number, out_ptr, needed_length, nil, error)
|
75
|
+
rescue RangeError
|
76
|
+
# Fall back to stringifying in Ruby and passing that to ICU
|
77
|
+
unless defined? Lib.unum_format_decimal
|
78
|
+
raise RangeError,"Number #{number} is too big to fit in int64_t and your "\
|
79
|
+
"ICU version is too old to have unum_format_decimal"
|
80
|
+
end
|
81
|
+
string_version = number.to_s
|
82
|
+
needed_length = Lib.unum_format_decimal(@f, string_version, string_version.bytesize, out_ptr, needed_length, nil, error)
|
83
|
+
end
|
73
84
|
when BigDecimal
|
74
85
|
string_version = number.to_s('F')
|
75
86
|
if Lib.respond_to? :unum_format_decimal
|
@@ -77,8 +88,6 @@ module ICU
|
|
77
88
|
else
|
78
89
|
needed_length = Lib.unum_format_double(@f, number.to_f, out_ptr, needed_length, nil, error)
|
79
90
|
end
|
80
|
-
when Bignum
|
81
|
-
needed_length = Lib.unum_format_int64(@f, number, out_ptr, needed_length, nil, error)
|
82
91
|
end
|
83
92
|
end
|
84
93
|
out_ptr.string needed_length
|
@@ -38,6 +38,14 @@ module ICU
|
|
38
38
|
# (for example, "Unknown City"), such as Los Angeles
|
39
39
|
# see: http://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
|
40
40
|
}
|
41
|
+
|
42
|
+
HOUR_CYCLE_SYMS = {
|
43
|
+
'h11' => 'K',
|
44
|
+
'h12' => 'h',
|
45
|
+
'h23' => 'H',
|
46
|
+
'h24' => 'k',
|
47
|
+
:locale => 'j',
|
48
|
+
}
|
41
49
|
@default_options = {}
|
42
50
|
|
43
51
|
def self.create(options = {})
|
@@ -96,14 +104,19 @@ module ICU
|
|
96
104
|
|
97
105
|
class DateTimeFormatter < BaseFormatter
|
98
106
|
def initialize(options={})
|
99
|
-
time_style
|
100
|
-
date_style
|
101
|
-
locale = options[:locale] || 'C'
|
102
|
-
tz_style
|
103
|
-
time_zone
|
104
|
-
skeleton
|
105
|
-
|
106
|
-
|
107
|
+
time_style = options[:time] || :short
|
108
|
+
date_style = options[:date] || :short
|
109
|
+
@locale = options[:locale] || 'C'
|
110
|
+
tz_style = options[:tz_style]
|
111
|
+
time_zone = options[:zone]
|
112
|
+
skeleton = options[:skeleton]
|
113
|
+
@hour_cycle = options[:hour_cycle]
|
114
|
+
|
115
|
+
if @hour_cycle && !HOUR_CYCLE_SYMS.keys.include?(@hour_cycle)
|
116
|
+
raise ICU::Error.new("Unknown hour cycle #{@hour_cycle}")
|
117
|
+
end
|
118
|
+
|
119
|
+
@f = make_formatter(time_style, date_style, @locale, time_zone, skeleton)
|
107
120
|
if tz_style
|
108
121
|
f0 = date_format(true)
|
109
122
|
f1 = update_tz_format(f0, tz_style)
|
@@ -111,11 +124,13 @@ module ICU
|
|
111
124
|
set_date_format(true, f1)
|
112
125
|
end
|
113
126
|
end
|
127
|
+
|
128
|
+
replace_hour_symbol!
|
114
129
|
end
|
115
130
|
|
116
131
|
def parse(str)
|
117
132
|
str_u = UCharPointer.from_string(str)
|
118
|
-
str_l =
|
133
|
+
str_l = str.size
|
119
134
|
Lib.check_error do |error|
|
120
135
|
ret = Lib.udat_parse(@f, str_u, str_l, nil, error)
|
121
136
|
Time.at(ret / 1000.0)
|
@@ -182,28 +197,28 @@ module ICU
|
|
182
197
|
end
|
183
198
|
|
184
199
|
def set_date_format(localized, pattern_str)
|
185
|
-
|
186
|
-
pattern_len = pattern_str.size
|
200
|
+
set_date_format_impl(localized, pattern_str)
|
187
201
|
|
188
|
-
|
189
|
-
|
190
|
-
|
202
|
+
# After setting the date format string, we need to ensure that any hour
|
203
|
+
# symbols were properly localised according to @hour_cycle.
|
204
|
+
replace_hour_symbol!
|
191
205
|
end
|
192
206
|
|
193
|
-
def skeleton_format(
|
194
|
-
|
207
|
+
def skeleton_format(skeleton_pattern_str, locale)
|
208
|
+
skeleton_pattern_ptr = UCharPointer.from_string(skeleton_pattern_str)
|
209
|
+
skeleton_pattern_len = skeleton_pattern_str.size
|
195
210
|
|
196
211
|
needed_length = 0
|
197
212
|
pattern_ptr = UCharPointer.new(needed_length)
|
198
213
|
|
199
214
|
udatpg_ptr = Lib.check_error { |error| Lib.udatpg_open(locale, error) }
|
200
|
-
generator = FFI::AutoPointer.new(udatpg_ptr, Lib.method(:
|
215
|
+
generator = FFI::AutoPointer.new(udatpg_ptr, Lib.method(:udatpg_close))
|
201
216
|
|
202
217
|
retried = false
|
203
218
|
|
204
219
|
begin
|
205
220
|
Lib.check_error do |error|
|
206
|
-
needed_length = Lib.udatpg_getBestPattern(generator,
|
221
|
+
needed_length = Lib.udatpg_getBestPattern(generator, skeleton_pattern_ptr, skeleton_pattern_len, pattern_ptr, needed_length, error)
|
207
222
|
end
|
208
223
|
|
209
224
|
return needed_length, pattern_ptr
|
@@ -214,6 +229,106 @@ module ICU
|
|
214
229
|
retry
|
215
230
|
end
|
216
231
|
end
|
232
|
+
|
233
|
+
private
|
234
|
+
|
235
|
+
# Converts the current pattern to a pattern that takes the desired hour cycle
|
236
|
+
# into account. This is needed because most of the standard patterns in ICU
|
237
|
+
# contain either h (12 hour) or H (23 hour) in them, instead of j (locale-
|
238
|
+
# specified hour cycle). This means if you use a locale with an @hours=h12
|
239
|
+
# keyword in it, for example, it would normally be totally ignored by ICU.
|
240
|
+
#
|
241
|
+
# This is the same fixup done by Firefox:
|
242
|
+
# https://github.com/tc39/ecma402/issues/665#issuecomment-1084833809
|
243
|
+
# https://searchfox.org/mozilla-central/rev/625c3d0c8ae46502aed83f33bd530cb93e926e9f/intl/components/src/DateTimeFormat.cpp#282-323
|
244
|
+
def replace_hour_symbol!
|
245
|
+
# Short circuit this case - nil means "use whatever is in the pattern already", so
|
246
|
+
# no need to actually run any of this implementation.
|
247
|
+
return unless @hour_cycle
|
248
|
+
|
249
|
+
# Get the current pattern and convert to a skeleton
|
250
|
+
skeleton_str = pattern_to_skeleton_uchar(current_pattern_as_uchar).string
|
251
|
+
|
252
|
+
# Manipulate the skeleton to make it work with the correct hour cycle.
|
253
|
+
skeleton_str.gsub!(/[hHkKjJ]/, HOUR_CYCLE_SYMS[@hour_cycle])
|
254
|
+
|
255
|
+
# Either ensure the skeleton has, or does not have, am/pm, as appropriate
|
256
|
+
if ['h11', 'h12'].include?(@hour_cycle)
|
257
|
+
# Only actually append 'am/pm' if there is an hour in the format string
|
258
|
+
if skeleton_str =~ /[hHkKjJ]/ && !skeleton_str.include?('a')
|
259
|
+
skeleton_str << 'a'
|
260
|
+
end
|
261
|
+
else
|
262
|
+
skeleton_str.gsub!('a', '')
|
263
|
+
end
|
264
|
+
|
265
|
+
# Convert the skeleton back to a pattern
|
266
|
+
new_pattern_str = skeleton_to_pattern_uchar(UCharPointer.from_string(skeleton_str)).string
|
267
|
+
|
268
|
+
# We also need to manipulate the _pattern_, a little bit, because (according to Firefox source):
|
269
|
+
#
|
270
|
+
# Input skeletons don't differentiate between "K" and "h" resp. "k" and "H".
|
271
|
+
#
|
272
|
+
# https://searchfox.org/mozilla-central/rev/625c3d0c8ae46502aed83f33bd530cb93e926e9f/intl/components/src/DateTimeFormat.cpp#183
|
273
|
+
# So, if we put a skeleton with a k in it into getBestPattern, it comes out with a H (and a
|
274
|
+
# skeleton with a K in it comes out with a h). Need to fix this in the generated pattern.
|
275
|
+
resolved_hour_cycle = @hour_cycle == :locale ? Locale.new(@locale).keyword('hours') : @hour_cycle
|
276
|
+
|
277
|
+
if HOUR_CYCLE_SYMS.keys.include?(resolved_hour_cycle)
|
278
|
+
new_pattern_str.gsub!(/[hHkK]/, HOUR_CYCLE_SYMS[resolved_hour_cycle])
|
279
|
+
end
|
280
|
+
|
281
|
+
# Finally, set the new pattern onto the date time formatter
|
282
|
+
set_date_format_impl(false, new_pattern_str)
|
283
|
+
end
|
284
|
+
|
285
|
+
# Load up the date formatter locale and make a generator
|
286
|
+
# Note that we _MUST_ actually use @locale as passed to us, rather than calling
|
287
|
+
# udat_getLocaleByType to look it up from @f, because the latter will throw away
|
288
|
+
# any @hours specifier in the locale, and we need it.
|
289
|
+
def datetime_pattern_generator
|
290
|
+
@datetime_pattern_generator ||= FFI::AutoPointer.new(
|
291
|
+
Lib.check_error { |error| Lib.udatpg_open(@locale, error) },
|
292
|
+
Lib.method(:udatpg_close)
|
293
|
+
)
|
294
|
+
end
|
295
|
+
|
296
|
+
def current_pattern_as_uchar
|
297
|
+
Lib::Util.read_uchar_buffer_as_ptr(0) do |buf, error|
|
298
|
+
Lib.udat_toPattern(@f, false, buf, buf.length_in_uchars, error)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
def pattern_to_skeleton_uchar(pattern_uchar)
|
303
|
+
Lib::Util.read_uchar_buffer_as_ptr(0) do |buf, error|
|
304
|
+
Lib.udatpg_getSkeleton(
|
305
|
+
datetime_pattern_generator,
|
306
|
+
pattern_uchar, pattern_uchar.length_in_uchars,
|
307
|
+
buf, buf.length_in_uchars,
|
308
|
+
error
|
309
|
+
)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
def skeleton_to_pattern_uchar(skeleton_uchar)
|
314
|
+
Lib::Util.read_uchar_buffer_as_ptr(0) do |buf, error|
|
315
|
+
Lib.udatpg_getBestPattern(
|
316
|
+
datetime_pattern_generator,
|
317
|
+
skeleton_uchar, skeleton_uchar.length_in_uchars,
|
318
|
+
buf, buf.length_in_uchars,
|
319
|
+
error
|
320
|
+
)
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
def set_date_format_impl(localized, pattern_str)
|
325
|
+
pattern = UCharPointer.from_string(pattern_str)
|
326
|
+
pattern_len = pattern_str.size
|
327
|
+
|
328
|
+
Lib.check_error do |error|
|
329
|
+
needed_length = Lib.udat_applyPattern(@f, localized, pattern, pattern_len)
|
330
|
+
end
|
331
|
+
end
|
217
332
|
end # DateTimeFormatter
|
218
333
|
end # Formatting
|
219
334
|
end # ICU
|
data/lib/ffi-icu/uchar.rb
CHANGED
data/lib/ffi-icu/version.rb
CHANGED
@@ -69,6 +69,11 @@ module ICU
|
|
69
69
|
expect { NumberFormatting.create('en-US', :currency, style: :iso) }.to raise_error(StandardError)
|
70
70
|
end
|
71
71
|
end
|
72
|
+
|
73
|
+
it 'should format a bignum' do
|
74
|
+
str = NumberFormatting.format_number("en", 1_000_000_000_000_000_000_000_000_000_000_000_000_000)
|
75
|
+
expect(str).to eq('1,000,000,000,000,000,000,000,000,000,000,000,000,000')
|
76
|
+
end
|
72
77
|
end
|
73
78
|
end # NumberFormatting
|
74
79
|
end # ICU
|
data/spec/time_spec.rb
CHANGED
@@ -95,6 +95,98 @@ module ICU
|
|
95
95
|
expect(f4.date_format(true)).to eq("MMM y")
|
96
96
|
end
|
97
97
|
end
|
98
|
+
|
99
|
+
context 'hour cycle' do
|
100
|
+
# en_AU normally is 12 hours, fr_FR is normally 23 hours
|
101
|
+
['en_AU', 'fr_FR', 'zh_CN'].each do |locale_name|
|
102
|
+
context "with locale #{locale_name}" do
|
103
|
+
it 'works with hour_cycle: h11' do
|
104
|
+
t = Time.new(2021, 04, 01, 12, 05, 0, "+00:00")
|
105
|
+
str = TimeFormatting.format(t, time: :short, date: :none, locale: locale_name, zone: 'UTC', hour_cycle: 'h11')
|
106
|
+
expect(str).to match(/0:05/i)
|
107
|
+
expect(str).to match(/(pm|下午)/i)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'works with hour_cycle: h12' do
|
111
|
+
t = Time.new(2021, 04, 01, 12, 05, 0, "+00:00")
|
112
|
+
str = TimeFormatting.format(t, time: :short, date: :none, locale: locale_name, zone: 'UTC', hour_cycle: 'h12')
|
113
|
+
expect(str).to match(/12:05/i)
|
114
|
+
expect(str).to match(/(pm|下午)/i)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'works with hour_cycle: h23' do
|
118
|
+
t = Time.new(2021, 04, 01, 00, 05, 0, "+00:00")
|
119
|
+
str = TimeFormatting.format(t, time: :short, date: :none, locale: locale_name, zone: 'UTC', hour_cycle: 'h23')
|
120
|
+
expect(str).to match(/0:05/i)
|
121
|
+
expect(str).to_not match(/(am|pm)/i)
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'works with hour_cycle: h24' do
|
125
|
+
t = Time.new(2021, 04, 01, 00, 05, 0, "+00:00")
|
126
|
+
str = TimeFormatting.format(t, time: :short, date: :none, locale: locale_name, zone: 'UTC', hour_cycle: 'h24')
|
127
|
+
expect(str).to match(/24:05/i)
|
128
|
+
expect(str).to_not match(/(am|pm)/i)
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'does not include am/pm if time is not requested' do
|
132
|
+
t = Time.new(2021, 04, 01, 00, 05, 0, "+00:00")
|
133
|
+
str = TimeFormatting.format(t, time: :none, date: :short, locale: locale_name, zone: 'UTC', hour_cycle: 'h12')
|
134
|
+
expect(str).to_not match(/(am|pm|下午|上午)/i)
|
135
|
+
end
|
136
|
+
|
137
|
+
context '@hours keyword' do
|
138
|
+
before(:each) do
|
139
|
+
skip("Only works on ICU >= 67") if Lib.version.to_a[0] < 67
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'works with @hours=h11 keyword' do
|
143
|
+
t = Time.new(2021, 04, 01, 12, 05, 0, "+00:00")
|
144
|
+
locale = Locale.new(locale_name).with_keyword('hours', 'h11').to_s
|
145
|
+
str = TimeFormatting.format(t, time: :short, date: :none, locale: locale, zone: 'UTC', hour_cycle: :locale)
|
146
|
+
expect(str).to match(/0:05/i)
|
147
|
+
expect(str).to match(/(pm|下午)/i)
|
148
|
+
end
|
149
|
+
it 'works with @hours=h12 keyword' do
|
150
|
+
t = Time.new(2021, 04, 01, 12, 05, 0, "+00:00")
|
151
|
+
locale = Locale.new(locale_name).with_keyword('hours', 'h12').to_s
|
152
|
+
str = TimeFormatting.format(t, time: :short, date: :none, locale: locale, zone: 'UTC', hour_cycle: :locale)
|
153
|
+
expect(str).to match(/12:05/i)
|
154
|
+
expect(str).to match(/(pm|下午)/i)
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'works with @hours=h23 keyword' do
|
158
|
+
t = Time.new(2021, 04, 01, 00, 05, 0, "+00:00")
|
159
|
+
locale = Locale.new(locale_name).with_keyword('hours', 'h23').to_s
|
160
|
+
str = TimeFormatting.format(t, time: :short, date: :none, locale: locale, zone: 'UTC', hour_cycle: :locale)
|
161
|
+
expect(str).to match(/0:05/i)
|
162
|
+
expect(str).to_not match(/(am|pm)/i)
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'works with @hours=h24 keyword' do
|
166
|
+
t = Time.new(2021, 04, 01, 00, 05, 0, "+00:00")
|
167
|
+
locale = Locale.new(locale_name).with_keyword('hours', 'h24').to_s
|
168
|
+
str = TimeFormatting.format(t, time: :short, date: :none, locale: locale, zone: 'UTC', hour_cycle: :locale)
|
169
|
+
expect(str).to match(/24:05/i)
|
170
|
+
expect(str).to_not match(/(am|pm)/i)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'works with defaults on a h12 locale' do
|
177
|
+
t = Time.new(2021, 04, 01, 13, 05, 0, "+00:00")
|
178
|
+
str = TimeFormatting.format(t, time: :short, date: :none, locale: 'en_AU', zone: 'UTC', hour_cycle: :locale)
|
179
|
+
expect(str).to match(/1:05/i)
|
180
|
+
expect(str).to match(/pm/i)
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'works with defaults on a h23 locale' do
|
184
|
+
t = Time.new(2021, 04, 01, 0, 05, 0, "+00:00")
|
185
|
+
str = TimeFormatting.format(t, time: :short, date: :none, locale: 'fr_FR', zone: 'UTC', hour_cycle: :locale)
|
186
|
+
expect(str).to match(/0:05/i)
|
187
|
+
expect(str).to_not match(/(am|pm)/i)
|
188
|
+
end
|
189
|
+
end
|
98
190
|
end
|
99
191
|
end
|
100
192
|
end
|