rubysl-date 0.0.1 → 1.0.1

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 (167) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +0 -1
  3. data/.travis.yml +7 -0
  4. data/README.md +2 -2
  5. data/Rakefile +0 -1
  6. data/lib/date.rb +1 -0
  7. data/lib/date/format.rb +1207 -0
  8. data/lib/rubysl/date.rb +2 -0
  9. data/lib/rubysl/date/date.rb +1765 -0
  10. data/lib/{rubysl-date → rubysl/date}/version.rb +1 -1
  11. data/rubysl-date.gemspec +18 -18
  12. data/spec/date/accessor_spec.rb +90 -0
  13. data/spec/date/add_month_spec.rb +29 -0
  14. data/spec/date/add_spec.rb +29 -0
  15. data/spec/date/ajd_spec.rb +5 -0
  16. data/spec/date/ajd_to_amjd_spec.rb +5 -0
  17. data/spec/date/ajd_to_jd_spec.rb +5 -0
  18. data/spec/date/amjd_spec.rb +5 -0
  19. data/spec/date/amjd_to_ajd_spec.rb +5 -0
  20. data/spec/date/append_spec.rb +5 -0
  21. data/spec/date/asctime_spec.rb +5 -0
  22. data/spec/date/boat_spec.rb +23 -0
  23. data/spec/date/case_compare_spec.rb +5 -0
  24. data/spec/date/civil_spec.rb +11 -0
  25. data/spec/date/civil_to_jd_spec.rb +16 -0
  26. data/spec/date/commercial_spec.rb +17 -0
  27. data/spec/date/commercial_to_jd_spec.rb +5 -0
  28. data/spec/date/comparison_spec.rb +5 -0
  29. data/spec/date/constants_spec.rb +110 -0
  30. data/spec/date/conversions_spec.rb +154 -0
  31. data/spec/date/ctime_spec.rb +5 -0
  32. data/spec/date/cwday_spec.rb +5 -0
  33. data/spec/date/cweek_spec.rb +5 -0
  34. data/spec/date/cwyear_spec.rb +5 -0
  35. data/spec/date/day_fraction_spec.rb +5 -0
  36. data/spec/date/day_fraction_to_time_spec.rb +5 -0
  37. data/spec/date/day_spec.rb +5 -0
  38. data/spec/date/downto_spec.rb +17 -0
  39. data/spec/date/england_spec.rb +5 -0
  40. data/spec/date/eql_spec.rb +11 -0
  41. data/spec/date/exist1_spec.rb +8 -0
  42. data/spec/date/exist2_spec.rb +8 -0
  43. data/spec/date/exist3_spec.rb +8 -0
  44. data/spec/date/exist_spec.rb +8 -0
  45. data/spec/date/existw_spec.rb +8 -0
  46. data/spec/date/format/bag/method_missing_spec.rb +5 -0
  47. data/spec/date/format/bag/to_hash_spec.rb +5 -0
  48. data/spec/date/gregorian_leap_spec.rb +15 -0
  49. data/spec/date/gregorian_spec.rb +46 -0
  50. data/spec/date/hash_spec.rb +7 -0
  51. data/spec/date/infinity/abs_spec.rb +5 -0
  52. data/spec/date/infinity/coerce_spec.rb +5 -0
  53. data/spec/date/infinity/comparison_spec.rb +5 -0
  54. data/spec/date/infinity/d_spec.rb +5 -0
  55. data/spec/date/infinity/finite_spec.rb +5 -0
  56. data/spec/date/infinity/infinite_spec.rb +5 -0
  57. data/spec/date/infinity/nan_spec.rb +5 -0
  58. data/spec/date/infinity/uminus_spec.rb +5 -0
  59. data/spec/date/infinity/uplus_spec.rb +5 -0
  60. data/spec/date/infinity/zero_spec.rb +5 -0
  61. data/spec/date/infinity_spec.rb +76 -0
  62. data/spec/date/inspect_spec.rb +5 -0
  63. data/spec/date/italy_spec.rb +5 -0
  64. data/spec/date/jd_spec.rb +14 -0
  65. data/spec/date/jd_to_ajd_spec.rb +5 -0
  66. data/spec/date/jd_to_civil_spec.rb +5 -0
  67. data/spec/date/jd_to_commercial_spec.rb +5 -0
  68. data/spec/date/jd_to_ld_spec.rb +5 -0
  69. data/spec/date/jd_to_mjd_spec.rb +5 -0
  70. data/spec/date/jd_to_ordinal_spec.rb +5 -0
  71. data/spec/date/jd_to_wday_spec.rb +5 -0
  72. data/spec/date/julian_leap_spec.rb +14 -0
  73. data/spec/date/julian_spec.rb +47 -0
  74. data/spec/date/ld_spec.rb +5 -0
  75. data/spec/date/ld_to_jd_spec.rb +5 -0
  76. data/spec/date/leap_spec.rb +9 -0
  77. data/spec/date/mday_spec.rb +5 -0
  78. data/spec/date/minus_month_spec.rb +22 -0
  79. data/spec/date/minus_spec.rb +29 -0
  80. data/spec/date/mjd_spec.rb +5 -0
  81. data/spec/date/mjd_to_jd_spec.rb +5 -0
  82. data/spec/date/mon_spec.rb +5 -0
  83. data/spec/date/month_spec.rb +5 -0
  84. data/spec/date/new0_spec.rb +8 -0
  85. data/spec/date/new1_spec.rb +8 -0
  86. data/spec/date/new2_spec.rb +8 -0
  87. data/spec/date/new3_spec.rb +8 -0
  88. data/spec/date/new_spec.rb +13 -0
  89. data/spec/date/new_start_spec.rb +5 -0
  90. data/spec/date/newsg_spec.rb +7 -0
  91. data/spec/date/neww_spec.rb +7 -0
  92. data/spec/date/next_spec.rb +5 -0
  93. data/spec/date/ns_spec.rb +11 -0
  94. data/spec/date/ordinal_spec.rb +7 -0
  95. data/spec/date/ordinal_to_jd_spec.rb +5 -0
  96. data/spec/date/os_spec.rb +11 -0
  97. data/spec/date/parse_spec.rb +173 -0
  98. data/spec/date/plus_spec.rb +19 -0
  99. data/spec/date/relationship_spec.rb +19 -0
  100. data/spec/date/right_shift_spec.rb +5 -0
  101. data/spec/date/sg_spec.rb +7 -0
  102. data/spec/date/shared/civil.rb +69 -0
  103. data/spec/date/shared/commercial.rb +62 -0
  104. data/spec/date/shared/jd.rb +14 -0
  105. data/spec/date/shared/new_bang.rb +14 -0
  106. data/spec/date/shared/ordinal.rb +42 -0
  107. data/spec/date/shared/parse.rb +54 -0
  108. data/spec/date/shared/parse_eu.rb +48 -0
  109. data/spec/date/shared/parse_us.rb +61 -0
  110. data/spec/date/shared/valid_civil.rb +69 -0
  111. data/spec/date/shared/valid_commercial.rb +66 -0
  112. data/spec/date/shared/valid_jd.rb +36 -0
  113. data/spec/date/shared/valid_ordinal.rb +60 -0
  114. data/spec/date/start_spec.rb +5 -0
  115. data/spec/date/step_spec.rb +55 -0
  116. data/spec/date/strftime_spec.rb +204 -0
  117. data/spec/date/strptime_spec.rb +161 -0
  118. data/spec/date/succ_spec.rb +5 -0
  119. data/spec/date/time_to_day_fraction_spec.rb +5 -0
  120. data/spec/date/to_s_spec.rb +5 -0
  121. data/spec/date/today_spec.rb +5 -0
  122. data/spec/date/upto_spec.rb +15 -0
  123. data/spec/date/valid_civil_spec.rb +9 -0
  124. data/spec/date/valid_commercial_spec.rb +9 -0
  125. data/spec/date/valid_date_spec.rb +6 -0
  126. data/spec/date/valid_jd_spec.rb +9 -0
  127. data/spec/date/valid_ordinal_spec.rb +9 -0
  128. data/spec/date/valid_time_spec.rb +5 -0
  129. data/spec/date/wday_spec.rb +5 -0
  130. data/spec/date/yday_spec.rb +5 -0
  131. data/spec/date/year_spec.rb +5 -0
  132. data/spec/date/zone_to_diff_spec.rb +5 -0
  133. data/spec/datetime/_strptime_spec.rb +5 -0
  134. data/spec/datetime/civil_spec.rb +5 -0
  135. data/spec/datetime/commercial_spec.rb +5 -0
  136. data/spec/datetime/hour_spec.rb +77 -0
  137. data/spec/datetime/httpdate_spec.rb +5 -0
  138. data/spec/datetime/iso8601_spec.rb +9 -0
  139. data/spec/datetime/jd_spec.rb +5 -0
  140. data/spec/datetime/jisx0301_spec.rb +9 -0
  141. data/spec/datetime/min_spec.rb +5 -0
  142. data/spec/datetime/minute_spec.rb +7 -0
  143. data/spec/datetime/new_offset_spec.rb +5 -0
  144. data/spec/datetime/new_spec.rb +52 -0
  145. data/spec/datetime/now_spec.rb +7 -0
  146. data/spec/datetime/offset_spec.rb +5 -0
  147. data/spec/datetime/ordinal_spec.rb +5 -0
  148. data/spec/datetime/parse_spec.rb +166 -0
  149. data/spec/datetime/rfc2822_spec.rb +5 -0
  150. data/spec/datetime/rfc3339_spec.rb +9 -0
  151. data/spec/datetime/rfc822_spec.rb +5 -0
  152. data/spec/datetime/sec_fraction_spec.rb +5 -0
  153. data/spec/datetime/sec_spec.rb +5 -0
  154. data/spec/datetime/second_fraction_spec.rb +5 -0
  155. data/spec/datetime/second_spec.rb +7 -0
  156. data/spec/datetime/shared/min.rb +77 -0
  157. data/spec/datetime/shared/sec.rb +65 -0
  158. data/spec/datetime/strftime_spec.rb +25 -0
  159. data/spec/datetime/strptime_spec.rb +5 -0
  160. data/spec/datetime/to_date_spec.rb +5 -0
  161. data/spec/datetime/to_datetime_spec.rb +5 -0
  162. data/spec/datetime/to_s_spec.rb +5 -0
  163. data/spec/datetime/to_time_spec.rb +5 -0
  164. data/spec/datetime/xmlschema_spec.rb +9 -0
  165. data/spec/datetime/zone_spec.rb +5 -0
  166. metadata +376 -88
  167. data/lib/rubysl-date.rb +0 -7
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2a79e200c26dce696d67d54ceee32ca7ea7926e3
4
+ data.tar.gz: d909437349a82b70bc3c1e98701636f19e4d1bd6
5
+ SHA512:
6
+ metadata.gz: 3ae6ba9b9a16f3b949ba2246b5157789e8ff18dc1e9d874f9908e668336ce3dae50c2564e42f463dd7bf08ef9192859bab848f775bd5a750cd0f31aa9abecf32
7
+ data.tar.gz: ee53807380e45124a257b51fe61f257d1d93956b343acc65d0465dc4df7dbf3557ecf7b7f2030d567c915e1165c4a70457c85431c2f889d25f1806145fb6003e
data/.gitignore CHANGED
@@ -15,4 +15,3 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
- .rbx
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ env:
3
+ - RUBYLIB=lib
4
+ script: bundle exec mspec
5
+ rvm:
6
+ - 1.8.7
7
+ - rbx-nightly-18mode
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # RubySL::Date
1
+ # Rubysl::Date
2
2
 
