hijri 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +3 -0
- data/.gitignore +4 -0
- data/.yardopts +1 -0
- data/CHANGELOG +4 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +49 -0
- data/Rakefile +16 -0
- data/hijri.gemspec +24 -0
- data/lib/format.rb +1313 -0
- data/lib/hijri.rb +9 -0
- data/lib/hijri/absolute.rb +72 -0
- data/lib/hijri/converter.rb +101 -0
- data/lib/hijri/date.rb +22 -0
- data/lib/hijri/hijri.rb +45 -0
- data/lib/hijri/version.rb +3 -0
- data/test/helper.rb +24 -0
- data/test/test_hijri.rb +31 -0
- metadata +120 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0478df4d8c70d30b3d704918f17ecd12cf7a2775
|
4
|
+
data.tar.gz: f234a98f8cf1a465fea1f6985feb52e8c972fd5d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d9025bc5ff49e22468aab6d681ca8646e7daa05486ed2a5c69cea8280e867d2dbeb836f215ea4c9101d09093046275cdb92ee787d74fee1acca5618b563aaaab
|
7
|
+
data.tar.gz: 06da097f084dc64776813237fe62bdbb2833e87bb7a4e7965a426ce16e63b07ba7b7de012b22094d26cc91bf8211dca7c4c5effa3739bab94e05bebe3bb70ca6
|
data/.document
ADDED
data/.gitignore
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup rdoc --title "hijri Documentation" --protected
|
data/CHANGELOG
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Abdulaziz AlShetwi
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Hijri
|
2
|
+
|
3
|
+
#####Hijri Date library for Ruby.
|
4
|
+
hijri is full Islamic Hijri calendar lib for ruby. The way it work is to convert Gregorian date to absolute date then convert it to Hijri date.
|
5
|
+
### Hijri Calendar (from Wikipedia)
|
6
|
+
The Islamic calendar or Muslim calendar or Hijri calendar: is a lunar calendar consisting of 12 lunar months in a year of 354 or 355 days. It is used to date events in many Muslim countries (concurrently with the Gregorian calendar), and used by Muslims everywhere to determine the proper day on which to celebrate Islamic holy days and festivals. The first year was the year during which the emigration of the Islamic prophet Muhammad from Mecca to Medina, known as the Hijra, occurred. Each numbered year is designated either H for Hijra or AH for the Latin anno Hegirae (in the year of the Hijra).[1] A limited number of years before Hijra (BH) are used to date events related to Islam, such as the birth of Muhammad in 53 BH.[2] The current Islamic year is 1431 AH, from approximately 18 December 2009 (evening) to 6 December 2010 (evening).
|
7
|
+
|
8
|
+
(read more in wikipedia)[http://en.wikipedia.org/wiki/Islamic_calendar]
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
gem 'hijri'
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
$ gem install hijri
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
DateTime.now.to_hijri
|
29
|
+
hijri = Hijri.new 1430, 1, 3
|
30
|
+
hijri.to_greo
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
## TODO
|
35
|
+
|
36
|
+
- [ ] Add Hijri::Date and Hijri::DateTime.
|
37
|
+
- [ ] Accept test error with one day range.
|
38
|
+
- [ ] Add Hijri.now to create Hijri::DateTime object.
|
39
|
+
- [ ] Add Hijri.today to create Hijri::Date object.
|
40
|
+
- [ ] Implement strftime method.
|
41
|
+
|
42
|
+
|
43
|
+
## Contributing
|
44
|
+
|
45
|
+
1. Fork it
|
46
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
47
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
48
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
49
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
|
5
|
+
require 'rake'
|
6
|
+
|
7
|
+
require 'rake/testtask'
|
8
|
+
Rake::TestTask.new do |test|
|
9
|
+
test.libs << 'test'
|
10
|
+
test.pattern = 'test/**/test_*.rb'
|
11
|
+
test.verbose = true
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'yard'
|
15
|
+
YARD::Rake::YardocTask.new
|
16
|
+
task :doc => :yard
|
data/hijri.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.expand_path('../lib/hijri/version', __FILE__)
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = "hijri"
|
7
|
+
gem.version = Hijri::VERSION
|
8
|
+
gem.summary = %q{Hijri Date Library for Ruby}
|
9
|
+
gem.description = %q{hijri is full Islamic Hijri calendar lib for ruby.}
|
10
|
+
gem.license = "MIT"
|
11
|
+
gem.authors = ["Abdulaziz AlShetwi"]
|
12
|
+
gem.email = "ecleeld@gmail.com"
|
13
|
+
gem.homepage = "https://rubygems.org/gems/hijri"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ['lib']
|
19
|
+
|
20
|
+
gem.add_development_dependency 'bundler', '~> 1.0'
|
21
|
+
gem.add_development_dependency 'rake', '~> 0.8'
|
22
|
+
gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
|
23
|
+
gem.add_development_dependency 'yard', '~> 0.8'
|
24
|
+
end
|
data/lib/format.rb
ADDED
@@ -0,0 +1,1313 @@
|
|
1
|
+
# format.rb: Written by Tadayoshi Funaba 1999-2009
|
2
|
+
# $Id: format.rb,v 2.43 2008-01-17 20:16:31+09 tadf Exp $
|
3
|
+
|
4
|
+
class Date
|
5
|
+
|
6
|
+
module Format # :nodoc:
|
7
|
+
|
8
|
+
MONTHS = {
|
9
|
+
'january' => 1, 'february' => 2, 'march' => 3, 'april' => 4,
|
10
|
+
'may' => 5, 'june' => 6, 'july' => 7, 'august' => 8,
|
11
|
+
'september'=> 9, 'october' =>10, 'november' =>11, 'december' =>12
|
12
|
+
}
|
13
|
+
|
14
|
+
DAYS = {
|
15
|
+
'sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday'=> 3,
|
16
|
+
'thursday' => 4, 'friday' => 5, 'saturday' => 6
|
17
|
+
}
|
18
|
+
|
19
|
+
ABBR_MONTHS = {
|
20
|
+
'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4,
|
21
|
+
'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8,
|
22
|
+
'sep' => 9, 'oct' =>10, 'nov' =>11, 'dec' =>12
|
23
|
+
}
|
24
|
+
|
25
|
+
ABBR_DAYS = {
|
26
|
+
'sun' => 0, 'mon' => 1, 'tue' => 2, 'wed' => 3,
|
27
|
+
'thu' => 4, 'fri' => 5, 'sat' => 6
|
28
|
+
}
|
29
|
+
|
30
|
+
ZONES = {
|
31
|
+
'ut' => 0*3600, 'gmt' => 0*3600, 'est' => -5*3600, 'edt' => -4*3600,
|
32
|
+
'cst' => -6*3600, 'cdt' => -5*3600, 'mst' => -7*3600, 'mdt' => -6*3600,
|
33
|
+
'pst' => -8*3600, 'pdt' => -7*3600,
|
34
|
+
'a' => 1*3600, 'b' => 2*3600, 'c' => 3*3600, 'd' => 4*3600,
|
35
|
+
'e' => 5*3600, 'f' => 6*3600, 'g' => 7*3600, 'h' => 8*3600,
|
36
|
+
'i' => 9*3600, 'k' => 10*3600, 'l' => 11*3600, 'm' => 12*3600,
|
37
|
+
'n' => -1*3600, 'o' => -2*3600, 'p' => -3*3600, 'q' => -4*3600,
|
38
|
+
'r' => -5*3600, 's' => -6*3600, 't' => -7*3600, 'u' => -8*3600,
|
39
|
+
'v' => -9*3600, 'w' =>-10*3600, 'x' =>-11*3600, 'y' =>-12*3600,
|
40
|
+
'z' => 0*3600,
|
41
|
+
|
42
|
+
'utc' => 0*3600, 'wet' => 0*3600,
|
43
|
+
'at' => -2*3600, 'brst'=> -2*3600, 'ndt' => -(2*3600+1800),
|
44
|
+
'art' => -3*3600, 'adt' => -3*3600, 'brt' => -3*3600, 'clst'=> -3*3600,
|
45
|
+
'nst' => -(3*3600+1800),
|
46
|
+
'ast' => -4*3600, 'clt' => -4*3600,
|
47
|
+
'akdt'=> -8*3600, 'ydt' => -8*3600,
|
48
|
+
'akst'=> -9*3600, 'hadt'=> -9*3600, 'hdt' => -9*3600, 'yst' => -9*3600,
|
49
|
+
'ahst'=>-10*3600, 'cat' =>-10*3600, 'hast'=>-10*3600, 'hst' =>-10*3600,
|
50
|
+
'nt' =>-11*3600,
|
51
|
+
'idlw'=>-12*3600,
|
52
|
+
'bst' => 1*3600, 'cet' => 1*3600, 'fwt' => 1*3600, 'met' => 1*3600,
|
53
|
+
'mewt'=> 1*3600, 'mez' => 1*3600, 'swt' => 1*3600, 'wat' => 1*3600,
|
54
|
+
'west'=> 1*3600,
|
55
|
+
'cest'=> 2*3600, 'eet' => 2*3600, 'fst' => 2*3600, 'mest'=> 2*3600,
|
56
|
+
'mesz'=> 2*3600, 'sast'=> 2*3600, 'sst' => 2*3600,
|
57
|
+
'bt' => 3*3600, 'eat' => 3*3600, 'eest'=> 3*3600, 'msk' => 3*3600,
|
58
|
+
'msd' => 4*3600, 'zp4' => 4*3600,
|
59
|
+
'zp5' => 5*3600, 'ist' => (5*3600+1800),
|
60
|
+
'zp6' => 6*3600,
|
61
|
+
'wast'=> 7*3600,
|
62
|
+
'cct' => 8*3600, 'sgt' => 8*3600, 'wadt'=> 8*3600,
|
63
|
+
'jst' => 9*3600, 'kst' => 9*3600,
|
64
|
+
'east'=> 10*3600, 'gst' => 10*3600,
|
65
|
+
'eadt'=> 11*3600,
|
66
|
+
'idle'=> 12*3600, 'nzst'=> 12*3600, 'nzt' => 12*3600,
|
67
|
+
'nzdt'=> 13*3600,
|
68
|
+
|
69
|
+
'afghanistan' => 16200, 'alaskan' => -32400,
|
70
|
+
'arab' => 10800, 'arabian' => 14400,
|
71
|
+
'arabic' => 10800, 'atlantic' => -14400,
|
72
|
+
'aus central' => 34200, 'aus eastern' => 36000,
|
73
|
+
'azores' => -3600, 'canada central' => -21600,
|
74
|
+
'cape verde' => -3600, 'caucasus' => 14400,
|
75
|
+
'cen. australia' => 34200, 'central america' => -21600,
|
76
|
+
'central asia' => 21600, 'central europe' => 3600,
|
77
|
+
'central european' => 3600, 'central pacific' => 39600,
|
78
|
+
'central' => -21600, 'china' => 28800,
|
79
|
+
'dateline' => -43200, 'e. africa' => 10800,
|
80
|
+
'e. australia' => 36000, 'e. europe' => 7200,
|
81
|
+
'e. south america' => -10800, 'eastern' => -18000,
|
82
|
+
'egypt' => 7200, 'ekaterinburg' => 18000,
|
83
|
+
'fiji' => 43200, 'fle' => 7200,
|
84
|
+
'greenland' => -10800, 'greenwich' => 0,
|
85
|
+
'gtb' => 7200, 'hawaiian' => -36000,
|
86
|
+
'india' => 19800, 'iran' => 12600,
|
87
|
+
'jerusalem' => 7200, 'korea' => 32400,
|
88
|
+
'mexico' => -21600, 'mid-atlantic' => -7200,
|
89
|
+
'mountain' => -25200, 'myanmar' => 23400,
|
90
|
+
'n. central asia' => 21600, 'nepal' => 20700,
|
91
|
+
'new zealand' => 43200, 'newfoundland' => -12600,
|
92
|
+
'north asia east' => 28800, 'north asia' => 25200,
|
93
|
+
'pacific sa' => -14400, 'pacific' => -28800,
|
94
|
+
'romance' => 3600, 'russian' => 10800,
|
95
|
+
'sa eastern' => -10800, 'sa pacific' => -18000,
|
96
|
+
'sa western' => -14400, 'samoa' => -39600,
|
97
|
+
'se asia' => 25200, 'malay peninsula' => 28800,
|
98
|
+
'south africa' => 7200, 'sri lanka' => 21600,
|
99
|
+
'taipei' => 28800, 'tasmania' => 36000,
|
100
|
+
'tokyo' => 32400, 'tonga' => 46800,
|
101
|
+
'us eastern' => -18000, 'us mountain' => -25200,
|
102
|
+
'vladivostok' => 36000, 'w. australia' => 28800,
|
103
|
+
'w. central africa' => 3600, 'w. europe' => 3600,
|
104
|
+
'west asia' => 18000, 'west pacific' => 36000,
|
105
|
+
'yakutsk' => 32400
|
106
|
+
}
|
107
|
+
|
108
|
+
[MONTHS, DAYS, ABBR_MONTHS, ABBR_DAYS, ZONES].each do |x|
|
109
|
+
x.freeze
|
110
|
+
end
|
111
|
+
|
112
|
+
class Bag # :nodoc:
|
113
|
+
|
114
|
+
def initialize
|
115
|
+
@elem = {}
|
116
|
+
end
|
117
|
+
|
118
|
+
def method_missing(t, *args, &block)
|
119
|
+
t = t.to_s
|
120
|
+
set = t.chomp!('=')
|
121
|
+
t = t.intern
|
122
|
+
if set
|
123
|
+
@elem[t] = args[0]
|
124
|
+
else
|
125
|
+
@elem[t]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def to_hash
|
130
|
+
@elem.reject{|k, v| /\A_/ =~ k.to_s || v.nil?}
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
def emit(e, f) # :nodoc:
|
138
|
+
case e
|
139
|
+
when Numeric
|
140
|
+
sign = %w(+ + -)[e <=> 0]
|
141
|
+
e = e.abs
|
142
|
+
end
|
143
|
+
|
144
|
+
s = e.to_s
|
145
|
+
|
146
|
+
if f[:s] && f[:p] == '0'
|
147
|
+
f[:w] -= 1
|
148
|
+
end
|
149
|
+
|
150
|
+
if f[:s] && f[:p] == "\s"
|
151
|
+
s[0,0] = sign
|
152
|
+
end
|
153
|
+
|
154
|
+
if f[:p] != '-'
|
155
|
+
s = s.rjust(f[:w], f[:p])
|
156
|
+
end
|
157
|
+
|
158
|
+
if f[:s] && f[:p] != "\s"
|
159
|
+
s[0,0] = sign
|
160
|
+
end
|
161
|
+
|
162
|
+
s = s.upcase if f[:u]
|
163
|
+
s = s.downcase if f[:d]
|
164
|
+
s
|
165
|
+
end
|
166
|
+
|
167
|
+
def emit_w(e, w, f) # :nodoc:
|
168
|
+
f[:w] = [f[:w], w].compact.max
|
169
|
+
emit(e, f)
|
170
|
+
end
|
171
|
+
|
172
|
+
def emit_n(e, w, f) # :nodoc:
|
173
|
+
f[:p] ||= '0'
|
174
|
+
emit_w(e, w, f)
|
175
|
+
end
|
176
|
+
|
177
|
+
def emit_sn(e, w, f) # :nodoc:
|
178
|
+
if e < 0
|
179
|
+
w += 1
|
180
|
+
f[:s] = true
|
181
|
+
end
|
182
|
+
emit_n(e, w, f)
|
183
|
+
end
|
184
|
+
|
185
|
+
def emit_z(e, w, f) # :nodoc:
|
186
|
+
w += 1
|
187
|
+
f[:s] = true
|
188
|
+
emit_n(e, w, f)
|
189
|
+
end
|
190
|
+
|
191
|
+
def emit_a(e, w, f) # :nodoc:
|
192
|
+
f[:p] ||= "\s"
|
193
|
+
emit_w(e, w, f)
|
194
|
+
end
|
195
|
+
|
196
|
+
def emit_ad(e, w, f) # :nodoc:
|
197
|
+
if f[:x]
|
198
|
+
f[:u] = true
|
199
|
+
f[:d] = false
|
200
|
+
end
|
201
|
+
emit_a(e, w, f)
|
202
|
+
end
|
203
|
+
|
204
|
+
def emit_au(e, w, f) # :nodoc:
|
205
|
+
if f[:x]
|
206
|
+
f[:u] = false
|
207
|
+
f[:d] = true
|
208
|
+
end
|
209
|
+
emit_a(e, w, f)
|
210
|
+
end
|
211
|
+
|
212
|
+
private :emit, :emit_w, :emit_n, :emit_sn, :emit_z,
|
213
|
+
:emit_a, :emit_ad, :emit_au
|
214
|
+
|
215
|
+
def strftime(fmt='%F')
|
216
|
+
fmt.gsub(/%([-_0^#]+)?(\d+)?([EO]?(?::{1,3}z|.))/m) do
|
217
|
+
f = {}
|
218
|
+
m = $&
|
219
|
+
s, w, c = $1, $2, $3
|
220
|
+
if s
|
221
|
+
s.scan(/./) do |k|
|
222
|
+
case k
|
223
|
+
when '-'; f[:p] = '-'
|
224
|
+
when '_'; f[:p] = "\s"
|
225
|
+
when '0'; f[:p] = '0'
|
226
|
+
when '^'; f[:u] = true
|
227
|
+
when '#'; f[:x] = true
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
if w
|
232
|
+
f[:w] = w.to_i
|
233
|
+
end
|
234
|
+
case c
|
235
|
+
when 'A'; emit_ad(DAYNAMES[wday], 0, f)
|
236
|
+
when 'a'; emit_ad(ABBR_DAYNAMES[wday], 0, f)
|
237
|
+
when 'B'; emit_ad(MONTHNAMES[mon], 0, f)
|
238
|
+
when 'b'; emit_ad(ABBR_MONTHNAMES[mon], 0, f)
|
239
|
+
when 'C', 'EC'; emit_sn((year / 100).floor, 2, f)
|
240
|
+
when 'c', 'Ec'; emit_a(strftime('%a %b %e %H:%M:%S %Y'), 0, f)
|
241
|
+
when 'D'; emit_a(strftime('%m/%d/%y'), 0, f)
|
242
|
+
when 'd', 'Od'; emit_n(mday, 2, f)
|
243
|
+
when 'e', 'Oe'; emit_a(mday, 2, f)
|
244
|
+
when 'F'
|
245
|
+
if m == '%F'
|
246
|
+
format('%.4d-%02d-%02d', year, mon, mday) # 4p
|
247
|
+
else
|
248
|
+
emit_a(strftime('%Y-%m-%d'), 0, f)
|
249
|
+
end
|
250
|
+
when 'G'; emit_sn(cwyear, 4, f)
|
251
|
+
when 'g'; emit_n(cwyear % 100, 2, f)
|
252
|
+
when 'H', 'OH'; emit_n(hour, 2, f)
|
253
|
+
when 'h'; emit_ad(strftime('%b'), 0, f)
|
254
|
+
when 'I', 'OI'; emit_n((hour % 12).nonzero? || 12, 2, f)
|
255
|
+
when 'j'; emit_n(yday, 3, f)
|
256
|
+
when 'k'; emit_a(hour, 2, f)
|
257
|
+
when 'L'
|
258
|
+
f[:p] = nil
|
259
|
+
w = f[:w] || 3
|
260
|
+
u = 10**w
|
261
|
+
emit_n((sec_fraction * u).floor, w, f)
|
262
|
+
when 'l'; emit_a((hour % 12).nonzero? || 12, 2, f)
|
263
|
+
when 'M', 'OM'; emit_n(min, 2, f)
|
264
|
+
when 'm', 'Om'; emit_n(mon, 2, f)
|
265
|
+
when 'N'
|
266
|
+
f[:p] = nil
|
267
|
+
w = f[:w] || 9
|
268
|
+
u = 10**w
|
269
|
+
emit_n((sec_fraction * u).floor, w, f)
|
270
|
+
when 'n'; emit_a("\n", 0, f)
|
271
|
+
when 'P'; emit_ad(strftime('%p').downcase, 0, f)
|
272
|
+
when 'p'; emit_au(if hour < 12 then 'AM' else 'PM' end, 0, f)
|
273
|
+
when 'Q'
|
274
|
+
s = ((ajd - UNIX_EPOCH_IN_AJD) / MILLISECONDS_IN_DAY).round
|
275
|
+
emit_sn(s, 1, f)
|
276
|
+
when 'R'; emit_a(strftime('%H:%M'), 0, f)
|
277
|
+
when 'r'; emit_a(strftime('%I:%M:%S %p'), 0, f)
|
278
|
+
when 'S', 'OS'; emit_n(sec, 2, f)
|
279
|
+
when 's'
|
280
|
+
s = ((ajd - UNIX_EPOCH_IN_AJD) / SECONDS_IN_DAY).round
|
281
|
+
emit_sn(s, 1, f)
|
282
|
+
when 'T'
|
283
|
+
if m == '%T'
|
284
|
+
format('%02d:%02d:%02d', hour, min, sec) # 4p
|
285
|
+
else
|
286
|
+
emit_a(strftime('%H:%M:%S'), 0, f)
|
287
|
+
end
|
288
|
+
when 't'; emit_a("\t", 0, f)
|
289
|
+
when 'U', 'W', 'OU', 'OW'
|
290
|
+
emit_n(if c[-1,1] == 'U' then wnum0 else wnum1 end, 2, f)
|
291
|
+
when 'u', 'Ou'; emit_n(cwday, 1, f)
|
292
|
+
when 'V', 'OV'; emit_n(cweek, 2, f)
|
293
|
+
when 'v'; emit_a(strftime('%e-%b-%Y'), 0, f)
|
294
|
+
when 'w', 'Ow'; emit_n(wday, 1, f)
|
295
|
+
when 'X', 'EX'; emit_a(strftime('%H:%M:%S'), 0, f)
|
296
|
+
when 'x', 'Ex'; emit_a(strftime('%m/%d/%y'), 0, f)
|
297
|
+
when 'Y', 'EY'; emit_sn(year, 4, f)
|
298
|
+
when 'y', 'Ey', 'Oy'; emit_n(year % 100, 2, f)
|
299
|
+
when 'Z'; emit_au(strftime('%:z'), 0, f)
|
300
|
+
when /\A(:{0,3})z/
|
301
|
+
t = $1.size
|
302
|
+
sign = if offset < 0 then -1 else +1 end
|
303
|
+
fr = offset.abs
|
304
|
+
ss = fr.div(SECONDS_IN_DAY) # 4p
|
305
|
+
hh, ss = ss.divmod(3600)
|
306
|
+
mm, ss = ss.divmod(60)
|
307
|
+
if t == 3
|
308
|
+
if ss.nonzero? then t = 2
|
309
|
+
elsif mm.nonzero? then t = 1
|
310
|
+
else t = -1
|
311
|
+
end
|
312
|
+
end
|
313
|
+
case t
|
314
|
+
when -1
|
315
|
+
tail = []
|
316
|
+
sep = ''
|
317
|
+
when 0
|
318
|
+
f[:w] -= 2 if f[:w]
|
319
|
+
tail = ['%02d' % mm]
|
320
|
+
sep = ''
|
321
|
+
when 1
|
322
|
+
f[:w] -= 3 if f[:w]
|
323
|
+
tail = ['%02d' % mm]
|
324
|
+
sep = ':'
|
325
|
+
when 2
|
326
|
+
f[:w] -= 6 if f[:w]
|
327
|
+
tail = ['%02d' % mm, '%02d' % ss]
|
328
|
+
sep = ':'
|
329
|
+
end
|
330
|
+
([emit_z(sign * hh, 2, f)] + tail).join(sep)
|
331
|
+
when '%'; emit_a('%', 0, f)
|
332
|
+
when '+'; emit_a(strftime('%a %b %e %H:%M:%S %Z %Y'), 0, f)
|
333
|
+
else
|
334
|
+
m
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
# alias_method :format, :strftime
|
340
|
+
|
341
|
+
def asctime() strftime('%c') end
|
342
|
+
|
343
|
+
alias_method :ctime, :asctime
|
344
|
+
|
345
|
+
def iso8601() strftime('%F') end
|
346
|
+
|
347
|
+
def rfc3339() iso8601 end
|
348
|
+
|
349
|
+
def xmlschema() iso8601 end # :nodoc:
|
350
|
+
|
351
|
+
def rfc2822() strftime('%a, %-d %b %Y %T %z') end
|
352
|
+
|
353
|
+
alias_method :rfc822, :rfc2822
|
354
|
+
|
355
|
+
def httpdate() new_offset(0).strftime('%a, %d %b %Y %T GMT') end # :nodoc:
|
356
|
+
|
357
|
+
def jisx0301
|
358
|
+
if jd < 2405160
|
359
|
+
iso8601
|
360
|
+
else
|
361
|
+
case jd
|
362
|
+
when 2405160...2419614
|
363
|
+
g = 'M%02d' % (year - 1867)
|
364
|
+
when 2419614...2424875
|
365
|
+
g = 'T%02d' % (year - 1911)
|
366
|
+
when 2424875...2447535
|
367
|
+
g = 'S%02d' % (year - 1925)
|
368
|
+
else
|
369
|
+
g = 'H%02d' % (year - 1988)
|
370
|
+
end
|
371
|
+
g + strftime('.%m.%d')
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
=begin
|
376
|
+
def beat(n=0)
|
377
|
+
i, f = (new_offset(HOURS_IN_DAY).day_fraction * 1000).divmod(1)
|
378
|
+
('@%03d' % i) +
|
379
|
+
if n < 1
|
380
|
+
''
|
381
|
+
else
|
382
|
+
'.%0*d' % [n, (f / Rational(1, 10**n)).round]
|
383
|
+
end
|
384
|
+
end
|
385
|
+
=end
|
386
|
+
|
387
|
+
def self.num_pattern? (s) # :nodoc:
|
388
|
+
/\A%[EO]?[CDdeFGgHIjkLlMmNQRrSsTUuVvWwXxYy\d]/ =~ s || /\A\d/ =~ s
|
389
|
+
end
|
390
|
+
|
391
|
+
private_class_method :num_pattern?
|
392
|
+
|
393
|
+
def self._strptime_i(str, fmt, e) # :nodoc:
|
394
|
+
fmt.scan(/%([EO]?(?::{1,3}z|.))|(.)/m) do |s, c|
|
395
|
+
a = $&
|
396
|
+
if s
|
397
|
+
case s
|
398
|
+
when 'A', 'a'
|
399
|
+
return unless str.sub!(/\A(#{Format::DAYS.keys.join('|')})/io, '') ||
|
400
|
+
str.sub!(/\A(#{Format::ABBR_DAYS.keys.join('|')})/io, '')
|
401
|
+
val = Format::DAYS[$1.downcase] || Format::ABBR_DAYS[$1.downcase]
|
402
|
+
return unless val
|
403
|
+
e.wday = val
|
404
|
+
when 'B', 'b', 'h'
|
405
|
+
return unless str.sub!(/\A(#{Format::MONTHS.keys.join('|')})/io, '') ||
|
406
|
+
str.sub!(/\A(#{Format::ABBR_MONTHS.keys.join('|')})/io, '')
|
407
|
+
val = Format::MONTHS[$1.downcase] || Format::ABBR_MONTHS[$1.downcase]
|
408
|
+
return unless val
|
409
|
+
e.mon = val
|
410
|
+
when 'C', 'EC'
|
411
|
+
return unless str.sub!(if num_pattern?($')
|
412
|
+
then /\A([-+]?\d{1,2})/
|
413
|
+
else /\A([-+]?\d{1,})/
|
414
|
+
end, '')
|
415
|
+
val = $1.to_i
|
416
|
+
e._cent = val
|
417
|
+
when 'c', 'Ec'
|
418
|
+
return unless _strptime_i(str, '%a %b %e %H:%M:%S %Y', e)
|
419
|
+
when 'D'
|
420
|
+
return unless _strptime_i(str, '%m/%d/%y', e)
|
421
|
+
when 'd', 'e', 'Od', 'Oe'
|
422
|
+
return unless str.sub!(/\A( \d|\d{1,2})/, '')
|
423
|
+
val = $1.to_i
|
424
|
+
return unless (1..31) === val
|
425
|
+
e.mday = val
|
426
|
+
when 'F'
|
427
|
+
return unless _strptime_i(str, '%Y-%m-%d', e)
|
428
|
+
when 'G'
|
429
|
+
return unless str.sub!(if num_pattern?($')
|
430
|
+
then /\A([-+]?\d{1,4})/
|
431
|
+
else /\A([-+]?\d{1,})/
|
432
|
+
end, '')
|
433
|
+
val = $1.to_i
|
434
|
+
e.cwyear = val
|
435
|
+
when 'g'
|
436
|
+
return unless str.sub!(/\A(\d{1,2})/, '')
|
437
|
+
val = $1.to_i
|
438
|
+
return unless (0..99) === val
|
439
|
+
e.cwyear = val
|
440
|
+
e._cent ||= if val >= 69 then 19 else 20 end
|
441
|
+
when 'H', 'k', 'OH'
|
442
|
+
return unless str.sub!(/\A( \d|\d{1,2})/, '')
|
443
|
+
val = $1.to_i
|
444
|
+
return unless (0..24) === val
|
445
|
+
e.hour = val
|
446
|
+
when 'I', 'l', 'OI'
|
447
|
+
return unless str.sub!(/\A( \d|\d{1,2})/, '')
|
448
|
+
val = $1.to_i
|
449
|
+
return unless (1..12) === val
|
450
|
+
e.hour = val
|
451
|
+
when 'j'
|
452
|
+
return unless str.sub!(/\A(\d{1,3})/, '')
|
453
|
+
val = $1.to_i
|
454
|
+
return unless (1..366) === val
|
455
|
+
e.yday = val
|
456
|
+
when 'L'
|
457
|
+
return unless str.sub!(if num_pattern?($')
|
458
|
+
then /\A([-+]?\d{1,3})/
|
459
|
+
else /\A([-+]?\d{1,})/
|
460
|
+
end, '')
|
461
|
+
# val = Rational($1.to_i, 10**3)
|
462
|
+
val = Rational($1.to_i, 10**$1.size)
|
463
|
+
e.sec_fraction = val
|
464
|
+
when 'M', 'OM'
|
465
|
+
return unless str.sub!(/\A(\d{1,2})/, '')
|
466
|
+
val = $1.to_i
|
467
|
+
return unless (0..59) === val
|
468
|
+
e.min = val
|
469
|
+
when 'm', 'Om'
|
470
|
+
return unless str.sub!(/\A(\d{1,2})/, '')
|
471
|
+
val = $1.to_i
|
472
|
+
return unless (1..12) === val
|
473
|
+
e.mon = val
|
474
|
+
when 'N'
|
475
|
+
return unless str.sub!(if num_pattern?($')
|
476
|
+
then /\A([-+]?\d{1,9})/
|
477
|
+
else /\A([-+]?\d{1,})/
|
478
|
+
end, '')
|
479
|
+
# val = Rational($1.to_i, 10**9)
|
480
|
+
val = Rational($1.to_i, 10**$1.size)
|
481
|
+
e.sec_fraction = val
|
482
|
+
when 'n', 't'
|
483
|
+
return unless _strptime_i(str, "\s", e)
|
484
|
+
when 'P', 'p'
|
485
|
+
return unless str.sub!(/\A([ap])(?:m\b|\.m\.)/i, '')
|
486
|
+
e._merid = if $1.downcase == 'a' then 0 else 12 end
|
487
|
+
when 'Q'
|
488
|
+
return unless str.sub!(/\A(-?\d{1,})/, '')
|
489
|
+
val = Rational($1.to_i, 10**3)
|
490
|
+
e.seconds = val
|
491
|
+
when 'R'
|
492
|
+
return unless _strptime_i(str, '%H:%M', e)
|
493
|
+
when 'r'
|
494
|
+
return unless _strptime_i(str, '%I:%M:%S %p', e)
|
495
|
+
when 'S', 'OS'
|
496
|
+
return unless str.sub!(/\A(\d{1,2})/, '')
|
497
|
+
val = $1.to_i
|
498
|
+
return unless (0..60) === val
|
499
|
+
e.sec = val
|
500
|
+
when 's'
|
501
|
+
return unless str.sub!(/\A(-?\d{1,})/, '')
|
502
|
+
val = $1.to_i
|
503
|
+
e.seconds = val
|
504
|
+
when 'T'
|
505
|
+
return unless _strptime_i(str, '%H:%M:%S', e)
|
506
|
+
when 'U', 'W', 'OU', 'OW'
|
507
|
+
return unless str.sub!(/\A(\d{1,2})/, '')
|
508
|
+
val = $1.to_i
|
509
|
+
return unless (0..53) === val
|
510
|
+
e.__send__(if s[-1,1] == 'U' then :wnum0= else :wnum1= end, val)
|
511
|
+
when 'u', 'Ou'
|
512
|
+
return unless str.sub!(/\A(\d{1})/, '')
|
513
|
+
val = $1.to_i
|
514
|
+
return unless (1..7) === val
|
515
|
+
e.cwday = val
|
516
|
+
when 'V', 'OV'
|
517
|
+
return unless str.sub!(/\A(\d{1,2})/, '')
|
518
|
+
val = $1.to_i
|
519
|
+
return unless (1..53) === val
|
520
|
+
e.cweek = val
|
521
|
+
when 'v'
|
522
|
+
return unless _strptime_i(str, '%e-%b-%Y', e)
|
523
|
+
when 'w'
|
524
|
+
return unless str.sub!(/\A(\d{1})/, '')
|
525
|
+
val = $1.to_i
|
526
|
+
return unless (0..6) === val
|
527
|
+
e.wday = val
|
528
|
+
when 'X', 'EX'
|
529
|
+
return unless _strptime_i(str, '%H:%M:%S', e)
|
530
|
+
when 'x', 'Ex'
|
531
|
+
return unless _strptime_i(str, '%m/%d/%y', e)
|
532
|
+
when 'Y', 'EY'
|
533
|
+
return unless str.sub!(if num_pattern?($')
|
534
|
+
then /\A([-+]?\d{1,4})/
|
535
|
+
else /\A([-+]?\d{1,})/
|
536
|
+
end, '')
|
537
|
+
val = $1.to_i
|
538
|
+
e.year = val
|
539
|
+
when 'y', 'Ey', 'Oy'
|
540
|
+
return unless str.sub!(/\A(\d{1,2})/, '')
|
541
|
+
val = $1.to_i
|
542
|
+
return unless (0..99) === val
|
543
|
+
e.year = val
|
544
|
+
e._cent ||= if val >= 69 then 19 else 20 end
|
545
|
+
when 'Z', /\A:{0,3}z/
|
546
|
+
return unless str.sub!(/\A((?:gmt|utc?)?[-+]\d+(?:[,.:]\d+(?::\d+)?)?
|
547
|
+
|[[:alpha:].\s]+(?:standard|daylight)\s+time\b
|
548
|
+
|[[:alpha:]]+(?:\s+dst)?\b
|
549
|
+
)/ix, '')
|
550
|
+
val = $1
|
551
|
+
e.zone = val
|
552
|
+
offset = zone_to_diff(val)
|
553
|
+
e.offset = offset
|
554
|
+
when '%'
|
555
|
+
return unless str.sub!(/\A%/, '')
|
556
|
+
when '+'
|
557
|
+
return unless _strptime_i(str, '%a %b %e %H:%M:%S %Z %Y', e)
|
558
|
+
else
|
559
|
+
return unless str.sub!(Regexp.new('\\A' + Regexp.quote(a)), '')
|
560
|
+
end
|
561
|
+
else
|
562
|
+
case c
|
563
|
+
when /\A\s/
|
564
|
+
str.sub!(/\A\s+/, '')
|
565
|
+
else
|
566
|
+
return unless str.sub!(Regexp.new('\\A' + Regexp.quote(a)), '')
|
567
|
+
end
|
568
|
+
end
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
572
|
+
private_class_method :_strptime_i
|
573
|
+
|
574
|
+
def self._strptime(str, fmt='%F')
|
575
|
+
str = str.dup
|
576
|
+
e = Format::Bag.new
|
577
|
+
return unless _strptime_i(str, fmt, e)
|
578
|
+
|
579
|
+
if e._cent
|
580
|
+
if e.cwyear
|
581
|
+
e.cwyear += e._cent * 100
|
582
|
+
end
|
583
|
+
if e.year
|
584
|
+
e. year += e._cent * 100
|
585
|
+
end
|
586
|
+
end
|
587
|
+
|
588
|
+
if e._merid
|
589
|
+
if e.hour
|
590
|
+
e.hour %= 12
|
591
|
+
e.hour += e._merid
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
595
|
+
unless str.empty?
|
596
|
+
e.leftover = str
|
597
|
+
end
|
598
|
+
|
599
|
+
e.to_hash
|
600
|
+
end
|
601
|
+
|
602
|
+
def self.s3e(e, y, m, d, bc=false)
|
603
|
+
unless String === m
|
604
|
+
m = m.to_s
|
605
|
+
end
|
606
|
+
|
607
|
+
if y && m && !d
|
608
|
+
y, m, d = d, y, m
|
609
|
+
end
|
610
|
+
|
611
|
+
if y == nil
|
612
|
+
if d && d.size > 2
|
613
|
+
y = d
|
614
|
+
d = nil
|
615
|
+
end
|
616
|
+
if d && d[0,1] == "'"
|
617
|
+
y = d
|
618
|
+
d = nil
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
622
|
+
if y
|
623
|
+
y.scan(/(\d+)(.+)?/)
|
624
|
+
if $2
|
625
|
+
y, d = d, $1
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
629
|
+
if m
|
630
|
+
if m[0,1] == "'" || m.size > 2
|
631
|
+
y, m, d = m, d, y # us -> be
|
632
|
+
end
|
633
|
+
end
|
634
|
+
|
635
|
+
if d
|
636
|
+
if d[0,1] == "'" || d.size > 2
|
637
|
+
y, d = d, y
|
638
|
+
end
|
639
|
+
end
|
640
|
+
|
641
|
+
if y
|
642
|
+
y =~ /([-+])?(\d+)/
|
643
|
+
if $1 || $2.size > 2
|
644
|
+
c = false
|
645
|
+
end
|
646
|
+
iy = $&.to_i
|
647
|
+
if bc
|
648
|
+
iy = -iy + 1
|
649
|
+
end
|
650
|
+
e.year = iy
|
651
|
+
end
|
652
|
+
|
653
|
+
if m
|
654
|
+
m =~ /\d+/
|
655
|
+
e.mon = $&.to_i
|
656
|
+
end
|
657
|
+
|
658
|
+
if d
|
659
|
+
d =~ /\d+/
|
660
|
+
e.mday = $&.to_i
|
661
|
+
end
|
662
|
+
|
663
|
+
if c != nil
|
664
|
+
e._comp = c
|
665
|
+
end
|
666
|
+
|
667
|
+
end
|
668
|
+
|
669
|
+
private_class_method :s3e
|
670
|
+
|
671
|
+
def self._parse_day(str, e) # :nodoc:
|
672
|
+
if str.sub!(/\b(#{Format::ABBR_DAYS.keys.join('|')})[^-\d\s]*/io, ' ')
|
673
|
+
e.wday = Format::ABBR_DAYS[$1.downcase]
|
674
|
+
true
|
675
|
+
=begin
|
676
|
+
elsif str.sub!(/\b(?!\dth)(su|mo|tu|we|th|fr|sa)\b/i, ' ')
|
677
|
+
e.wday = %w(su mo tu we th fr sa).index($1.downcase)
|
678
|
+
true
|
679
|
+
=end
|
680
|
+
end
|
681
|
+
end
|
682
|
+
|
683
|
+
def self._parse_time(str, e) # :nodoc:
|
684
|
+
if str.sub!(
|
685
|
+
/(
|
686
|
+
(?:
|
687
|
+
\d+\s*:\s*\d+
|
688
|
+
(?:
|
689
|
+
\s*:\s*\d+(?:[,.]\d*)?
|
690
|
+
)?
|
691
|
+
|
|
692
|
+
\d+\s*h(?:\s*\d+m?(?:\s*\d+s?)?)?
|
693
|
+
)
|
694
|
+
(?:
|
695
|
+
\s*
|
696
|
+
[ap](?:m\b|\.m\.)
|
697
|
+
)?
|
698
|
+
|
|
699
|
+
\d+\s*[ap](?:m\b|\.m\.)
|
700
|
+
)
|
701
|
+
(?:
|
702
|
+
\s*
|
703
|
+
(
|
704
|
+
(?:gmt|utc?)?[-+]\d+(?:[,.:]\d+(?::\d+)?)?
|
705
|
+
|
|
706
|
+
[[:alpha:].\s]+(?:standard|daylight)\stime\b
|
707
|
+
|
|
708
|
+
[[:alpha:]]+(?:\sdst)?\b
|
709
|
+
)
|
710
|
+
)?
|
711
|
+
/ix,
|
712
|
+
' ')
|
713
|
+
|
714
|
+
t = $1
|
715
|
+
e.zone = $2 if $2
|
716
|
+
|
717
|
+
t =~ /\A(\d+)h?
|
718
|
+
(?:\s*:?\s*(\d+)m?
|
719
|
+
(?:
|
720
|
+
\s*:?\s*(\d+)(?:[,.](\d+))?s?
|
721
|
+
)?
|
722
|
+
)?
|
723
|
+
(?:\s*([ap])(?:m\b|\.m\.))?/ix
|
724
|
+
|
725
|
+
e.hour = $1.to_i
|
726
|
+
e.min = $2.to_i if $2
|
727
|
+
e.sec = $3.to_i if $3
|
728
|
+
e.sec_fraction = Rational($4.to_i, 10**$4.size) if $4
|
729
|
+
|
730
|
+
if $5
|
731
|
+
e.hour %= 12
|
732
|
+
if $5.downcase == 'p'
|
733
|
+
e.hour += 12
|
734
|
+
end
|
735
|
+
end
|
736
|
+
true
|
737
|
+
end
|
738
|
+
end
|
739
|
+
|
740
|
+
=begin
|
741
|
+
def self._parse_beat(str, e) # :nodoc:
|
742
|
+
if str.sub!(/@\s*(\d+)(?:[,.](\d*))?/, ' ')
|
743
|
+
beat = Rational($1.to_i)
|
744
|
+
beat += Rational($2.to_i, 10**$2.size) if $2
|
745
|
+
secs = Rational(beat, 1000)
|
746
|
+
h, min, s, fr = self.day_fraction_to_time(secs)
|
747
|
+
e.hour = h
|
748
|
+
e.min = min
|
749
|
+
e.sec = s
|
750
|
+
e.sec_fraction = fr * 86400
|
751
|
+
e.zone = '+01:00'
|
752
|
+
true
|
753
|
+
end
|
754
|
+
end
|
755
|
+
=end
|
756
|
+
|
757
|
+
def self._parse_eu(str, e) # :nodoc:
|
758
|
+
if str.sub!(
|
759
|
+
/'?(\d+)[^-\d\s]*
|
760
|
+
\s*
|
761
|
+
(#{Format::ABBR_MONTHS.keys.join('|')})[^-\d\s']*
|
762
|
+
(?:
|
763
|
+
\s*
|
764
|
+
(c(?:e|\.e\.)|b(?:ce|\.c\.e\.)|a(?:d|\.d\.)|b(?:c|\.c\.))?
|
765
|
+
\s*
|
766
|
+
('?-?\d+(?:(?:st|nd|rd|th)\b)?)
|
767
|
+
)?
|
768
|
+
/iox,
|
769
|
+
' ') # '
|
770
|
+
s3e(e, $4, Format::ABBR_MONTHS[$2.downcase], $1,
|
771
|
+
$3 && $3[0,1].downcase == 'b')
|
772
|
+
true
|
773
|
+
end
|
774
|
+
end
|
775
|
+
|
776
|
+
def self._parse_us(str, e) # :nodoc:
|
777
|
+
if str.sub!(
|
778
|
+
/\b(#{Format::ABBR_MONTHS.keys.join('|')})[^-\d\s']*
|
779
|
+
\s*
|
780
|
+
('?\d+)[^-\d\s']*
|
781
|
+
(?:
|
782
|
+
\s*
|
783
|
+
(c(?:e|\.e\.)|b(?:ce|\.c\.e\.)|a(?:d|\.d\.)|b(?:c|\.c\.))?
|
784
|
+
\s*
|
785
|
+
('?-?\d+)
|
786
|
+
)?
|
787
|
+
/iox,
|
788
|
+
' ') # '
|
789
|
+
s3e(e, $4, Format::ABBR_MONTHS[$1.downcase], $2,
|
790
|
+
$3 && $3[0,1].downcase == 'b')
|
791
|
+
true
|
792
|
+
end
|
793
|
+
end
|
794
|
+
|
795
|
+
def self._parse_iso(str, e) # :nodoc:
|
796
|
+
if str.sub!(/('?[-+]?\d+)-(\d+)-('?-?\d+)/, ' ')
|
797
|
+
s3e(e, $1, $2, $3)
|
798
|
+
true
|
799
|
+
end
|
800
|
+
end
|
801
|
+
|
802
|
+
def self._parse_iso2(str, e) # :nodoc:
|
803
|
+
if str.sub!(/\b(\d{2}|\d{4})?-?w(\d{2})(?:-?(\d))?\b/i, ' ')
|
804
|
+
e.cwyear = $1.to_i if $1
|
805
|
+
e.cweek = $2.to_i
|
806
|
+
e.cwday = $3.to_i if $3
|
807
|
+
true
|
808
|
+
elsif str.sub!(/-w-(\d)\b/i, ' ')
|
809
|
+
e.cwday = $1.to_i
|
810
|
+
true
|
811
|
+
elsif str.sub!(/--(\d{2})?-(\d{2})\b/, ' ')
|
812
|
+
e.mon = $1.to_i if $1
|
813
|
+
e.mday = $2.to_i
|
814
|
+
true
|
815
|
+
elsif str.sub!(/--(\d{2})(\d{2})?\b/, ' ')
|
816
|
+
e.mon = $1.to_i
|
817
|
+
e.mday = $2.to_i if $2
|
818
|
+
true
|
819
|
+
elsif /[,.](\d{2}|\d{4})-\d{3}\b/ !~ str &&
|
820
|
+
str.sub!(/\b(\d{2}|\d{4})-(\d{3})\b/, ' ')
|
821
|
+
e.year = $1.to_i
|
822
|
+
e.yday = $2.to_i
|
823
|
+
true
|
824
|
+
elsif /\d-\d{3}\b/ !~ str &&
|
825
|
+
str.sub!(/\b-(\d{3})\b/, ' ')
|
826
|
+
e.yday = $1.to_i
|
827
|
+
true
|
828
|
+
end
|
829
|
+
end
|
830
|
+
|
831
|
+
def self._parse_jis(str, e) # :nodoc:
|
832
|
+
if str.sub!(/\b([mtsh])(\d+)\.(\d+)\.(\d+)/i, ' ')
|
833
|
+
era = { 'm'=>1867,
|
834
|
+
't'=>1911,
|
835
|
+
's'=>1925,
|
836
|
+
'h'=>1988
|
837
|
+
}[$1.downcase]
|
838
|
+
e.year = $2.to_i + era
|
839
|
+
e.mon = $3.to_i
|
840
|
+
e.mday = $4.to_i
|
841
|
+
true
|
842
|
+
end
|
843
|
+
end
|
844
|
+
|
845
|
+
def self._parse_vms(str, e) # :nodoc:
|
846
|
+
if str.sub!(/('?-?\d+)-(#{Format::ABBR_MONTHS.keys.join('|')})[^-]*
|
847
|
+
-('?-?\d+)/iox, ' ')
|
848
|
+
s3e(e, $3, Format::ABBR_MONTHS[$2.downcase], $1)
|
849
|
+
true
|
850
|
+
elsif str.sub!(/\b(#{Format::ABBR_MONTHS.keys.join('|')})[^-]*
|
851
|
+
-('?-?\d+)(?:-('?-?\d+))?/iox, ' ')
|
852
|
+
s3e(e, $3, Format::ABBR_MONTHS[$1.downcase], $2)
|
853
|
+
true
|
854
|
+
end
|
855
|
+
end
|
856
|
+
|
857
|
+
def self._parse_sla(str, e) # :nodoc:
|
858
|
+
if str.sub!(%r|('?-?\d+)/\s*('?\d+)(?:\D\s*('?-?\d+))?|, ' ') # '
|
859
|
+
s3e(e, $1, $2, $3)
|
860
|
+
true
|
861
|
+
end
|
862
|
+
end
|
863
|
+
|
864
|
+
def self._parse_dot(str, e) # :nodoc:
|
865
|
+
if str.sub!(%r|('?-?\d+)\.\s*('?\d+)\.\s*('?-?\d+)|, ' ') # '
|
866
|
+
s3e(e, $1, $2, $3)
|
867
|
+
true
|
868
|
+
end
|
869
|
+
end
|
870
|
+
|
871
|
+
def self._parse_year(str, e) # :nodoc:
|
872
|
+
if str.sub!(/'(\d+)\b/, ' ')
|
873
|
+
e.year = $1.to_i
|
874
|
+
true
|
875
|
+
end
|
876
|
+
end
|
877
|
+
|
878
|
+
def self._parse_mon(str, e) # :nodoc:
|
879
|
+
if str.sub!(/\b(#{Format::ABBR_MONTHS.keys.join('|')})\S*/io, ' ')
|
880
|
+
e.mon = Format::ABBR_MONTHS[$1.downcase]
|
881
|
+
true
|
882
|
+
end
|
883
|
+
end
|
884
|
+
|
885
|
+
def self._parse_mday(str, e) # :nodoc:
|
886
|
+
if str.sub!(/(\d+)(st|nd|rd|th)\b/i, ' ')
|
887
|
+
e.mday = $1.to_i
|
888
|
+
true
|
889
|
+
end
|
890
|
+
end
|
891
|
+
|
892
|
+
def self._parse_ddd(str, e) # :nodoc:
|
893
|
+
if str.sub!(
|
894
|
+
/([-+]?)(\d{2,14})
|
895
|
+
(?:
|
896
|
+
\s*
|
897
|
+
t?
|
898
|
+
\s*
|
899
|
+
(\d{2,6})?(?:[,.](\d*))?
|
900
|
+
)?
|
901
|
+
(?:
|
902
|
+
\s*
|
903
|
+
(
|
904
|
+
z\b
|
905
|
+
|
|
906
|
+
[-+]\d{1,4}\b
|
907
|
+
|
|
908
|
+
\[[-+]?\d[^\]]*\]
|
909
|
+
)
|
910
|
+
)?
|
911
|
+
/ix,
|
912
|
+
' ')
|
913
|
+
case $2.size
|
914
|
+
when 2
|
915
|
+
if $3.nil? && $4
|
916
|
+
e.sec = $2[-2, 2].to_i
|
917
|
+
else
|
918
|
+
e.mday = $2[ 0, 2].to_i
|
919
|
+
end
|
920
|
+
when 4
|
921
|
+
if $3.nil? && $4
|
922
|
+
e.sec = $2[-2, 2].to_i
|
923
|
+
e.min = $2[-4, 2].to_i
|
924
|
+
else
|
925
|
+
e.mon = $2[ 0, 2].to_i
|
926
|
+
e.mday = $2[ 2, 2].to_i
|
927
|
+
end
|
928
|
+
when 6
|
929
|
+
if $3.nil? && $4
|
930
|
+
e.sec = $2[-2, 2].to_i
|
931
|
+
e.min = $2[-4, 2].to_i
|
932
|
+
e.hour = $2[-6, 2].to_i
|
933
|
+
else
|
934
|
+
e.year = ($1 + $2[ 0, 2]).to_i
|
935
|
+
e.mon = $2[ 2, 2].to_i
|
936
|
+
e.mday = $2[ 4, 2].to_i
|
937
|
+
end
|
938
|
+
when 8, 10, 12, 14
|
939
|
+
if $3.nil? && $4
|
940
|
+
e.sec = $2[-2, 2].to_i
|
941
|
+
e.min = $2[-4, 2].to_i
|
942
|
+
e.hour = $2[-6, 2].to_i
|
943
|
+
e.mday = $2[-8, 2].to_i
|
944
|
+
if $2.size >= 10
|
945
|
+
e.mon = $2[-10, 2].to_i
|
946
|
+
end
|
947
|
+
if $2.size == 12
|
948
|
+
e.year = ($1 + $2[-12, 2]).to_i
|
949
|
+
end
|
950
|
+
if $2.size == 14
|
951
|
+
e.year = ($1 + $2[-14, 4]).to_i
|
952
|
+
e._comp = false
|
953
|
+
end
|
954
|
+
else
|
955
|
+
e.year = ($1 + $2[ 0, 4]).to_i
|
956
|
+
e.mon = $2[ 4, 2].to_i
|
957
|
+
e.mday = $2[ 6, 2].to_i
|
958
|
+
e.hour = $2[ 8, 2].to_i if $2.size >= 10
|
959
|
+
e.min = $2[10, 2].to_i if $2.size >= 12
|
960
|
+
e.sec = $2[12, 2].to_i if $2.size >= 14
|
961
|
+
e._comp = false
|
962
|
+
end
|
963
|
+
when 3
|
964
|
+
if $3.nil? && $4
|
965
|
+
e.sec = $2[-2, 2].to_i
|
966
|
+
e.min = $2[-3, 1].to_i
|
967
|
+
else
|
968
|
+
e.yday = $2[ 0, 3].to_i
|
969
|
+
end
|
970
|
+
when 5
|
971
|
+
if $3.nil? && $4
|
972
|
+
e.sec = $2[-2, 2].to_i
|
973
|
+
e.min = $2[-4, 2].to_i
|
974
|
+
e.hour = $2[-5, 1].to_i
|
975
|
+
else
|
976
|
+
e.year = ($1 + $2[ 0, 2]).to_i
|
977
|
+
e.yday = $2[ 2, 3].to_i
|
978
|
+
end
|
979
|
+
when 7
|
980
|
+
if $3.nil? && $4
|
981
|
+
e.sec = $2[-2, 2].to_i
|
982
|
+
e.min = $2[-4, 2].to_i
|
983
|
+
e.hour = $2[-6, 2].to_i
|
984
|
+
e.mday = $2[-7, 1].to_i
|
985
|
+
else
|
986
|
+
e.year = ($1 + $2[ 0, 4]).to_i
|
987
|
+
e.yday = $2[ 4, 3].to_i
|
988
|
+
end
|
989
|
+
end
|
990
|
+
if $3
|
991
|
+
if $4
|
992
|
+
case $3.size
|
993
|
+
when 2, 4, 6
|
994
|
+
e.sec = $3[-2, 2].to_i
|
995
|
+
e.min = $3[-4, 2].to_i if $3.size >= 4
|
996
|
+
e.hour = $3[-6, 2].to_i if $3.size >= 6
|
997
|
+
end
|
998
|
+
else
|
999
|
+
case $3.size
|
1000
|
+
when 2, 4, 6
|
1001
|
+
e.hour = $3[ 0, 2].to_i
|
1002
|
+
e.min = $3[ 2, 2].to_i if $3.size >= 4
|
1003
|
+
e.sec = $3[ 4, 2].to_i if $3.size >= 6
|
1004
|
+
end
|
1005
|
+
end
|
1006
|
+
end
|
1007
|
+
if $4
|
1008
|
+
e.sec_fraction = Rational($4.to_i, 10**$4.size)
|
1009
|
+
end
|
1010
|
+
if $5
|
1011
|
+
e.zone = $5
|
1012
|
+
if e.zone[0,1] == '['
|
1013
|
+
o, n, = e.zone[1..-2].split(':')
|
1014
|
+
e.zone = n || o
|
1015
|
+
if /\A\d/ =~ o
|
1016
|
+
o = format('+%s', o)
|
1017
|
+
end
|
1018
|
+
e.offset = zone_to_diff(o)
|
1019
|
+
end
|
1020
|
+
end
|
1021
|
+
true
|
1022
|
+
end
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
private_class_method :_parse_day, :_parse_time, # :_parse_beat,
|
1026
|
+
:_parse_eu, :_parse_us, :_parse_iso, :_parse_iso2,
|
1027
|
+
:_parse_jis, :_parse_vms, :_parse_sla, :_parse_dot,
|
1028
|
+
:_parse_year, :_parse_mon, :_parse_mday, :_parse_ddd
|
1029
|
+
|
1030
|
+
def self._parse(str, comp=true)
|
1031
|
+
str = str.dup
|
1032
|
+
|
1033
|
+
e = Format::Bag.new
|
1034
|
+
|
1035
|
+
e._comp = comp
|
1036
|
+
|
1037
|
+
str.gsub!(/[^-+',.\/:@[:alnum:]\[\]]+/, ' ')
|
1038
|
+
|
1039
|
+
_parse_time(str, e) # || _parse_beat(str, e)
|
1040
|
+
_parse_day(str, e)
|
1041
|
+
|
1042
|
+
_parse_eu(str, e) ||
|
1043
|
+
_parse_us(str, e) ||
|
1044
|
+
_parse_iso(str, e) ||
|
1045
|
+
_parse_jis(str, e) ||
|
1046
|
+
_parse_vms(str, e) ||
|
1047
|
+
_parse_sla(str, e) ||
|
1048
|
+
_parse_dot(str, e) ||
|
1049
|
+
_parse_iso2(str, e) ||
|
1050
|
+
_parse_year(str, e) ||
|
1051
|
+
_parse_mon(str, e) ||
|
1052
|
+
_parse_mday(str, e) ||
|
1053
|
+
_parse_ddd(str, e)
|
1054
|
+
|
1055
|
+
if str.sub!(/\b(bc\b|bce\b|b\.c\.|b\.c\.e\.)/i, ' ')
|
1056
|
+
if e.year
|
1057
|
+
e.year = -e.year + 1
|
1058
|
+
end
|
1059
|
+
end
|
1060
|
+
|
1061
|
+
if str.sub!(/\A\s*(\d{1,2})\s*\z/, ' ')
|
1062
|
+
if e.hour && !e.mday
|
1063
|
+
v = $1.to_i
|
1064
|
+
if (1..31) === v
|
1065
|
+
e.mday = v
|
1066
|
+
end
|
1067
|
+
end
|
1068
|
+
if e.mday && !e.hour
|
1069
|
+
v = $1.to_i
|
1070
|
+
if (0..24) === v
|
1071
|
+
e.hour = v
|
1072
|
+
end
|
1073
|
+
end
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
if e._comp
|
1077
|
+
if e.cwyear
|
1078
|
+
if e.cwyear >= 0 && e.cwyear <= 99
|
1079
|
+
e.cwyear += if e.cwyear >= 69
|
1080
|
+
then 1900 else 2000 end
|
1081
|
+
end
|
1082
|
+
end
|
1083
|
+
if e.year
|
1084
|
+
if e.year >= 0 && e.year <= 99
|
1085
|
+
e.year += if e.year >= 69
|
1086
|
+
then 1900 else 2000 end
|
1087
|
+
end
|
1088
|
+
end
|
1089
|
+
end
|
1090
|
+
|
1091
|
+
e.offset ||= zone_to_diff(e.zone) if e.zone
|
1092
|
+
|
1093
|
+
e.to_hash
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
def self._iso8601(str) # :nodoc:
|
1097
|
+
if /\A\s*(([-+]?\d{2,}|-)-\d{2}-\d{2}|
|
1098
|
+
([-+]?\d{2,})?-\d{3}|
|
1099
|
+
(\d{2}|\d{4})?-w\d{2}-\d|
|
1100
|
+
-w-\d)
|
1101
|
+
(t
|
1102
|
+
\d{2}:\d{2}(:\d{2}([,.]\d+)?)?
|
1103
|
+
(z|[-+]\d{2}(:?\d{2})?)?)?\s*\z/ix =~ str
|
1104
|
+
_parse(str)
|
1105
|
+
elsif /\A\s*(([-+]?(\d{2}|\d{4})|--)\d{2}\d{2}|
|
1106
|
+
([-+]?(\d{2}|\d{4}))?\d{3}|-\d{3}|
|
1107
|
+
(\d{2}|\d{4})?w\d{2}\d)
|
1108
|
+
(t?
|
1109
|
+
\d{2}\d{2}(\d{2}([,.]\d+)?)?
|
1110
|
+
(z|[-+]\d{2}(\d{2})?)?)?\s*\z/ix =~ str
|
1111
|
+
_parse(str)
|
1112
|
+
elsif /\A\s*(\d{2}:\d{2}(:\d{2}([,.]\d+)?)?
|
1113
|
+
(z|[-+]\d{2}(:?\d{2})?)?)?\s*\z/ix =~ str
|
1114
|
+
_parse(str)
|
1115
|
+
elsif /\A\s*(\d{2}\d{2}(\d{2}([,.]\d+)?)?
|
1116
|
+
(z|[-+]\d{2}(\d{2})?)?)?\s*\z/ix =~ str
|
1117
|
+
_parse(str)
|
1118
|
+
end
|
1119
|
+
end
|
1120
|
+
|
1121
|
+
def self._rfc3339(str) # :nodoc:
|
1122
|
+
if /\A\s*-?\d{4}-\d{2}-\d{2} # allow minus, anyway
|
1123
|
+
(t|\s)
|
1124
|
+
\d{2}:\d{2}:\d{2}(\.\d+)?
|
1125
|
+
(z|[-+]\d{2}:\d{2})\s*\z/ix =~ str
|
1126
|
+
_parse(str)
|
1127
|
+
end
|
1128
|
+
end
|
1129
|
+
|
1130
|
+
def self._xmlschema(str) # :nodoc:
|
1131
|
+
if /\A\s*(-?\d{4,})(?:-(\d{2})(?:-(\d{2}))?)?
|
1132
|
+
(?:t
|
1133
|
+
(\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?)?
|
1134
|
+
(z|[-+]\d{2}:\d{2})?\s*\z/ix =~ str
|
1135
|
+
e = Format::Bag.new
|
1136
|
+
e.year = $1.to_i
|
1137
|
+
e.mon = $2.to_i if $2
|
1138
|
+
e.mday = $3.to_i if $3
|
1139
|
+
e.hour = $4.to_i if $4
|
1140
|
+
e.min = $5.to_i if $5
|
1141
|
+
e.sec = $6.to_i if $6
|
1142
|
+
e.sec_fraction = Rational($7.to_i, 10**$7.size) if $7
|
1143
|
+
if $8
|
1144
|
+
e.zone = $8
|
1145
|
+
e.offset = zone_to_diff($8)
|
1146
|
+
end
|
1147
|
+
e.to_hash
|
1148
|
+
elsif /\A\s*(\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?
|
1149
|
+
(z|[-+]\d{2}:\d{2})?\s*\z/ix =~ str
|
1150
|
+
e = Format::Bag.new
|
1151
|
+
e.hour = $1.to_i if $1
|
1152
|
+
e.min = $2.to_i if $2
|
1153
|
+
e.sec = $3.to_i if $3
|
1154
|
+
e.sec_fraction = Rational($4.to_i, 10**$4.size) if $4
|
1155
|
+
if $5
|
1156
|
+
e.zone = $5
|
1157
|
+
e.offset = zone_to_diff($5)
|
1158
|
+
end
|
1159
|
+
e.to_hash
|
1160
|
+
elsif /\A\s*(?:--(\d{2})(?:-(\d{2}))?|---(\d{2}))
|
1161
|
+
(z|[-+]\d{2}:\d{2})?\s*\z/ix =~ str
|
1162
|
+
e = Format::Bag.new
|
1163
|
+
e.mon = $1.to_i if $1
|
1164
|
+
e.mday = $2.to_i if $2
|
1165
|
+
e.mday = $3.to_i if $3
|
1166
|
+
if $4
|
1167
|
+
e.zone = $4
|
1168
|
+
e.offset = zone_to_diff($4)
|
1169
|
+
end
|
1170
|
+
e.to_hash
|
1171
|
+
end
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
def self._rfc2822(str) # :nodoc:
|
1175
|
+
if /\A\s*(?:(?:#{Format::ABBR_DAYS.keys.join('|')})\s*,\s+)?
|
1176
|
+
\d{1,2}\s+
|
1177
|
+
(?:#{Format::ABBR_MONTHS.keys.join('|')})\s+
|
1178
|
+
-?(\d{2,})\s+ # allow minus, anyway
|
1179
|
+
\d{2}:\d{2}(:\d{2})?\s*
|
1180
|
+
(?:[-+]\d{4}|ut|gmt|e[sd]t|c[sd]t|m[sd]t|p[sd]t|[a-ik-z])\s*\z/iox =~ str
|
1181
|
+
e = _parse(str, false)
|
1182
|
+
if $1.size < 4
|
1183
|
+
if e[:year] < 50
|
1184
|
+
e[:year] += 2000
|
1185
|
+
elsif e[:year] < 1000
|
1186
|
+
e[:year] += 1900
|
1187
|
+
end
|
1188
|
+
end
|
1189
|
+
e
|
1190
|
+
end
|
1191
|
+
end
|
1192
|
+
|
1193
|
+
class << self; alias_method :_rfc822, :_rfc2822 end
|
1194
|
+
|
1195
|
+
def self._httpdate(str) # :nodoc:
|
1196
|
+
if /\A\s*(#{Format::ABBR_DAYS.keys.join('|')})\s*,\s+
|
1197
|
+
\d{2}\s+
|
1198
|
+
(#{Format::ABBR_MONTHS.keys.join('|')})\s+
|
1199
|
+
-?\d{4}\s+ # allow minus, anyway
|
1200
|
+
\d{2}:\d{2}:\d{2}\s+
|
1201
|
+
gmt\s*\z/iox =~ str
|
1202
|
+
_rfc2822(str)
|
1203
|
+
elsif /\A\s*(#{Format::DAYS.keys.join('|')})\s*,\s+
|
1204
|
+
\d{2}\s*-\s*
|
1205
|
+
(#{Format::ABBR_MONTHS.keys.join('|')})\s*-\s*
|
1206
|
+
\d{2}\s+
|
1207
|
+
\d{2}:\d{2}:\d{2}\s+
|
1208
|
+
gmt\s*\z/iox =~ str
|
1209
|
+
_parse(str)
|
1210
|
+
elsif /\A\s*(#{Format::ABBR_DAYS.keys.join('|')})\s+
|
1211
|
+
(#{Format::ABBR_MONTHS.keys.join('|')})\s+
|
1212
|
+
\d{1,2}\s+
|
1213
|
+
\d{2}:\d{2}:\d{2}\s+
|
1214
|
+
\d{4}\s*\z/iox =~ str
|
1215
|
+
_parse(str)
|
1216
|
+
end
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
def self._jisx0301(str) # :nodoc:
|
1220
|
+
if /\A\s*[mtsh]?\d{2}\.\d{2}\.\d{2}
|
1221
|
+
(t
|
1222
|
+
(\d{2}:\d{2}(:\d{2}([,.]\d*)?)?
|
1223
|
+
(z|[-+]\d{2}(:?\d{2})?)?)?)?\s*\z/ix =~ str
|
1224
|
+
if /\A\s*\d/ =~ str
|
1225
|
+
_parse(str.sub(/\A\s*(\d)/, 'h\1'))
|
1226
|
+
else
|
1227
|
+
_parse(str)
|
1228
|
+
end
|
1229
|
+
else
|
1230
|
+
_iso8601(str)
|
1231
|
+
end
|
1232
|
+
end
|
1233
|
+
|
1234
|
+
t = Module.new do
|
1235
|
+
|
1236
|
+
private
|
1237
|
+
|
1238
|
+
def zone_to_diff(zone) # :nodoc:
|
1239
|
+
zone = zone.downcase
|
1240
|
+
if zone.sub!(/\s+(standard|daylight)\s+time\z/, '')
|
1241
|
+
dst = $1 == 'daylight'
|
1242
|
+
else
|
1243
|
+
dst = zone.sub!(/\s+dst\z/, '')
|
1244
|
+
end
|
1245
|
+
if Format::ZONES.include?(zone)
|
1246
|
+
offset = Format::ZONES[zone]
|
1247
|
+
offset += 3600 if dst
|
1248
|
+
elsif zone.sub!(/\A(?:gmt|utc?)?([-+])/, '')
|
1249
|
+
sign = $1
|
1250
|
+
if zone.include?(':')
|
1251
|
+
hour, min, sec, = zone.split(':')
|
1252
|
+
elsif zone.include?(',') || zone.include?('.')
|
1253
|
+
hour, fr, = zone.split(/[,.]/)
|
1254
|
+
min = Rational(fr.to_i, 10**fr.size) * 60
|
1255
|
+
else
|
1256
|
+
case zone.size
|
1257
|
+
when 3
|
1258
|
+
hour = zone[0,1]
|
1259
|
+
min = zone[1,2]
|
1260
|
+
else
|
1261
|
+
hour = zone[0,2]
|
1262
|
+
min = zone[2,2]
|
1263
|
+
sec = zone[4,2]
|
1264
|
+
end
|
1265
|
+
end
|
1266
|
+
offset = hour.to_i * 3600 + min.to_i * 60 + sec.to_i
|
1267
|
+
offset *= -1 if sign == '-'
|
1268
|
+
end
|
1269
|
+
offset
|
1270
|
+
end
|
1271
|
+
|
1272
|
+
end
|
1273
|
+
|
1274
|
+
extend t
|
1275
|
+
include t
|
1276
|
+
|
1277
|
+
end
|
1278
|
+
|
1279
|
+
class DateTime < Date
|
1280
|
+
|
1281
|
+
def strftime(fmt='%FT%T%:z')
|
1282
|
+
super(fmt)
|
1283
|
+
end
|
1284
|
+
|
1285
|
+
def self._strptime(str, fmt='%FT%T%z')
|
1286
|
+
super(str, fmt)
|
1287
|
+
end
|
1288
|
+
|
1289
|
+
def iso8601_timediv(n) # :nodoc:
|
1290
|
+
strftime('T%T' +
|
1291
|
+
if n < 1
|
1292
|
+
''
|
1293
|
+
else
|
1294
|
+
'.%0*d' % [n, (sec_fraction / Rational(1, 10**n)).round]
|
1295
|
+
end +
|
1296
|
+
'%:z')
|
1297
|
+
end
|
1298
|
+
|
1299
|
+
private :iso8601_timediv
|
1300
|
+
|
1301
|
+
def iso8601(n=0)
|
1302
|
+
super() + iso8601_timediv(n)
|
1303
|
+
end
|
1304
|
+
|
1305
|
+
def rfc3339(n=0) iso8601(n) end
|
1306
|
+
|
1307
|
+
def xmlschema(n=0) iso8601(n) end # :nodoc:
|
1308
|
+
|
1309
|
+
def jisx0301(n=0)
|
1310
|
+
super() + iso8601_timediv(n)
|
1311
|
+
end
|
1312
|
+
|
1313
|
+
end
|