i18n 1.6.0

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.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +125 -0
  4. data/lib/i18n.rb +398 -0
  5. data/lib/i18n/backend.rb +21 -0
  6. data/lib/i18n/backend/base.rb +284 -0
  7. data/lib/i18n/backend/cache.rb +113 -0
  8. data/lib/i18n/backend/cache_file.rb +36 -0
  9. data/lib/i18n/backend/cascade.rb +56 -0
  10. data/lib/i18n/backend/chain.rb +127 -0
  11. data/lib/i18n/backend/fallbacks.rb +84 -0
  12. data/lib/i18n/backend/flatten.rb +115 -0
  13. data/lib/i18n/backend/gettext.rb +85 -0
  14. data/lib/i18n/backend/interpolation_compiler.rb +123 -0
  15. data/lib/i18n/backend/key_value.rb +206 -0
  16. data/lib/i18n/backend/memoize.rb +54 -0
  17. data/lib/i18n/backend/metadata.rb +71 -0
  18. data/lib/i18n/backend/pluralization.rb +55 -0
  19. data/lib/i18n/backend/simple.rb +111 -0
  20. data/lib/i18n/backend/transliterator.rb +108 -0
  21. data/lib/i18n/config.rb +165 -0
  22. data/lib/i18n/core_ext/hash.rb +47 -0
  23. data/lib/i18n/exceptions.rb +111 -0
  24. data/lib/i18n/gettext.rb +28 -0
  25. data/lib/i18n/gettext/helpers.rb +75 -0
  26. data/lib/i18n/gettext/po_parser.rb +329 -0
  27. data/lib/i18n/interpolate/ruby.rb +39 -0
  28. data/lib/i18n/locale.rb +8 -0
  29. data/lib/i18n/locale/fallbacks.rb +96 -0
  30. data/lib/i18n/locale/tag.rb +28 -0
  31. data/lib/i18n/locale/tag/parents.rb +22 -0
  32. data/lib/i18n/locale/tag/rfc4646.rb +74 -0
  33. data/lib/i18n/locale/tag/simple.rb +39 -0
  34. data/lib/i18n/middleware.rb +17 -0
  35. data/lib/i18n/tests.rb +14 -0
  36. data/lib/i18n/tests/basics.rb +60 -0
  37. data/lib/i18n/tests/defaults.rb +52 -0
  38. data/lib/i18n/tests/interpolation.rb +159 -0
  39. data/lib/i18n/tests/link.rb +56 -0
  40. data/lib/i18n/tests/localization.rb +19 -0
  41. data/lib/i18n/tests/localization/date.rb +117 -0
  42. data/lib/i18n/tests/localization/date_time.rb +103 -0
  43. data/lib/i18n/tests/localization/procs.rb +116 -0
  44. data/lib/i18n/tests/localization/time.rb +103 -0
  45. data/lib/i18n/tests/lookup.rb +81 -0
  46. data/lib/i18n/tests/pluralization.rb +35 -0
  47. data/lib/i18n/tests/procs.rb +55 -0
  48. data/lib/i18n/version.rb +5 -0
  49. metadata +124 -0