3
3
  TODO: Write a gem description
4
4
 
@@ -24,6 +24,6 @@ TODO: Write usage instructions here
24
24
 
25
25
  1. Fork it
26
26
  2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Added some feature'`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
28
  4. Push to the branch (`git push origin my-new-feature`)
29
29
  5. Create new Pull Request
data/Rakefile CHANGED
@@ -1,2 +1 @@
1
- #!/usr/bin/env rake
2
1
  require "bundler/gem_tasks"
@@ -0,0 +1 @@
1
+ require "rubysl/date"
@@ -0,0 +1,1207 @@
1
+ # format.rb: Written by Tadayoshi Funaba 1999-2008
2
+ # $Id: format.rb,v 2.43 2008-01-17 20:16:31+09 tadf Exp $
3
+
4
+ require 'rational'
5
+
6
+ class Date
7
+
8
+ module Format # :nodoc:
9
+
10
+ MONTHS = {
11
+ 'january' => 1, 'february' => 2, 'march' => 3, 'april' => 4,
12
+ 'may' => 5, 'june' => 6, 'july' => 7, 'august' => 8,
13
+ 'september'=> 9, 'october' =>10, 'november' =>11, 'december' =>12
14
+ }
15
+
16
+ DAYS = {
17
+ 'sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday'=> 3,
18
+ 'thursday' => 4, 'friday' => 5, 'saturday' => 6
19
+ }
20
+
21
+ ABBR_MONTHS = {
22
+ 'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4,
23
+ 'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8,
24
+ 'sep' => 9, 'oct' =>10, 'nov' =>11, 'dec' =>12
25
+ }
26
+
27
+ ABBR_DAYS = {
28
+ 'sun' => 0, 'mon' => 1, 'tue' => 2, 'wed' => 3,
29
+ 'thu' => 4, 'fri' => 5, 'sat' => 6
30
+ }
31
+
32
+ ZONES = {
33
+ 'ut' => 0*3600, 'gmt' => 0*3600, 'est' => -5*3600, 'edt' => -4*3600,
34
+ 'cst' => -6*3600, 'cdt' => -5*3600, 'mst' => -7*3600, 'mdt' => -6*3600,
35
+ 'pst' => -8*3600, 'pdt' => -7*3600,
36
+ 'a' => 1*3600, 'b' => 2*3600, 'c' => 3*3600, 'd' => 4*3600,
37
+ 'e' => 5*3600, 'f' => 6*3600, 'g' => 7*3600, 'h' => 8*3600,
38
+ 'i' => 9*3600, 'k' => 10*3600, 'l' => 11*3600, 'm' => 12*3600,
39
+ 'n' => -1*3600, 'o' => -2*3600, 'p' => -3*3600, 'q' => -4*3600,
40
+ 'r' => -5*3600, 's' => -6*3600, 't' => -7*3600, 'u' => -8*3600,
41
+ 'v' => -9*3600, 'w' =>-10*3600, 'x' =>-11*3600, 'y' =>-12*3600,
42
+ 'z' => 0*3600,
43
+
44
+ 'utc' => 0*3600, 'wet' => 0*3600,
45
+ 'at' => -2*3600, 'brst'=> -2*3600, 'ndt' => -(2*3600+1800),
46
+ 'art' => -3*3600, 'adt' => -3*3600, 'brt' => -3*3600, 'clst'=> -3*3600,
47
+ 'nst' => -(3*3600+1800),
48
+ 'ast' => -4*3600, 'clt' => -4*3600,
49
+ 'akdt'=> -8*3600, 'ydt' => -8*3600,
50
+ 'akst'=> -9*3600, 'hadt'=> -9*3600, 'hdt' => -9*3600, 'yst' => -9*3600,
51
+ 'ahst'=>-10*3600, 'cat' =>-10*3600, 'hast'=>-10*3600, 'hst' =>-10*3600,
52
+ 'nt' =>-11*3600,
53
+ 'idlw'=>-12*3600,
54
+ 'bst' => 1*3600, 'cet' => 1*3600, 'fwt' => 1*3600, 'met' => 1*3600,
55
+ 'mewt'=> 1*3600, 'mez' => 1*3600, 'swt' => 1*3600, 'wat' => 1*3600,
56
+ 'west'=> 1*3600,
57
+ 'cest'=> 2*3600, 'eet' => 2*3600, 'fst' => 2*3600, 'mest'=> 2*3600,
58
+ 'mesz'=> 2*3600, 'sast'=> 2*3600, 'sst' => 2*3600,
59
+ 'bt' => 3*3600, 'eat' => 3*3600, 'eest'=> 3*3600, 'msk' => 3*3600,
60
+ 'msd' => 4*3600, 'zp4' => 4*3600,
61
+ 'zp5' => 5*3600, 'ist' => (5*3600+1800),
62
+ 'zp6' => 6*3600,
63
+ 'wast'=> 7*3600,
64
+ 'cct' => 8*3600, 'sgt' => 8*3600, 'wadt'=> 8*3600,
65
+ 'jst' => 9*3600, 'kst' => 9*3600,
66
+ 'east'=> 10*3600, 'gst' => 10*3600,
67
+ 'eadt'=> 11*3600,
68
+ 'idle'=> 12*3600, 'nzst'=> 12*3600, 'nzt' => 12*3600,
69
+ 'nzdt'=> 13*3600,
70
+
71
+ 'afghanistan' => 16200, 'alaskan' => -32400,
72
+ 'arab' => 10800, 'arabian' => 14400,
73
+ 'arabic' => 10800, 'atlantic' => -14400,
74
+ 'aus central' => 34200, 'aus eastern' => 36000,
75
+ 'azores' => -3600, 'canada central' => -21600,
76
+ 'cape verde' => -3600, 'caucasus' => 14400,
77
+ 'cen. australia' => 34200, 'central america' => -21600,
78
+ 'central asia' => 21600, 'central europe' => 3600,
79
+ 'central european' => 3600, 'central pacific' => 39600,
80
+ 'central' => -21600, 'china' => 28800,
81
+ 'dateline' => -43200, 'e. africa' => 10800,
82
+ 'e. australia' => 36000, 'e. europe' => 7200,
83
+ 'e. south america' => -10800, 'eastern' => -18000,
84
+ 'egypt' => 7200, 'ekaterinburg' => 18000,
85
+ 'fiji' => 43200, 'fle' => 7200,
86
+ 'greenland' => -10800, 'greenwich' => 0,
87
+ 'gtb' => 7200, 'hawaiian' => -36000,
88
+ 'india' => 19800, 'iran' => 12600,
89
+ 'jerusalem' => 7200, 'korea' => 32400,
90
+ 'mexico' => -21600, 'mid-atlantic' => -7200,
91
+ 'mountain' => -25200, 'myanmar' => 23400,
92
+ 'n. central asia' => 21600, 'nepal' => 20700,
93
+ 'new zealand' => 43200, 'newfoundland' => -12600,
94
+ 'north asia east' => 28800, 'north asia' => 25200,
95
+ 'pacific sa' => -14400, 'pacific' => -28800,
96
+ 'romance' => 3600, 'russian' => 10800,
97
+ 'sa eastern' => -10800, 'sa pacific' => -18000,
98
+ 'sa western' => -14400, 'samoa' => -39600,
99
+ 'se asia' => 25200, 'malay peninsula' => 28800,
100
+ 'south africa' => 7200, 'sri lanka' => 21600,
101
+ 'taipei' => 28800, 'tasmania' => 36000,
102
+ 'tokyo' => 32400, 'tonga' => 46800,
103
+ 'us eastern' => -18000, 'us mountain' => -25200,
104
+ 'vladivostok' => 36000, 'w. australia' => 28800,
105
+ 'w. central africa' => 3600, 'w. europe' => 3600,
106
+ 'west asia' => 18000, 'west pacific' => 36000,
107
+ 'yakutsk' => 32400
108
+ }
109
+
110
+ [MONTHS, DAYS, ABBR_MONTHS, ABBR_DAYS, ZONES].each do |x|
111
+ x.freeze
112
+ end
113
+
114
+ class Bag # :nodoc:
115
+
116
+ def initialize
117
+ @extra = {}
118
+ end
119
+
120
+ attr_accessor :year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :zone
121
+ attr_accessor :offset
122
+
123
+ attr_accessor :_cent, :_merid, :_comp
124
+
125
+ def [](key)
126
+ @extra[key]
127
+ end
128
+
129
+ def []=(key, val)
130
+ @extra[key] = val
131
+ end
132
+
133
+ Fast = [:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :zone,
134
+ :offset]
135
+
136
+ def to_hash
137
+ Fast.each do |x|
138
+ if val = __send__(x)
139
+ @extra[x] = val
140
+ end
141
+ end
142
+
143
+ @extra
144
+ end
145
+
146
+ end
147
+
148
+ end
149
+
150
+ def emit(e, f) # :nodoc:
151
+ case e
152
+ when Numeric
153
+ sign = %w(+ + -)[e <=> 0]
154
+ e = e.abs
155
+ end
156
+
157
+ s = e.to_s
158
+
159
+ if f[:s] && f[:p] == '0'
160
+ f[:w] -= 1
161
+ end
162
+
163
+ if f[:s] && f[:p] == "\s"
164
+ s[0,0] = sign
165
+ end
166
+
167
+ if f[:p] != '-'
168
+ s = s.rjust(f[:w], f[:p])
169
+ end
170
+
171
+ if f[:s] && f[:p] != "\s"
172
+ s[0,0] = sign
173
+ end
174
+
175
+ s = s.upcase if f[:u]
176
+ s = s.downcase if f[:d]
177
+ s
178
+ end
179
+
180
+ def emit_w(e, w, f) # :nodoc:
181
+ f[:w] = w unless f[:w]
182
+ emit(e, f)
183
+ end
184
+
185
+ def emit_n(e, w, f) # :nodoc:
186
+ f[:p] ||= '0'
187
+ emit_w(e, w, f)
188
+ end
189
+
190
+ def emit_sn(e, w, f) # :nodoc:
191
+ if e < 0
192
+ w += 1
193
+ f[:s] = true
194
+ end
195
+ emit_n(e, w, f)
196
+ end
197
+
198
+ def emit_z(e, w, f) # :nodoc:
199
+ w += 1
200
+ f[:s] = true
201
+ emit_n(e, w, f)
202
+ end
203
+
204
+ def emit_a(e, w, f) # :nodoc:
205
+ f[:p] ||= "\s"
206
+ emit_w(e, w, f)
207
+ end
208
+
209
+ def emit_ad(e, w, f) # :nodoc:
210
+ if f[:x]
211
+ f[:u] = true
212
+ f[:d] = false
213
+ end
214
+ emit_a(e, w, f)
215
+ end
216
+
217
+ def emit_au(e, w, f) # :nodoc:
218
+ if f[:x]
219
+ f[:u] = false
220
+ f[:d] = true
221
+ end
222
+ emit_a(e, w, f)
223
+ end
224
+
225
+ private :emit, :emit_w, :emit_n, :emit_sn, :emit_z,
226
+ :emit_a, :emit_ad, :emit_au
227
+
228
+ def strftime(fmt='%F')
229
+ fmt.gsub(/%([-_0^#]+)?(\d+)?([EO]?(?::{1,3}z|.))/m) do |m|
230
+ f = {}
231
+ a = $&
232
+ s, w, c = $1, $2, $3
233
+ if s
234
+ s.scan(/./) do |k|
235
+ case k
236
+ when '-'; f[:p] = '-'
237
+ when '_'; f[:p] = "\s"
238
+ when '0'; f[:p] = '0'
239
+ when '^'; f[:u] = true
240
+ when '#'; f[:x] = true
241
+ end
242
+ end
243
+ end
244
+ if w
245
+ f[:w] = w.to_i
246
+ end
247
+ case c
248
+ when 'A'; emit_ad(DAYNAMES[wday], 0, f)
249
+ when 'a'; emit_ad(ABBR_DAYNAMES[wday], 0, f)
250
+ when 'B'; emit_ad(MONTHNAMES[mon], 0, f)
251
+ when 'b'; emit_ad(ABBR_MONTHNAMES[mon], 0, f)
252
+ when 'C', 'EC'; emit_sn((year / 100).floor, 2, f)
253
+ when 'c', 'Ec'; emit_a(strftime('%a %b %e %H:%M:%S %Y'), 0, f)
254
+ when 'D'; emit_a(strftime('%m/%d/%y'), 0, f)
255
+ when 'd', 'Od'; emit_n(mday, 2, f)
256
+ when 'e', 'Oe'; emit_a(mday, 2, f)
257
+ when 'F'
258
+ if m == '%F'
259
+ format('%.4d-%02d-%02d', year, mon, mday) # 4p
260
+ else
261
+ emit_a(strftime('%Y-%m-%d'), 0, f)
262
+ end
263
+ when 'G'; emit_sn(cwyear, 4, f)
264
+ when 'g'; emit_n(cwyear % 100, 2, f)
265
+ when 'H', 'OH'; emit_n(hour, 2, f)
266
+ when 'h'; emit_ad(strftime('%b'), 0, f)
267
+ when 'I', 'OI'; emit_n((hour % 12).nonzero? || 12, 2, f)
268
+ when 'j'; emit_n(yday, 3, f)
269
+ when 'k'; emit_a(hour, 2, f)
270
+ when 'L'
271
+ emit_n((sec_fraction / MILLISECONDS_IN_DAY).floor, 3, f)
272
+ when 'l'; emit_a((hour % 12).nonzero? || 12, 2, f)
273
+ when 'M', 'OM'; emit_n(min, 2, f)
274
+ when 'm', 'Om'; emit_n(mon, 2, f)
275
+ when 'N'
276
+ emit_n((sec_fraction / NANOSECONDS_IN_DAY).floor, 9, f)
277
+ when 'n'; "\n"
278
+ when 'P'; emit_ad(strftime('%p').downcase, 0, f)
279
+ when 'p'; emit_au(if hour < 12 then 'AM' else 'PM' end, 0, f)
280
+ when 'Q'
281
+ s = ((ajd - UNIX_EPOCH_IN_AJD) / MILLISECONDS_IN_DAY).round
282
+ emit_sn(s, 1, f)
283
+ when 'R'; emit_a(strftime('%H:%M'), 0, f)
284
+ when 'r'; emit_a(strftime('%I:%M:%S %p'), 0, f)
285
+ when 'S', 'OS'; emit_n(sec, 2, f)
286
+ when 's'
287
+ s = ((ajd - UNIX_EPOCH_IN_AJD) / SECONDS_IN_DAY).round
288
+ emit_sn(s, 1, f)
289
+ when 'T'
290
+ if m == '%T'
291
+ format('%02d:%02d:%02d', hour, min, sec) # 4p
292
+ else
293
+ emit_a(strftime('%H:%M:%S'), 0, f)
294
+ end
295
+ when 't'; "\t"
296
+ when 'U', 'W', 'OU', 'OW'
297
+ emit_n(if c[-1,1] == 'U' then wnum0 else wnum1 end, 2, f)
298
+ when 'u', 'Ou'; emit_n(cwday, 1, f)
299
+ when 'V', 'OV'; emit_n(cweek, 2, f)
300
+ when 'v'; emit_a(strftime('%e-%b-%Y'), 0, f)
301
+ when 'w', 'Ow'; emit_n(wday, 1, f)
302
+ when 'X', 'EX'; emit_a(strftime('%H:%M:%S'), 0, f)
303
+ when 'x', 'Ex'; emit_a(strftime('%m/%d/%y'), 0, f)
304
+ when 'Y', 'EY'; emit_sn(year, 4, f)
305
+ when 'y', 'Ey', 'Oy'; emit_n(year % 100, 2, f)
306
+ when 'Z'; emit_au(strftime('%:z'), 0, f)
307
+ when /\A(:{0,3})z/
308
+ t = $1.size
309
+ sign = if offset < 0 then -1 else +1 end
310
+ fr = offset.abs
311
+ ss = fr.div(SECONDS_IN_DAY) # 4p
312
+ hh, ss = ss.divmod(3600)
313
+ mm, ss = ss.divmod(60)
314
+ if t == 3
315
+ if ss.nonzero? then t = 2
316
+ elsif mm.nonzero? then t = 1
317
+ else t = -1
318
+ end
319
+ end
320
+ case t
321
+ when -1
322
+ tail = []
323
+ sep = ''
324
+ when 0
325
+ f[:w] -= 2 if f[:w]
326
+ tail = ['%02d' % mm]
327
+ sep = ''
328
+ when 1
329
+ f[:w] -= 3 if f[:w]
330
+ tail = ['%02d' % mm]
331
+ sep = ':'
332
+ when 2
333
+ f[:w] -= 6 if f[:w]
334
+ tail = ['%02d' % mm, '%02d' % ss]
335
+ sep = ':'
336
+ end
337
+ ([emit_z(sign * hh, 2, f)] + tail).join(sep)
338
+ when '%'; emit_a('%', 0, f)
339
+ when '+'; emit_a(strftime('%a %b %e %H:%M:%S %Z %Y'), 0, f)
340
+ when '1'
341
+ if $VERBOSE
342
+ warn("warning: strftime: %1 is deprecated; forget this")
343
+ end
344
+ emit_n(jd, 1, f)
345
+ when '2'
346
+ if $VERBOSE
347
+ warn("warning: strftime: %2 is deprecated; use '%Y-%j'")
348
+ end
349
+ emit_a(strftime('%Y-%j'), 0, f)
350
+ when '3'
351
+ if $VERBOSE
352
+ warn("warning: strftime: %3 is deprecated; use '%F'")
353
+ end
354
+ emit_a(strftime('%F'), 0, f)
355
+ else
356
+ a
357
+ end
358
+ end
359
+ end
360
+
361
+ # alias_method :format, :strftime
362
+
363
+ def asctime() strftime('%c') end
364
+
365
+ alias_method :ctime, :asctime
366
+
367
+ =begin
368
+ def iso8601() strftime('%F') end
369
+
370
+ def rfc3339() iso8601 end
371
+
372
+ def rfc2822() strftime('%a, %-d %b %Y %T %z') end
373
+
374
+ alias_method :rfc822, :rfc2822
375
+
376
+ def jisx0301
377
+ if jd < 2405160
378
+ iso8601
379
+ else
380
+ case jd
381
+ when 2405160...2419614
382
+ g = 'M%02d' % (year - 1867)
383
+ when 2419614...2424875
384
+ g = 'T%02d' % (year - 1911)
385
+ when 2424875...2447535
386
+ g = 'S%02d' % (year - 1925)
387
+ else
388
+ g = 'H%02d' % (year - 1988)
389
+ end
390
+ g + strftime('.%m.%d')
391
+ end
392
+ end
393
+
394
+ def beat(n=0)
395
+ i, f = (new_offset(HOURS_IN_DAY).day_fraction * 1000).divmod(1)
396
+ ('@%03d' % i) +
397
+ if n < 1
398
+ ''
399
+ else
400
+ '.%0*d' % [n, (f / Rational(1, 10**n)).round]
401
+ end
402
+ end
403
+ =end
404
+
405
+ def self.num_pattern? (s) # :nodoc:
406
+ /\A%[EO]?[CDdeFGgHIjkLlMmNQRrSsTUuVvWwXxYy\d]/ =~ s || /\A\d/ =~ s
407
+ end
408
+
409
+ private_class_method :num_pattern?
410
+
411
+ def self._strptime_i(str, fmt, e) # :nodoc:
412
+ fmt.scan(/%([EO]?(?::{1,3}z|.))|(.)/m) do |s, c|
413
+ a = $&
414
+ if s
415
+ case s
416
+ when 'A', 'a'
417
+ return unless str.sub!(/\A(#{Format::DAYS.keys.join('|')})/io, '') ||
418
+ str.sub!(/\A(#{Format::ABBR_DAYS.keys.join('|')})/io, '')
419
+ val = Format::DAYS[$1.downcase] || Format::ABBR_DAYS[$1.downcase]
420
+ return unless val
421
+ e[:wday] = val
422
+ when 'B', 'b', 'h'
423
+ return unless str.sub!(/\A(#{Format::MONTHS.keys.join('|')})/io, '') ||
424
+ str.sub!(/\A(#{Format::ABBR_MONTHS.keys.join('|')})/io, '')
425
+ val = Format::MONTHS[$1.downcase] || Format::ABBR_MONTHS[$1.downcase]
426
+ return unless val
427
+ e.mon = val
428
+ when 'C', 'EC'
429
+ return unless str.sub!(if num_pattern?($')
430
+ then /\A([-+]?\d{1,2})/
431
+ else /\A([-+]?\d{1,})/
432
+ end, '')
433
+ val = $1.to_i
434
+ e._cent = val
435
+ when 'c', 'Ec'
436
+ return unless _strptime_i(str, '%a %b %e %H:%M:%S %Y', e)
437
+ when 'D'
438
+ return unless _strptime_i(str, '%m/%d/%y', e)
439
+ when 'd', 'e', 'Od', 'Oe'
440
+ return unless str.sub!(/\A( \d|\d{1,2})/, '')
441
+ val = $1.to_i
442
+ return unless (1..31) === val
443
+ e.mday = val
444
+ when 'F'
445
+ return unless _strptime_i(str, '%Y-%m-%d', e)
446
+ when 'G'
447
+ return unless str.sub!(if num_pattern?($')
448
+ then /\A([-+]?\d{1,4})/
449
+ else /\A([-+]?\d{1,})/
450
+ end, '')
451
+ val = $1.to_i
452
+ e[:cwyear] = val
453
+ when 'g'
454
+ return unless str.sub!(/\A(\d{1,2})/, '')
455
+ val = $1.to_i
456
+ return unless (0..99) === val
457
+ e[:cwyear] = val
458
+ e._cent ||= if val >= 69 then 19 else 20 end
459
+ when 'H', 'k', 'OH'
460
+ return unless str.sub!(/\A( \d|\d{1,2})/, '')
461
+ val = $1.to_i
462
+ return unless (0..24) === val
463
+ e.hour = val
464
+ when 'I', 'l', 'OI'
465
+ return unless str.sub!(/\A( \d|\d{1,2})/, '')
466
+ val = $1.to_i
467
+ return unless (1..12) === val
468
+ e.hour = val
469
+ when 'j'
470
+ return unless str.sub!(/\A(\d{1,3})/, '')
471
+ val = $1.to_i
472
+ return unless (1..366) === val
473
+ e[:yday] = val
474
+ when 'L'
475
+ return unless str.sub!(if num_pattern?($')
476
+ then /\A([-+]?\d{1,3})/
477
+ else /\A([-+]?\d{1,})/
478
+ end, '')
479
+ # val = Rational($1.to_i, 10**3)
480
+ val = Rational($1.to_i, 10**$1.size)
481
+ e.sec_fraction = val
482
+ when 'M', 'OM'
483
+ return unless str.sub!(/\A(\d{1,2})/, '')
484
+ val = $1.to_i
485
+ return unless (0..59) === val
486
+ e.min = val
487
+ when 'm', 'Om'
488
+ return unless str.sub!(/\A(\d{1,2})/, '')
489
+ val = $1.to_i
490
+ return unless (1..12) === val
491
+ e.mon = val
492
+ when 'N'
493
+ return unless str.sub!(if num_pattern?($')
494
+ then /\A([-+]?\d{1,9})/
495
+ else /\A([-+]?\d{1,})/
496
+ end, '')
497
+ # val = Rational($1.to_i, 10**9)
498
+ val = Rational($1.to_i, 10**$1.size)
499
+ e.sec_fraction = val
500
+ when 'n', 't'
501
+ return unless _strptime_i(str, "\s", e)
502
+ when 'P', 'p'
503
+ return unless str.sub!(/\A([ap])(?:m\b|\.m\.)/i, '')
504
+ e._merid = if $1.downcase == 'a' then 0 else 12 end
505
+ when 'Q'
506
+ return unless str.sub!(/\A(-?\d{1,})/, '')
507
+ val = Rational($1.to_i, 10**3)
508
+ e[:seconds] = val
509
+ when 'R'
510
+ return unless _strptime_i(str, '%H:%M', e)
511
+ when 'r'
512
+ return unless _strptime_i(str, '%I:%M:%S %p', e)
513
+ when 'S', 'OS'
514
+ return unless str.sub!(/\A(\d{1,2})/, '')
515
+ val = $1.to_i
516
+ return unless (0..60) === val
517
+ e.sec = val
518
+ when 's'
519
+ return unless str.sub!(/\A(-?\d{1,})/, '')
520
+ val = $1.to_i
521
+ e[:seconds] = val
522
+ when 'T'
523
+ return unless _strptime_i(str, '%H:%M:%S', e)
524
+ when 'U', 'W', 'OU', 'OW'
525
+ return unless str.sub!(/\A(\d{1,2})/, '')
526
+ val = $1.to_i
527
+ return unless (0..53) === val
528
+ if s[-1,1] == 'U'
529
+ e[:wnum0] = val
530
+ else
531
+ e[:wnum1] = val
532
+ end
533
+ when 'u', 'Ou'
534
+ return unless str.sub!(/\A(\d{1})/, '')
535
+ val = $1.to_i
536
+ return unless (1..7) === val
537
+ e[:cwday] = val
538
+ when 'V', 'OV'
539
+ return unless str.sub!(/\A(\d{1,2})/, '')
540
+ val = $1.to_i
541
+ return unless (1..53) === val
542
+ e[:cweek] = val
543
+ when 'v'
544
+ return unless _strptime_i(str, '%e-%b-%Y', e)
545
+ when 'w'
546
+ return unless str.sub!(/\A(\d{1})/, '')
547
+ val = $1.to_i
548
+ return unless (0..6) === val
549
+ e[:wday] = val
550
+ when 'X', 'EX'
551
+ return unless _strptime_i(str, '%H:%M:%S', e)
552
+ when 'x', 'Ex'
553
+ return unless _strptime_i(str, '%m/%d/%y', e)
554
+ when 'Y', 'EY'
555
+ return unless str.sub!(if num_pattern?($')
556
+ then /\A([-+]?\d{1,4})/
557
+ else /\A([-+]?\d{1,})/
558
+ end, '')
559
+ val = $1.to_i
560
+ e.year = val
561
+ when 'y', 'Ey', 'Oy'
562
+ return unless str.sub!(/\A(\d{1,2})/, '')
563
+ val = $1.to_i
564
+ return unless (0..99) === val
565
+ e.year = val
566
+ e._cent ||= if val >= 69 then 19 else 20 end
567
+ when 'Z', /\A:{0,3}z/
568
+ return unless str.sub!(/\A((?:gmt|utc?)?[-+]\d+(?:[,.:]\d+(?::\d+)?)?
569
+ |[[:alpha:].\s]+(?:standard|daylight)\s+time\b
570
+ |[[:alpha:]]+(?:\s+dst)?\b
571
+ )/ix, '')
572
+ val = $1
573
+ e.zone = val
574
+ offset = zone_to_diff(val)
575
+ e.offset = offset
576
+ when '%'
577
+ return unless str.sub!(/\A%/, '')
578
+ when '+'
579
+ return unless _strptime_i(str, '%a %b %e %H:%M:%S %Z %Y', e)
580
+ when '1'
581
+ if $VERBOSE
582
+ warn("warning: strptime: %1 is deprecated; forget this")
583
+ end
584
+ return unless str.sub!(/\A(\d+)/, '')
585
+ val = $1.to_i
586
+ e[:jd] = val
587
+ when '2'
588
+ if $VERBOSE
589
+ warn("warning: strptime: %2 is deprecated; use '%Y-%j'")
590
+ end
591
+ return unless _strptime_i(str, '%Y-%j', e)
592
+ when '3'
593
+ if $VERBOSE
594
+ warn("warning: strptime: %3 is deprecated; use '%F'")
595
+ end
596
+ return unless _strptime_i(str, '%F', e)
597
+ else
598
+ return unless str.sub!(Regexp.new('\\A' + Regexp.quote(a)), '')
599
+ end
600
+ else
601
+ case c
602
+ when /\A[\s\v]/
603
+ str.sub!(/\A[\s\v]+/, '')
604
+ else
605
+ return unless str.sub!(Regexp.new('\\A' + Regexp.quote(a)), '')
606
+ end
607
+ end
608
+ end
609
+ end
610
+
611
+ private_class_method :_strptime_i
612
+
613
+ def self._strptime(str, fmt='%F')
614
+ str = str.dup
615
+ e = Format::Bag.new
616
+
617
+ return unless _strptime_i(str, fmt, e)
618
+
619
+ if e._cent
620
+ if e[:cwyear]
621
+ e[:cwyear] += e._cent * 100
622
+ end
623
+ if e.year
624
+ e.year += e._cent * 100
625
+ end
626
+ end
627
+
628
+ if e._merid
629
+ if e.hour
630
+ e.hour %= 12
631
+ e.hour += e._merid
632
+ end
633
+ end
634
+
635
+ unless str.empty?
636
+ e[:leftover] = str
637
+ end
638
+
639
+ e.to_hash
640
+ end
641
+
642
+ def self.s3e(e, y, m, d, bc=false)
643
+ unless String === m
644
+ m = m.to_s
645
+ end
646
+
647
+ if y && m && !d
648
+ y, m, d = d, y, m
649
+ end
650
+
651
+ if y == nil
652
+ if d && d.size > 2
653
+ y = d
654
+ d = nil
655
+ end
656
+ if d && d[0,1] == "'"
657
+ y = d
658
+ d = nil
659
+ end
660
+ end
661
+
662
+ if y
663
+ y.scan(/(\d+)(.+)?/)
664
+ if $2
665
+ y, d = d, $1
666
+ end
667
+ end
668
+
669
+ if m
670
+ if m[0,1] == "'" || m.size > 2
671
+ y, m, d = m, d, y # us -> be
672
+ end
673
+ end
674
+
675
+ if d
676
+ if d[0,1] == "'" || d.size > 2
677
+ y, d = d, y
678
+ end
679
+ end
680
+
681
+ if y
682
+ y =~ /([-+])?(\d+)/
683
+ if $1 || $2.size > 2
684
+ c = false
685
+ end
686
+ iy = $&.to_i
687
+ if bc
688
+ iy = -iy + 1
689
+ end
690
+ e.year = iy
691
+ end
692
+
693
+ if m
694
+ m =~ /\d+/
695
+ e.mon = $&.to_i
696
+ end
697
+
698
+ if d
699
+ d =~ /\d+/
700
+ e.mday = $&.to_i
701
+ end
702
+
703
+ if c != nil
704
+ e._comp = c
705
+ end
706
+
707
+ end
708
+
709
+ private_class_method :s3e
710
+
711
+ def self._parse_day(str, e) # :nodoc:
712
+ if str.sub!(/\b(#{Format::ABBR_DAYS.keys.join('|')})[^-\d\s]*/ino, ' ')
713
+ e[:wday] = Format::ABBR_DAYS[$1.downcase]
714
+ true
715
+ =begin
716
+ elsif str.sub!(/\b(?!\dth)(su|mo|tu|we|th|fr|sa)\b/in, ' ')
717
+ e[:wday] = %w(su mo tu we th fr sa).index($1.downcase)
718
+ true
719
+ =end
720
+ end
721
+ end
722
+
723
+ def self._parse_time(str, e) # :nodoc:
724
+ if str.sub!(
725
+ /(
726
+ (?:
727
+ \d+\s*:\s*\d+
728
+ (?:
729
+ \s*:\s*\d+(?:[,.]\d*)?
730
+ )?
731
+ |
732
+ \d+\s*h(?:\s*\d+m?(?:\s*\d+s?)?)?
733
+ )
734
+ (?:
735
+ \s*
736
+ [ap](?:m\b|\.m\.)
737
+ )?
738
+ |
739
+ \d+\s*[ap](?:m\b|\.m\.)
740
+ )
741
+ (?:
742
+ \s*
743
+ (
744
+ (?:gmt|utc?)?[-+]\d+(?:[,.:]\d+(?::\d+)?)?
745
+ |
746
+ [[:alpha:].\s]+(?:standard|daylight)\stime\b
747
+ |
748
+ [[:alpha:]]+(?:\sdst)?\b
749
+ )
750
+ )?
751
+ /inx,
752
+ ' ')
753
+
754
+ t = $1
755
+ e.zone = $2 if $2
756
+
757
+ t =~ /\A(\d+)h?
758
+ (?:\s*:?\s*(\d+)m?
759
+ (?:
760
+ \s*:?\s*(\d+)(?:[,.](\d+))?s?
761
+ )?
762
+ )?
763
+ (?:\s*([ap])(?:m\b|\.m\.))?/inx
764
+
765
+ e.hour = $1.to_i
766
+ e.min = $2.to_i if $2
767
+ e.sec = $3.to_i if $3
768
+ e.sec_fraction = Rational($4.to_i, 10**$4.size) if $4
769
+
770
+ if $5
771
+ e.hour %= 12
772
+ if $5.downcase == 'p'
773
+ e.hour += 12
774
+ end
775
+ end
776
+ true
777
+ end
778
+ end
779
+
780
+ =begin
781
+ def self._parse_beat(str, e) # :nodoc:
782
+ if str.sub!(/@\s*(\d+)(?:[,.](\d*))?/, ' ')
783
+ beat = Rational($1.to_i)
784
+ beat += Rational($2.to_i, 10**$2.size) if $2
785
+ secs = Rational(beat, 1000)
786
+ h, min, s, fr = self.day_fraction_to_time(secs)
787
+ e.hour = h
788
+ e.min = min
789
+ e.sec = s
790
+ e.sec_fraction = fr * 86400
791
+ e.zone = '+01:00'
792
+ true
793
+ end
794
+ end
795
+ =end
796
+
797
+ def self._parse_eu(str, e) # :nodoc:
798
+ if str.sub!(
799
+ /'?(\d+)[^-\d\s]*
800
+ \s*
801
+ (#{Format::ABBR_MONTHS.keys.join('|')})[^-\d\s']*
802
+ (?:
803
+ \s*
804
+ (c(?:e|\.e\.)|b(?:ce|\.c\.e\.)|a(?:d|\.d\.)|b(?:c|\.c\.))?
805
+ \s*
806
+ ('?-?\d+(?:(?:st|nd|rd|th)\b)?)
807
+ )?
808
+ /inox,
809
+ ' ') # '
810
+ s3e(e, $4, Format::ABBR_MONTHS[$2.downcase], $1,
811
+ $3 && $3[0,1].downcase == 'b')
812
+ true
813
+ end
814
+ end
815
+
816
+ def self._parse_us(str, e) # :nodoc:
817
+ if str.sub!(
818
+ /\b(#{Format::ABBR_MONTHS.keys.join('|')})[^-\d\s']*
819
+ \s*
820
+ ('?\d+)[^-\d\s']*
821
+ (?:
822
+ \s*
823
+ (c(?:e|\.e\.)|b(?:ce|\.c\.e\.)|a(?:d|\.d\.)|b(?:c|\.c\.))?
824
+ \s*
825
+ ('?-?\d+)
826
+ )?
827
+ /inox,
828
+ ' ') # '
829
+ s3e(e, $4, Format::ABBR_MONTHS[$1.downcase], $2,
830
+ $3 && $3[0,1].downcase == 'b')
831
+ true
832
+ end
833
+ end
834
+
835
+ def self._parse_iso(str, e) # :nodoc:
836
+ if str.sub!(/('?[-+]?\d+)-(\d+)-('?-?\d+)/n, ' ')
837
+ s3e(e, $1, $2, $3)
838
+ true
839
+ end
840
+ end
841
+
842
+ def self._parse_iso2(str, e) # :nodoc:
843
+ if str.sub!(/\b(\d{2}|\d{4})?-?w(\d{2})(?:-?(\d))?\b/in, ' ')
844
+ e[:cwyear] = $1.to_i if $1
845
+ e[:cweek] = $2.to_i
846
+ e[:cwday] = $3.to_i if $3
847
+ true
848
+ elsif str.sub!(/-w-(\d)\b/in, ' ')
849
+ e[:cwday] = $1.to_i
850
+ true
851
+ elsif str.sub!(/--(\d{2})?-(\d{2})\b/n, ' ')
852
+ e.mon = $1.to_i if $1
853
+ e.mday = $2.to_i
854
+ true
855
+ elsif str.sub!(/--(\d{2})(\d{2})?\b/n, ' ')
856
+ e.mon = $1.to_i
857
+ e.mday = $2.to_i if $2
858
+ true
859
+ elsif /[,.](\d{2}|\d{4})-\d{3}\b/n !~ str &&
860
+ str.sub!(/\b(\d{2}|\d{4})-(\d{3})\b/n, ' ')
861
+ e.year = $1.to_i
862
+ e[:yday] = $2.to_i
863
+ true
864
+ elsif /\d-\d{3}\b/n !~ str &&
865
+ str.sub!(/\b-(\d{3})\b/n, ' ')
866
+ e[:yday] = $1.to_i
867
+ true
868
+ end
869
+ end
870
+
871
+ def self._parse_jis(str, e) # :nodoc:
872
+ if str.sub!(/\b([mtsh])(\d+)\.(\d+)\.(\d+)/in, ' ')
873
+ era = { 'm'=>1867,
874
+ 't'=>1911,
875
+ 's'=>1925,
876
+ 'h'=>1988
877
+ }[$1.downcase]
878
+ e.year = $2.to_i + era
879
+ e.mon = $3.to_i
880
+ e.mday = $4.to_i
881
+ true
882
+ end
883
+ end
884
+
885
+ def self._parse_vms(str, e) # :nodoc:
886
+ if str.sub!(/('?-?\d+)-(#{Format::ABBR_MONTHS.keys.join('|')})[^-]*
887
+ -('?-?\d+)/inox, ' ')
888
+ s3e(e, $3, Format::ABBR_MONTHS[$2.downcase], $1)
889
+ true
890
+ elsif str.sub!(/\b(#{Format::ABBR_MONTHS.keys.join('|')})[^-]*
891
+ -('?-?\d+)(?:-('?-?\d+))?/inox, ' ')
892
+ s3e(e, $3, Format::ABBR_MONTHS[$1.downcase], $2)
893
+ true
894
+ end
895
+ end
896
+
897
+ def self._parse_sla(str, e) # :nodoc:
898
+ if str.sub!(%r|('?-?\d+)/\s*('?\d+)(?:\D\s*('?-?\d+))?|n, ' ') # '
899
+ s3e(e, $3, $1, $2)
900
+ true
901
+ end
902
+ end
903
+
904
+ def self._parse_dot(str, e) # :nodoc:
905
+ if str.sub!(%r|('?-?\d+)\.\s*('?\d+)\.\s*('?-?\d+)|n, ' ') # '
906
+ s3e(e, $1, $2, $3)
907
+ true
908
+ end
909
+ end
910
+
911
+ def self._parse_year(str, e) # :nodoc:
912
+ if str.sub!(/'(\d+)\b/n, ' ')
913
+ e.year = $1.to_i
914
+ true
915
+ end
916
+ end
917
+
918
+ def self._parse_mon(str, e) # :nodoc:
919
+ if str.sub!(/\b(#{Format::ABBR_MONTHS.keys.join('|')})\S*/ino, ' ')
920
+ e.mon = Format::ABBR_MONTHS[$1.downcase]
921
+ true
922
+ end
923
+ end
924
+
925
+ def self._parse_mday(str, e) # :nodoc:
926
+ if str.sub!(/(\d+)(st|nd|rd|th)\b/in, ' ')
927
+ e.mday = $1.to_i
928
+ true
929
+ end
930
+ end
931
+
932
+ def self._parse_ddd(str, e) # :nodoc:
933
+ if str.sub!(
934
+ /([-+]?)(\d{2,14})
935
+ (?:
936
+ \s*
937
+ t?
938
+ \s*
939
+ (\d{2,6})?(?:[,.](\d*))?
940
+ )?
941
+ (?:
942
+ \s*
943
+ (
944
+ z\b
945
+ |
946
+ [-+]\d{1,4}\b
947
+ |
948
+ \[[-+]?\d[^\]]*\]
949
+ )
950
+ )?
951
+ /inx,
952
+ ' ')
953
+ case $2.size
954
+ when 2
955
+ if $3.nil? && $4
956
+ e.sec = $2[-2, 2].to_i
957
+ else
958
+ e.mday = $2[ 0, 2].to_i
959
+ end
960
+ when 4
961
+ if $3.nil? && $4
962
+ e.sec = $2[-2, 2].to_i
963
+ e.min = $2[-4, 2].to_i
964
+ else
965
+ e.mon = $2[ 0, 2].to_i
966
+ e.mday = $2[ 2, 2].to_i
967
+ end
968
+ when 6
969
+ if $3.nil? && $4
970
+ e.sec = $2[-2, 2].to_i
971
+ e.min = $2[-4, 2].to_i
972
+ e.hour = $2[-6, 2].to_i
973
+ else
974
+ e.year = ($1 + $2[ 0, 2]).to_i
975
+ e.mon = $2[ 2, 2].to_i
976
+ e.mday = $2[ 4, 2].to_i
977
+ end
978
+ when 8, 10, 12, 14
979
+ if $3.nil? && $4
980
+ e.sec = $2[-2, 2].to_i
981
+ e.min = $2[-4, 2].to_i
982
+ e.hour = $2[-6, 2].to_i
983
+ e.mday = $2[-8, 2].to_i
984
+ if $2.size >= 10
985
+ e.mon = $2[-10, 2].to_i
986
+ end
987
+ if $2.size == 12
988
+ e.year = ($1 + $2[-12, 2]).to_i
989
+ end
990
+ if $2.size == 14
991
+ e.year = ($1 + $2[-14, 4]).to_i
992
+ e._comp = false
993
+ end
994
+ else
995
+ e.year = ($1 + $2[ 0, 4]).to_i
996
+ e.mon = $2[ 4, 2].to_i
997
+ e.mday = $2[ 6, 2].to_i
998
+ e.hour = $2[ 8, 2].to_i if $2.size >= 10
999
+ e.min = $2[10, 2].to_i if $2.size >= 12
1000
+ e.sec = $2[12, 2].to_i if $2.size >= 14
1001
+ e._comp = false
1002
+ end
1003
+ when 3
1004
+ if $3.nil? && $4
1005
+ e.sec = $2[-2, 2].to_i
1006
+ e.min = $2[-3, 1].to_i
1007
+ else
1008
+ e[:yday] = $2[ 0, 3].to_i
1009
+ end
1010
+ when 5
1011
+ if $3.nil? && $4
1012
+ e.sec = $2[-2, 2].to_i
1013
+ e.min = $2[-4, 2].to_i
1014
+ e.hour = $2[-5, 1].to_i
1015
+ else
1016
+ e.year = ($1 + $2[ 0, 2]).to_i
1017
+ e[:yday] = $2[ 2, 3].to_i
1018
+ end
1019
+ when 7
1020
+ if $3.nil? && $4
1021
+ e.sec = $2[-2, 2].to_i
1022
+ e.min = $2[-4, 2].to_i
1023
+ e.hour = $2[-6, 2].to_i
1024
+ e.mday = $2[-7, 1].to_i
1025
+ else
1026
+ e.year = ($1 + $2[ 0, 4]).to_i
1027
+ e[:yday] = $2[ 4, 3].to_i
1028
+ end
1029
+ end
1030
+ if $3
1031
+ if $4
1032
+ case $3.size
1033
+ when 2, 4, 6
1034
+ e.sec = $3[-2, 2].to_i
1035
+ e.min = $3[-4, 2].to_i if $3.size >= 4
1036
+ e.hour = $3[-6, 2].to_i if $3.size >= 6
1037
+ end
1038
+ else
1039
+ case $3.size
1040
+ when 2, 4, 6
1041
+ e.hour = $3[ 0, 2].to_i
1042
+ e.min = $3[ 2, 2].to_i if $3.size >= 4
1043
+ e.sec = $3[ 4, 2].to_i if $3.size >= 6
1044
+ end
1045
+ end
1046
+ end
1047
+ if $4
1048
+ e.sec_fraction = Rational($4.to_i, 10**$4.size)
1049
+ end
1050
+ if $5
1051
+ e.zone = $5
1052
+ if e.zone[0,1] == '['
1053
+ o, n, = e.zone[1..-2].split(':')
1054
+ e.zone = n || o
1055
+ if /\A\d/ =~ o
1056
+ o = format('+%s', o)
1057
+ end
1058
+ e.offset = zone_to_diff(o)
1059
+ end
1060
+ end
1061
+ true
1062
+ end
1063
+ end
1064
+
1065
+ private_class_method :_parse_day, :_parse_time, # :_parse_beat,
1066
+ :_parse_eu, :_parse_us, :_parse_iso, :_parse_iso2,
1067
+ :_parse_jis, :_parse_vms, :_parse_sla, :_parse_dot,
1068
+ :_parse_year, :_parse_mon, :_parse_mday, :_parse_ddd
1069
+
1070
+ def self._parse(str, comp=false, return_bag=false)
1071
+ str = str.dup
1072
+
1073
+ e = Format::Bag.new
1074
+
1075
+ e._comp = comp
1076
+
1077
+ str.gsub!(/[^-+',.\/:@[:alnum:]\[\]\x80-\xff]+/n, ' ')
1078
+
1079
+ _parse_time(str, e) # || _parse_beat(str, e)
1080
+ _parse_day(str, e)
1081
+
1082
+ _parse_eu(str, e) ||
1083
+ _parse_us(str, e) ||
1084
+ _parse_iso(str, e) ||
1085
+ _parse_jis(str, e) ||
1086
+ _parse_vms(str, e) ||
1087
+ _parse_sla(str, e) ||
1088
+ _parse_dot(str, e) ||
1089
+ _parse_iso2(str, e) ||
1090
+ _parse_year(str, e) ||
1091
+ _parse_mon(str, e) ||
1092
+ _parse_mday(str, e) ||
1093
+ _parse_ddd(str, e)
1094
+
1095
+ if str.sub!(/\b(bc\b|bce\b|b\.c\.|b\.c\.e\.)/in, ' ')
1096
+ if e.year
1097
+ e.year = -e.year + 1
1098
+ end
1099
+ end
1100
+
1101
+ if str.sub!(/\A\s*(\d{1,2})\s*\z/n, ' ')
1102
+ if e.hour && !e.mday
1103
+ v = $1.to_i
1104
+ if (1..31) === v
1105
+ e.mday = v
1106
+ end
1107
+ end
1108
+ if e.mday && !e.hour
1109
+ v = $1.to_i
1110
+ if (0..24) === v
1111
+ e.hour = v
1112
+ end
1113
+ end
1114
+ end
1115
+
1116
+ if e._comp
1117
+ if e[:cwyear]
1118
+ if e[:cwyear] >= 0 && e[:cwyear] <= 99
1119
+ e[:cwyear] += if e[:cwyear] >= 69
1120
+ then 1900 else 2000 end
1121
+ end
1122
+ end
1123
+ if e.year
1124
+ if e.year >= 0 && e.year <= 99
1125
+ e.year += if e.year >= 69
1126
+ then 1900 else 2000 end
1127
+ end
1128
+ end
1129
+ end
1130
+
1131
+ e.offset ||= zone_to_diff(e.zone) if e.zone
1132
+
1133
+ return e if return_bag
1134
+ e.to_hash
1135
+ end
1136
+
1137
+ def self.zone_to_diff(zone) # :nodoc:
1138
+ zone = zone.downcase
1139
+ if zone.sub!(/\s+(standard|daylight)\s+time\z/, '')
1140
+ dst = $1 == 'daylight'
1141
+ else
1142
+ dst = zone.sub!(/\s+dst\z/, '')
1143
+ end
1144
+ if Format::ZONES.include?(zone)
1145
+ offset = Format::ZONES[zone]
1146
+ offset += 3600 if dst
1147
+ elsif zone.sub!(/\A(?:gmt|utc?)?([-+])/, '')
1148
+ sign = $1
1149
+ if zone.include?(':')
1150
+ hour, min, sec, = zone.split(':')
1151
+ elsif zone.include?(',') || zone.include?('.')
1152
+ hour, fr, = zone.split(/[,.]/)
1153
+ min = Rational(fr.to_i, 10**fr.size) * 60
1154
+ else
1155
+ case zone.size
1156
+ when 3
1157
+ hour = zone[0,1]
1158
+ min = zone[1,2]
1159
+ else
1160
+ hour = zone[0,2]
1161
+ min = zone[2,2]
1162
+ sec = zone[4,2]
1163
+ end
1164
+ end
1165
+ offset = hour.to_i * 3600 + min.to_i * 60 + sec.to_i
1166
+ offset *= -1 if sign == '-'
1167
+ end
1168
+ offset
1169
+ end
1170
+
1171
+ end
1172
+
1173
+ class DateTime < Date
1174
+
1175
+ def strftime(fmt='%FT%T%:z')
1176
+ super(fmt)
1177
+ end
1178
+
1179
+ def self._strptime(str, fmt='%FT%T%z')
1180
+ super(str, fmt)
1181
+ end
1182
+
1183
+ =begin
1184
+ def iso8601_timediv(n) # :nodoc:
1185
+ strftime('T%T' +
1186
+ if n < 1
1187
+ ''
1188
+ else
1189
+ '.%0*d' % [n, (sec_fraction / SECONDS_IN_DAY / (10**n)).round]
1190
+ end +
1191
+ '%:z')
1192
+ end
1193
+
1194
+ private :iso8601_timediv
1195
+
1196
+ def iso8601(n=0)
1197
+ super() + iso8601_timediv(n)
1198
+ end
1199
+
1200
+ def rfc3339(n=0) iso8601(n) end
1201
+
1202
+ def jisx0301(n=0)
1203
+ super() + iso8601_timediv(n)
1204
+ end
1205
+ =end
1206
+
1207
+ end