ffi-icu 0.4.0 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|