@@ -0,0 +1,159 @@
1
+ # encoding: utf-8
2
+
3
+ module I18n
4
+ module Tests
5
+ module Interpolation
6
+ # If no interpolation parameter is not given, I18n should not alter the string.
7
+ # This behavior is due to three reasons:
8
+ #
9
+ # * Checking interpolation keys in all strings hits performance, badly;
10
+ #
11
+ # * This allows us to retrieve untouched values through I18n. For example
12
+ # I could have a middleware that returns I18n lookup results in JSON
13
+ # to be processed through Javascript. Leaving the keys untouched allows
14
+ # the interpolation to happen at the javascript level;
15
+ #
16
+ # * Security concerns: if I allow users to translate a web site, they can
17
+ # insert %{} in messages causing the I18n lookup to fail in every request.
18
+ #
19
+ test "interpolation: given no values it does not alter the string" do
20
+ assert_equal 'Hi %{name}!', interpolate(:default => 'Hi %{name}!')
21
+ end
22
+
23
+ test "interpolation: given values it interpolates them into the string" do
24
+ assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => 'David')
25
+ end
26
+
27
+ test "interpolation: given a nil value it still interpolates it into the string" do
28
+ assert_equal 'Hi !', interpolate(:default => 'Hi %{name}!', :name => nil)
29
+ end
30
+
31
+ test "interpolation: given a lambda as a value it calls it if the string contains the key" do
32
+ assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => lambda { |*args| 'David' })
33
+ end
34
+
35
+ test "interpolation: given a lambda as a value it does not call it if the string does not contain the key" do
36
+ assert_nothing_raised { interpolate(:default => 'Hi!', :name => lambda { |*args| raise 'fail' }) }
37
+ end
38
+
39
+ test "interpolation: given values but missing a key it raises I18n::MissingInterpolationArgument" do
40
+ assert_raise(I18n::MissingInterpolationArgument) do
41
+ interpolate(:default => '%{foo}', :bar => 'bar')
42
+ end
43
+ end
44
+
45
+ test "interpolation: it does not raise I18n::MissingInterpolationArgument for escaped variables" do
46
+ assert_nothing_raised do
47
+ assert_equal 'Barr %{foo}', interpolate(:default => '%{bar} %%{foo}', :bar => 'Barr')
48
+ end
49
+ end
50
+
51
+ test "interpolation: it does not change the original, stored translation string" do
52
+ I18n.backend.store_translations(:en, :interpolate => 'Hi %{name}!')
53
+ assert_equal 'Hi David!', interpolate(:interpolate, :name => 'David')
54
+ assert_equal 'Hi Yehuda!', interpolate(:interpolate, :name => 'Yehuda')
55
+ end
56
+
57
+ test "interpolation: given an array interpolates each element" do
58
+ I18n.backend.store_translations(:en, :array_interpolate => ['Hi', 'Mr. %{name}', 'or sir %{name}'])
59
+ assert_equal ['Hi', 'Mr. Bartuz', 'or sir Bartuz'], interpolate(:array_interpolate, :name => 'Bartuz')
60
+ end
61
+
62
+ test "interpolation: given the translation is in utf-8 it still works" do
63
+ assert_equal 'Häi David!', interpolate(:default => 'Häi %{name}!', :name => 'David')
64
+ end
65
+
66
+ test "interpolation: given the value is in utf-8 it still works" do
67
+ assert_equal 'Hi ゆきひろ!', interpolate(:default => 'Hi %{name}!', :name => 'ゆきひろ')
68
+ end
69
+
70
+ test "interpolation: given the translation and the value are in utf-8 it still works" do
71
+ assert_equal 'こんにちは、ゆきひろさん!', interpolate(:default => 'こんにちは、%{name}さん!', :name => 'ゆきひろ')
72
+ end
73
+
74
+ if Object.const_defined?(:Encoding)
75
+ test "interpolation: given a euc-jp translation and a utf-8 value it raises Encoding::CompatibilityError" do
76
+ assert_raise(Encoding::CompatibilityError) do
77
+ interpolate(:default => euc_jp('こんにちは、%{name}さん!'), :name => 'ゆきひろ')
78
+ end
79
+ end
80
+
81
+ test "interpolation: given a utf-8 translation and a euc-jp value it raises Encoding::CompatibilityError" do
82
+ assert_raise(Encoding::CompatibilityError) do
83
+ interpolate(:default => 'こんにちは、%{name}さん!', :name => euc_jp('ゆきひろ'))
84
+ end
85
+ end
86
+
87
+ test "interpolation: ASCII strings in the backend should be encoded to UTF8 if interpolation options are in UTF8" do
88
+ I18n.backend.store_translations 'en', 'encoding' => ('%{who} let me go'.force_encoding("ASCII"))
89
+ result = I18n.t 'encoding', :who => "måmmå miå"
90
+ assert_equal Encoding::UTF_8, result.encoding
91
+ end
92
+
93
+ test "interpolation: UTF8 strings in the backend are still returned as UTF8 with ASCII interpolation" do
94
+ I18n.backend.store_translations 'en', 'encoding' => 'måmmå miå %{what}'
95
+ result = I18n.t 'encoding', :what => 'let me go'.force_encoding("ASCII")
96
+ assert_equal Encoding::UTF_8, result.encoding
97
+ end
98
+
99
+ test "interpolation: UTF8 strings in the backend are still returned as UTF8 even with numbers interpolation" do
100
+ I18n.backend.store_translations 'en', 'encoding' => '%{count} times: måmmå miå'
101
+ result = I18n.t 'encoding', :count => 3
102
+ assert_equal Encoding::UTF_8, result.encoding
103
+ end
104
+ end
105
+
106
+ test "interpolation: given a translations containing a reserved key it raises I18n::ReservedInterpolationKey" do
107
+ assert_raise(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{exception_handler}') }
108
+ assert_raise(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{default}') }
109
+ assert_raise(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{separator}') }
110
+ assert_raise(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{scope}') }
111
+ end
112
+
113
+ test "interpolation: deep interpolation for default string" do
114
+ assert_equal 'Hi %{name}!', interpolate(:default => 'Hi %{name}!', :deep_interpolation => true)
115
+ end
116
+
117
+ test "interpolation: deep interpolation for interpolated string" do
118
+ assert_equal 'Hi Ann!', interpolate(:default => 'Hi %{name}!', :name => 'Ann', :deep_interpolation => true)
119
+ end
120
+
121
+ test "interpolation: deep interpolation for Hash" do
122
+ people = { :people => { :ann => 'Ann is %{ann}', :john => 'John is %{john}' } }
123
+ interpolated_people = { :people => { :ann => 'Ann is good', :john => 'John is big' } }
124
+ assert_equal interpolated_people, interpolate(:default => people, :ann => 'good', :john => 'big', :deep_interpolation => true)
125
+ end
126
+
127
+ test "interpolation: deep interpolation for Array" do
128
+ people = { :people => ['Ann is %{ann}', 'John is %{john}'] }
129
+ interpolated_people = { :people => ['Ann is good', 'John is big'] }
130
+ assert_equal interpolated_people, interpolate(:default => people, :ann => 'good', :john => 'big', :deep_interpolation => true)
131
+ end
132
+
133
+ protected
134
+
135
+ def capture(stream)
136
+ begin
137
+ stream = stream.to_s
138
+ eval "$#{stream} = StringIO.new"
139
+ yield
140
+ result = eval("$#{stream}").string
141
+ ensure
142
+ eval("$#{stream} = #{stream.upcase}")
143
+ end
144
+
145
+ result
146
+ end
147
+
148
+ def euc_jp(string)
149
+ string.encode!(Encoding::EUC_JP)
150
+ end
151
+
152
+ def interpolate(*args)
153
+ options = args.last.is_a?(Hash) ? args.pop : {}
154
+ key = args.pop
155
+ I18n.backend.translate('en', key, options)
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+
3
+ module I18n
4
+ module Tests
5
+ module Link
6
+ test "linked lookup: if a key resolves to a symbol it looks up the symbol" do
7
+ I18n.backend.store_translations 'en', {
8
+ :link => :linked,
9
+ :linked => 'linked'
10
+ }
11
+ assert_equal 'linked', I18n.backend.translate('en', :link)
12
+ end
13
+
14
+ test "linked lookup: if a key resolves to a dot-separated symbol it looks up the symbol" do
15
+ I18n.backend.store_translations 'en', {
16
+ :link => :"foo.linked",
17
+ :foo => { :linked => 'linked' }
18
+ }
19
+ assert_equal('linked', I18n.backend.translate('en', :link))
20
+ end
21
+
22
+ test "linked lookup: if a dot-separated key resolves to a symbol it looks up the symbol" do
23
+ I18n.backend.store_translations 'en', {
24
+ :foo => { :link => :linked },
25
+ :linked => 'linked'
26
+ }
27
+ assert_equal('linked', I18n.backend.translate('en', :'foo.link'))
28
+ end
29
+
30
+ test "linked lookup: if a dot-separated key resolves to a dot-separated symbol it looks up the symbol" do
31
+ I18n.backend.store_translations 'en', {
32
+ :foo => { :link => :"bar.linked" },
33
+ :bar => { :linked => 'linked' }
34
+ }
35
+ assert_equal('linked', I18n.backend.translate('en', :'foo.link'))
36
+ end
37
+
38
+ test "linked lookup: links always refer to the absolute key" do
39
+ I18n.backend.store_translations 'en', {
40
+ :foo => { :link => :linked, :linked => 'linked in foo' },
41
+ :linked => 'linked absolutely'
42
+ }
43
+ assert_equal 'linked absolutely', I18n.backend.translate('en', :link, :scope => :foo)
44
+ end
45
+
46
+ test "linked lookup: a link can resolve to a namespace in the middle of a dot-separated key" do
47
+ I18n.backend.store_translations 'en', {
48
+ :activemodel => { :errors => { :messages => { :blank => "can't be blank" } } },
49
+ :activerecord => { :errors => { :messages => :"activemodel.errors.messages" } }
50
+ }
51
+ assert_equal "can't be blank", I18n.t(:"activerecord.errors.messages.blank")
52
+ assert_equal "can't be blank", I18n.t(:"activerecord.errors.messages.blank")
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,19 @@
1
+ module I18n
2
+ module Tests
3
+ module Localization
4
+ autoload :Date, 'i18n/tests/localization/date'
5
+ autoload :DateTime, 'i18n/tests/localization/date_time'
6
+ autoload :Time, 'i18n/tests/localization/time'
7
+ autoload :Procs, 'i18n/tests/localization/procs'
8
+
9
+ def self.included(base)
10
+ base.class_eval do
11
+ include I18n::Tests::Localization::Date
12
+ include I18n::Tests::Localization::DateTime
13
+ include I18n::Tests::Localization::Procs
14
+ include I18n::Tests::Localization::Time
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,117 @@
1
+ # encoding: utf-8
2
+
3
+ module I18n
4
+ module Tests
5
+ module Localization
6
+ module Date
7
+ def setup
8
+ super
9
+ setup_date_translations
10
+ @date = ::Date.new(2008, 3, 1)
11
+ end
12
+
13
+ test "localize Date: given the short format it uses it" do
14
+ assert_equal '01. Mär', I18n.l(@date, :format => :short, :locale => :de)
15
+ end
16
+
17
+ test "localize Date: given the long format it uses it" do
18
+ assert_equal '01. März 2008', I18n.l(@date, :format => :long, :locale => :de)
19
+ end
20
+
21
+ test "localize Date: given the default format it uses it" do
22
+ assert_equal '01.03.2008', I18n.l(@date, :format => :default, :locale => :de)
23
+ end
24
+
25
+ test "localize Date: given a day name format it returns the correct day name" do
26
+ assert_equal 'Samstag', I18n.l(@date, :format => '%A', :locale => :de)
27
+ end
28
+
29
+ test "localize Date: given a uppercased day name format it returns the correct day name in upcase" do
30
+ assert_equal 'samstag'.upcase, I18n.l(@date, :format => '%^A', :locale => :de)
31
+ end
32
+
33
+ test "localize Date: given an abbreviated day name format it returns the correct abbreviated day name" do
34
+ assert_equal 'Sa', I18n.l(@date, :format => '%a', :locale => :de)
35
+ end
36
+
37
+ test "localize Date: given an abbreviated and uppercased day name format it returns the correct abbreviated day name in upcase" do
38
+ assert_equal 'sa'.upcase, I18n.l(@date, :format => '%^a', :locale => :de)
39
+ end
40
+
41
+ test "localize Date: given a month name format it returns the correct month name" do
42
+ assert_equal 'März', I18n.l(@date, :format => '%B', :locale => :de)
43
+ end
44
+
45
+ test "localize Date: given a uppercased month name format it returns the correct month name in upcase" do
46
+ assert_equal 'märz'.upcase, I18n.l(@date, :format => '%^B', :locale => :de)
47
+ end
48
+
49
+ test "localize Date: given an abbreviated month name format it returns the correct abbreviated month name" do
50
+ assert_equal 'Mär', I18n.l(@date, :format => '%b', :locale => :de)
51
+ end
52
+
53
+ test "localize Date: given an abbreviated and uppercased month name format it returns the correct abbreviated month name in upcase" do
54
+ assert_equal 'mär'.upcase, I18n.l(@date, :format => '%^b', :locale => :de)
55
+ end
56
+
57
+ test "localize Date: given a date format with the month name upcased it returns the correct value" do
58
+ assert_equal '1. FEBRUAR 2008', I18n.l(::Date.new(2008, 2, 1), :format => "%-d. %^B %Y", :locale => :de)
59
+ end
60
+
61
+ test "localize Date: given missing translations it returns the correct error message" do
62
+ assert_equal 'translation missing: fr.date.abbr_month_names', I18n.l(@date, :format => '%b', :locale => :fr)
63
+ end
64
+
65
+ test "localize Date: given an unknown format it does not fail" do
66
+ assert_nothing_raised { I18n.l(@date, :format => '%x') }
67
+ end
68
+
69
+ test "localize Date: does not modify the options hash" do
70
+ options = { :format => '%b', :locale => :de }
71
+ assert_equal 'Mär', I18n.l(@date, options)
72
+ assert_equal({ :format => '%b', :locale => :de }, options)
73
+ assert_nothing_raised { I18n.l(@date, options.freeze) }
74
+ end
75
+
76
+ test "localize Date: given nil with default value it returns default" do
77
+ assert_equal 'default', I18n.l(nil, :default => 'default')
78
+ end
79
+
80
+ test "localize Date: given nil it raises I18n::ArgumentError" do
81
+ assert_raise(I18n::ArgumentError) { I18n.l(nil) }
82
+ end
83
+
84
+ test "localize Date: given a plain Object it raises I18n::ArgumentError" do
85
+ assert_raise(I18n::ArgumentError) { I18n.l(Object.new) }
86
+ end
87
+
88
+ test "localize Date: given a format is missing it raises I18n::MissingTranslationData" do
89
+ assert_raise(I18n::MissingTranslationData) { I18n.l(@date, :format => :missing) }
90
+ end
91
+
92
+ test "localize Date: it does not alter the format string" do
93
+ assert_equal '01. Februar 2009', I18n.l(::Date.parse('2009-02-01'), :format => :long, :locale => :de)
94
+ assert_equal '01. Oktober 2009', I18n.l(::Date.parse('2009-10-01'), :format => :long, :locale => :de)
95
+ end
96
+
97
+ protected
98
+
99
+ def setup_date_translations
100
+ I18n.backend.store_translations :de, {
101
+ :date => {
102
+ :formats => {
103
+ :default => "%d.%m.%Y",
104
+ :short => "%d. %b",
105
+ :long => "%d. %B %Y",
106
+ },
107
+ :day_names => %w(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag),
108
+ :abbr_day_names => %w(So Mo Di Mi Do Fr Sa),
109
+ :month_names => %w(Januar Februar März April Mai Juni Juli August September Oktober November Dezember).unshift(nil),
110
+ :abbr_month_names => %w(Jan Feb Mär Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil)
111
+ }
112
+ }
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,103 @@
1
+ # encoding: utf-8
2
+
3
+ module I18n
4
+ module Tests
5
+ module Localization
6
+ module DateTime
7
+ def setup
8
+ super
9
+ setup_datetime_translations
10
+ @datetime = ::DateTime.new(2008, 3, 1, 6)
11
+ @other_datetime = ::DateTime.new(2008, 3, 1, 18)
12
+ end
13
+
14
+ test "localize DateTime: given the short format it uses it" do
15
+ assert_equal '01. Mär 06:00', I18n.l(@datetime, :format => :short, :locale => :de)
16
+ end
17
+
18
+ test "localize DateTime: given the long format it uses it" do
19
+ assert_equal '01. März 2008 06:00', I18n.l(@datetime, :format => :long, :locale => :de)
20
+ end
21
+
22
+ test "localize DateTime: given the default format it uses it" do
23
+ assert_equal 'Sa, 01. Mär 2008 06:00:00 +0000', I18n.l(@datetime, :format => :default, :locale => :de)
24
+ end
25
+
26
+ test "localize DateTime: given a day name format it returns the correct day name" do
27
+ assert_equal 'Samstag', I18n.l(@datetime, :format => '%A', :locale => :de)
28
+ end
29
+
30
+ test "localize DateTime: given a uppercased day name format it returns the correct day name in upcase" do
31
+ assert_equal 'samstag'.upcase, I18n.l(@datetime, :format => '%^A', :locale => :de)
32
+ end
33
+
34
+ test "localize DateTime: given an abbreviated day name format it returns the correct abbreviated day name" do
35
+ assert_equal 'Sa', I18n.l(@datetime, :format => '%a', :locale => :de)
36
+ end
37
+
38
+ test "localize DateTime: given an abbreviated and uppercased day name format it returns the correct abbreviated day name in upcase" do
39
+ assert_equal 'sa'.upcase, I18n.l(@datetime, :format => '%^a', :locale => :de)
40
+ end
41
+
42
+ test "localize DateTime: given a month name format it returns the correct month name" do
43
+ assert_equal 'März', I18n.l(@datetime, :format => '%B', :locale => :de)
44
+ end
45
+
46
+ test "localize DateTime: given a uppercased month name format it returns the correct month name in upcase" do
47
+ assert_equal 'märz'.upcase, I18n.l(@datetime, :format => '%^B', :locale => :de)
48
+ end
49
+
50
+ test "localize DateTime: given an abbreviated month name format it returns the correct abbreviated month name" do
51
+ assert_equal 'Mär', I18n.l(@datetime, :format => '%b', :locale => :de)
52
+ end
53
+
54
+ test "localize DateTime: given an abbreviated and uppercased month name format it returns the correct abbreviated month name in upcase" do
55
+ assert_equal 'mär'.upcase, I18n.l(@datetime, :format => '%^b', :locale => :de)
56
+ end
57
+
58
+ test "localize DateTime: given a date format with the month name upcased it returns the correct value" do
59
+ assert_equal '1. FEBRUAR 2008', I18n.l(::DateTime.new(2008, 2, 1, 6), :format => "%-d. %^B %Y", :locale => :de)
60
+ end
61
+
62
+ test "localize DateTime: given missing translations it returns the correct error message" do
63
+ assert_equal 'translation missing: fr.date.abbr_month_names', I18n.l(@datetime, :format => '%b', :locale => :fr)
64
+ end
65
+
66
+ test "localize DateTime: given a meridian indicator format it returns the correct meridian indicator" do
67
+ assert_equal 'AM', I18n.l(@datetime, :format => '%p', :locale => :de)
68
+ assert_equal 'PM', I18n.l(@other_datetime, :format => '%p', :locale => :de)
69
+ end
70
+
71
+ test "localize DateTime: given a meridian indicator format it returns the correct meridian indicator in downcase" do
72
+ assert_equal 'am', I18n.l(@datetime, :format => '%P', :locale => :de)
73
+ assert_equal 'pm', I18n.l(@other_datetime, :format => '%P', :locale => :de)
74
+ end
75
+
76
+ test "localize DateTime: given an unknown format it does not fail" do
77
+ assert_nothing_raised { I18n.l(@datetime, :format => '%x') }
78
+ end
79
+
80
+ test "localize DateTime: given a format is missing it raises I18n::MissingTranslationData" do
81
+ assert_raise(I18n::MissingTranslationData) { I18n.l(@datetime, :format => :missing) }
82
+ end
83
+
84
+ protected
85
+
86
+ def setup_datetime_translations
87
+ # time translations might have been set up in Tests::Api::Localization::Time
88
+ I18n.backend.store_translations :de, {
89
+ :time => {
90
+ :formats => {
91
+ :default => "%a, %d. %b %Y %H:%M:%S %z",
92
+ :short => "%d. %b %H:%M",
93
+ :long => "%d. %B %Y %H:%M"
94
+ },
95
+ :am => 'am',
96
+ :pm => 'pm'
97
+ }
98
+ }
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end