rubysl-date 0.0.1 → 1.0.1

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