hijri 0.2.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8a57a98c55f59a921c16661f2dde825a5600d32d
4
- data.tar.gz: d1f368e87d525735c9e01afc3a4841e3ce2d1052
3
+ metadata.gz: 7d85b27d3b44ff6c7d07d0c694b00e0ff7aa8b9c
4
+ data.tar.gz: 82fb98fc862f70e0d04477e12f74a77408979500
5
5
  SHA512:
6
- metadata.gz: 6d9061ec1e355f146a8be9b1ca1b58a2fe6c111078929fcb88b5aecc7d9edbf9dcaf5453ba120b899c5bdab8107c8b9c516e8adceea22ce40980cf974bb9ef35
7
- data.tar.gz: 83e0d0511d673e93479a75520d9401f05aa5a6d6e3a7fb9911e508354e31aa8edf6b33e25438eeb59f31e9ea311bfb38e0fa55172e8480ab0824beaf8ea8401d
6
+ metadata.gz: cb74e3acfc640014bbd3499a74122f8b01d753fac32942015d4d3928f5dcde7133fdc8c34bfb6212c2fea76aa901b884f4132a80c1c1e2d735548925bfcc358f
7
+ data.tar.gz: 91fc784276f15e1a6b0e39adedf1830a15ee1fdf338a4cdd2337f747e52567eaea8d7440811d72a078ca88f3dc77a164f59286a7e0935aae1a4e12e3f2f99f70
@@ -6,8 +6,10 @@ rvm:
6
6
  - "1.9.3"
7
7
  - "2.0.0"
8
8
  - "2.1"
9
+ - "2.2.0"
9
10
  - jruby-18mode # JRuby in 1.8 mode
10
11
  - jruby-19mode # JRuby in 1.9 mode
11
12
  - rbx
13
+ - rbx-2
12
14
 
13
15
  sudo: false
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ === 0.4.0 / 2015-01-11
2
+
3
+ * Add Hijri::DateTime.to_s
4
+ * protect year, month and day in Hijri::Date.
5
+ * Implement Hijri::Date.strftime method.
6
+ * Add Hijri::Date.yday method
7
+ * Add Hijri::Date.wday method
8
+ * Add Hijri::Date.weeknum method
9
+
1
10
  === 0.2.5 / 2014-12-11
2
11
 
3
12
  * Add Comparable for Hijri::Date.
data/Gemfile CHANGED
@@ -2,6 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- if RUBY_VERSION < '1.8.8'
5
+ if %w(1.8.7 2.2.0).include? RUBY_VERSION
6
6
  gem 'minitest'
7
7
  end
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  #####Hijri Date library for Ruby.
7
7
  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.
8
- ### Hijri Calendar (from Wikipedia)
8
+ #### Hijri Calendar (from Wikipedia)
9
9
  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).
10
10
 
11
11
  http://en.wikipedia.org/wiki/Islamic_calendar
@@ -33,6 +33,7 @@ Or install it yourself as:
33
33
  - 1.9.3
34
34
  - 2.0.0
35
35
  - 2.1
36
+ - 2.2
36
37
  - JRuby 1.7.16.1
37
38
  - jruby-18mode
38
39
  - jruby-19mode
@@ -57,6 +58,9 @@ hijri.to_greo # => #<Date: 2009-01-01 ((2454833j,0s,0n),+0s,2299161j)>
57
58
 
58
59
  # and there is DateTime too
59
60
  date_and_time = Hijri::DateTime.now # => #<Hijri::DateTime:0x007f875e8eac00 @year=1436, @month=2, @day=16, @hour=14, @minute=14, @second=39, @zone="+03:00">
61
+
62
+ # hijri support strftime method with the same option as Greogian date format
63
+ Hijri::DateTime.now.strftime('%c') # => "Ahad Rabia I 20 16:00:25 1436"
60
64
  ```
61
65
 
62
66
 
@@ -67,7 +71,8 @@ date_and_time = Hijri::DateTime.now # => #<Hijri::DateTime:0x007f875e8eac00 @yea
67
71
  - [x] Add Hijri::DateTime.now to create Hijri::DateTime object.
68
72
  - [x] Add Hijri::Date.today to create Hijri::Date object with today date.
69
73
  - [x] Add Comparable for Hijri::Date.
70
- - [ ] Implement strftime method.
74
+ - [x] Implement strftime method.
75
+ - [ ] Add Hijri::Date.change method.
71
76
 
72
77
 
73
78
  ## Contributing
@@ -2,6 +2,8 @@ require 'date'
2
2
 
3
3
  module Hijri
4
4
  ISLAMIC_EPOCH = 227014
5
+ AVERAGE_YEARS_DAYS = 354.367056
6
+ AVERAGE_MONTH_DAYS = 29.530588
5
7
  end
6
8
 
7
9
  require 'hijri/version'
@@ -9,4 +11,4 @@ require 'hijri/date'
9
11
  require 'hijri/datetime'
10
12
  require 'hijri/gregorian'
11
13
  require 'hijri/converter'
12
-
14
+ require 'hijri/format'
@@ -3,9 +3,30 @@ module Hijri
3
3
 
4
4
  include Comparable
5
5
 
6
- attr_accessor :day, :month, :year
7
- MONTHNAMES_EN = %w(Muharram Safar Rabia-Awwal Rabia-Thani Jumaada-Awal Jumaada-Thani Rajab Sha'ban Ramadan Shawwal Dhul-Qi'dah Dhul-Hijjah)
6
+ attr_reader :day, :month, :year
7
+
8
+ # TODO change mon to month in format.rb.
9
+ alias :mon :month
10
+ alias :mday :day
11
+
12
+
13
+ MONTHNAMES = [nil] + %w(Muharram Safar Rabia-Awwal Rabia-Thani Jumaada-Awal Jumaada-Thani Rajab Sha'ban Ramadan Shawwal Dhul-Qi'dah Dhul-Hijjah)
8
14
  DAYNAMES = %w(as-Sabt al-Ahad al-Ithnayn ath-Thalaathaa al-Arba'aa' al-Khamis al-Jumu'ah)
15
+ ABBR_MONTHNAMES = [nil] + ["Muharram", "Safar", "Rabia I", "Rabia II", "Jumaada I", "Jumaada II", "Rajab", "Sha'ban", "Ramadan", "Shawwal", "Dhul-Qi'dah", "Dhul-Hijjah"]
16
+ ABBR_DAYNAMES = %w(Sabt Ahad Ithnayn Thalaathaa Arba'aa' Khamis Jumu'ah)
17
+
18
+ [MONTHNAMES, DAYNAMES, ABBR_MONTHNAMES, ABBR_DAYNAMES].each do |xs|
19
+ xs.each{|x| x.freeze unless x.nil?}.freeze
20
+ end
21
+
22
+ HALF_DAYS_IN_DAY = Rational(1, 2) # :nodoc:
23
+ HOURS_IN_DAY = Rational(1, 24) # :nodoc:
24
+ MINUTES_IN_DAY = Rational(1, 1440) # :nodoc:
25
+ SECONDS_IN_DAY = Rational(1, 86400) # :nodoc:
26
+ MILLISECONDS_IN_DAY = Rational(1, 86400*10**3) # :nodoc:
27
+ NANOSECONDS_IN_DAY = Rational(1, 86400*10**9) # :nodoc:
28
+ MILLISECONDS_IN_SECOND = Rational(1, 10**3) # :nodoc:
29
+ NANOSECONDS_IN_SECOND = Rational(1, 10**9) # :nodoc:
9
30
 
10
31
  class << self
11
32
  def today
@@ -51,6 +72,7 @@ module Hijri
51
72
 
52
73
  return (day + month_days + this_year + nonleap_year_days + leap_year_days + Hijri::ISLAMIC_EPOCH).to_i
53
74
  end
75
+ alias :abs :to_abs
54
76
 
55
77
  def to_greo
56
78
  ::Date.new *Converter.hijri_to_greo(self)
@@ -61,5 +83,22 @@ module Hijri
61
83
  self
62
84
  end
63
85
 
86
+ def yday
87
+ (((month - 1) * AVERAGE_MONTH_DAYS) + day).floor
88
+ end
89
+
90
+ def wday
91
+ (((year * AVERAGE_YEARS_DAYS) + yday) % 7).floor
92
+ end
93
+
94
+ def weeknum(week_start=0)
95
+ yday / 7
96
+ end
97
+ alias :cweek :weeknum
98
+
99
+ def wnum0() weeknum(0) end # :nodoc:
100
+ def wnum1() weeknum(1) end # :nodoc:
101
+
102
+ private :wnum0, :wnum1
64
103
  end
65
104
  end
@@ -1,12 +1,18 @@
1
1
  module Hijri
2
2
  class DateTime < Date
3
3
 
4
- attr_reader :hour, :minute, :second, :zone
4
+ attr_reader :hour, :minute, :second, :offset, :zone
5
+
6
+ alias :min :minute
7
+ alias :sec :second
8
+
9
+
5
10
  def initialize(year=1, month=1, day=1, hour=0, minute=0, second=0, zone="00:00")
6
11
  super(year, month, day)
7
12
  @hour = hour
8
13
  @minute = minute
9
14
  @second = second
15
+ @offset = zone.to_f / 24
10
16
  @zone = zone
11
17
  end
12
18
 
@@ -21,7 +27,10 @@ module Hijri
21
27
  ::DateTime.new *Converter.hijri_to_greo(self)
22
28
  end
23
29
 
24
- # TODO to_s
30
+ def to_s
31
+ zone_str = (@zone == '00:00' ? "+#{@zone}" : @zone)
32
+ "#{super}T#{sprintf('%02d', @hour)}:#{sprintf('%02d', @minute)}:#{sprintf('%02d', @second)}#{zone_str}"
33
+ end
25
34
 
26
35
  class << self
27
36
  def now
@@ -1,235 +1,237 @@
1
1
  # format.rb: Written by Tadayoshi Funaba 1999-2009
2
2
  # $Id: format.rb,v 2.43 2008-01-17 20:16:31+09 tadf Exp $
3
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
4
+ # I stole this code from ruby date.
5
+ module Hijri
6
+ class Date
7
+
8
+ module Format # :nodoc:
9
+
10
+ MONTHS = {
11
+ 'Muharram' => 1, 'Safar' => 2, 'Rabia-Awwal' => 3, 'Rabia-Thani' => 4,
12
+ 'Jumaada-Awal' => 5, 'Jumaada-Thani' => 6, 'Rajab' => 7, "Sha'ban" => 8,
13
+ 'Ramadan'=> 9, 'Shawwal' => 10, "Dhul-Qi'dah" => 11, 'Dhul-Hijjah' => 12
14
+ }
15
+
16
+ DAYS = {
17
+ 'al-Ahad' => 0, 'al-Ithnayn' => 1, 'ath-Thalaathaa' => 2, "al-Arba'aa'"=> 3,
18
+ 'al-Khamis' => 4, "al-Jumu'ah" => 5, 'as-Sabt' => 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
111
113
 
112
- class Bag # :nodoc:
114
+ class Bag # :nodoc:
113
115
 
114
- def initialize
115
- @elem = {}
116
- end
116
+ def initialize
117
+ @elem = {}
118
+ end
117
119
 
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
120
+ def method_missing(t, *args, &block)
121
+ t = t.to_s
122
+ set = t.chomp!('=')
123
+ t = t.intern
124
+ if set
125
+ @elem[t] = args[0]
126
+ else
127
+ @elem[t]
128
+ end
129
+ end
130
+
131
+ def to_hash
132
+ @elem.reject{|k, v| /\A_/ =~ k.to_s || v.nil?}
133
+ end
128
134
 
129
- def to_hash
130
- @elem.reject{|k, v| /\A_/ =~ k.to_s || v.nil?}
131
135
  end
132
136
 
133
137
  end
134
138
 
135
- end
139
+ def emit(e, f) # :nodoc:
140
+ case e
141
+ when Numeric
142
+ sign = %w(+ + -)[e <=> 0]
143
+ e = e.abs
144
+ end
136
145
 
137
- def emit(e, f) # :nodoc:
138
- case e
139
- when Numeric
140
- sign = %w(+ + -)[e <=> 0]
141
- e = e.abs
142
- end
146
+ s = e.to_s
143
147
 
144
- s = e.to_s
148
+ if f[:s] && f[:p] == '0'
149
+ f[:w] -= 1
150
+ end
145
151
 
146
- if f[:s] && f[:p] == '0'
147
- f[:w] -= 1
148
- end
152
+ if f[:s] && f[:p] == "\s"
153
+ s[0,0] = sign
154
+ end
149
155
 
150
- if f[:s] && f[:p] == "\s"
151
- s[0,0] = sign
152
- end
156
+ if f[:p] != '-'
157
+ s = s.rjust(f[:w], f[:p])
158
+ end
153
159
 
154
- if f[:p] != '-'
155
- s = s.rjust(f[:w], f[:p])
156
- end
160
+ if f[:s] && f[:p] != "\s"
161
+ s[0,0] = sign
162
+ end
157
163
 
158
- if f[:s] && f[:p] != "\s"
159
- s[0,0] = sign
164
+ s = s.upcase if f[:u]
165
+ s = s.downcase if f[:d]
166
+ s
160
167
  end
161
168
 
162
- s = s.upcase if f[:u]
163
- s = s.downcase if f[:d]
164
- s
165
- end
169
+ def emit_w(e, w, f) # :nodoc:
170
+ f[:w] = [f[:w], w].compact.max
171
+ emit(e, f)
172
+ end
166
173
 
167
- def emit_w(e, w, f) # :nodoc:
168
- f[:w] = [f[:w], w].compact.max
169
- emit(e, f)
170
- end
174
+ def emit_n(e, w, f) # :nodoc:
175
+ f[:p] ||= '0'
176
+ emit_w(e, w, f)
177
+ end
171
178
 
172
- def emit_n(e, w, f) # :nodoc:
173
- f[:p] ||= '0'
174
- emit_w(e, w, f)
175
- end
179
+ def emit_sn(e, w, f) # :nodoc:
180
+ if e < 0
181
+ w += 1
182
+ f[:s] = true
183
+ end
184
+ emit_n(e, w, f)
185
+ end
176
186
 
177
- def emit_sn(e, w, f) # :nodoc:
178
- if e < 0
187
+ def emit_z(e, w, f) # :nodoc:
179
188
  w += 1
180
189
  f[:s] = true
190
+ emit_n(e, w, f)
181
191
  end
182
- emit_n(e, w, f)
183
- end
184
192
 
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
193
+ def emit_a(e, w, f) # :nodoc:
194
+ f[:p] ||= "\s"
195
+ emit_w(e, w, f)
196
+ end
195
197
 
196
- def emit_ad(e, w, f) # :nodoc:
197
- if f[:x]
198
- f[:u] = true
199
- f[:d] = false
198
+ def emit_ad(e, w, f) # :nodoc:
199
+ if f[:x]
200
+ f[:u] = true
201
+ f[:d] = false
202
+ end
203
+ emit_a(e, w, f)
200
204
  end
201
- emit_a(e, w, f)
202
- end
203
205
 
204
- def emit_au(e, w, f) # :nodoc:
205
- if f[:x]
206
- f[:u] = false
207
- f[:d] = true
206
+ def emit_au(e, w, f) # :nodoc:
207
+ if f[:x]
208
+ f[:u] = false
209
+ f[:d] = true
210
+ end
211
+ emit_a(e, w, f)
208
212
  end
209
- emit_a(e, w, f)
210
- end
211
213
 
212
- private :emit, :emit_w, :emit_n, :emit_sn, :emit_z,
213
- :emit_a, :emit_ad, :emit_au
214
+ private :emit, :emit_w, :emit_n, :emit_sn, :emit_z,
215
+ :emit_a, :emit_ad, :emit_au
214
216
 
215
- def strftime(fmt='%F')
216
- fmt.gsub(/%([-_0^#]+)?(\d+)?([EO]?(?::{1,3}z|.))/m) do
217
+ def strftime(fmt='%F')
218
+ fmt.gsub(/%([-_0^#]+)?(\d+)?([EO]?(?::{1,3}z|.))/m) do
217
219
  f = {}
218
220
  m = $&
219
221
  s, w, c = $1, $2, $3
220
222
  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
223
+ s.scan(/./) do |k|
224
+ case k
225
+ when '-'; f[:p] = '-'
226
+ when '_'; f[:p] = "\s"
227
+ when '0'; f[:p] = '0'
228
+ when '^'; f[:u] = true
229
+ when '#'; f[:x] = true
230
+ end
231
+ end
230
232
  end
231
233
  if w
232
- f[:w] = w.to_i
234
+ f[:w] = w.to_i
233
235
  end
234
236
  case c
235
237
  when 'A'; emit_ad(DAYNAMES[wday], 0, f)
@@ -242,11 +244,11 @@ class Date
242
244
  when 'd', 'Od'; emit_n(mday, 2, f)
243
245
  when 'e', 'Oe'; emit_a(mday, 2, f)
244
246
  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
247
+ if m == '%F'
248
+ format('%.4d-%02d-%02d', year, mon, mday) # 4p
249
+ else
250
+ emit_a(strftime('%Y-%m-%d'), 0, f)
251
+ end
250
252
  when 'G'; emit_sn(cwyear, 4, f)
251
253
  when 'g'; emit_n(cwyear % 100, 2, f)
252
254
  when 'H', 'OH'; emit_n(hour, 2, f)
@@ -255,1059 +257,1054 @@ class Date
255
257
  when 'j'; emit_n(yday, 3, f)
256
258
  when 'k'; emit_a(hour, 2, f)
257
259
  when 'L'
258
- f[:p] = nil
259
- w = f[:w] || 3
260
- u = 10**w
261
- emit_n((sec_fraction * u).floor, w, f)
260
+ f[:p] = nil
261
+ w = f[:w] || 3
262
+ u = 10**w
263
+ emit_n((sec_fraction * u).floor, w, f)
262
264
  when 'l'; emit_a((hour % 12).nonzero? || 12, 2, f)
263
265
  when 'M', 'OM'; emit_n(min, 2, f)
264
266
  when 'm', 'Om'; emit_n(mon, 2, f)
265
267
  when 'N'
266
- f[:p] = nil
267
- w = f[:w] || 9
268
- u = 10**w
269
- emit_n((sec_fraction * u).floor, w, f)
268
+ f[:p] = nil
269
+ w = f[:w] || 9
270
+ u = 10**w
271
+ emit_n((sec_fraction * u).floor, w, f)
270
272
  when 'n'; emit_a("\n", 0, f)
271
273
  when 'P'; emit_ad(strftime('%p').downcase, 0, f)
272
274
  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)
275
+ when 'Q'
276
+ s = ((ajd - UNIX_EPOCH_IN_AJD) / MILLISECONDS_IN_DAY).round
277
+ emit_sn(s, 1, f)
278
+ when 'R'; emit_a(strftime('%H:%M'), 0, f)
279
+ when 'r'; emit_a(strftime('%I:%M:%S %p'), 0, f)
280
+ when 'S', 'OS'; emit_n(sec, 2, f)
281
+ when 's'
282
+ s = ((ajd - UNIX_EPOCH_IN_AJD) / SECONDS_IN_DAY).round
283
+ emit_sn(s, 1, f)
284
+ when 'T'
285
+ if m == '%T'
286
+ format('%02d:%02d:%02d', hour, min, sec) # 4p
287
+ else
288
+ emit_a(strftime('%H:%M:%S'), 0, f)
289
+ end
290
+ when 't'; emit_a("\t", 0, f)
291
+ when 'U', 'W', 'OU', 'OW'
292
+ emit_n(if c[-1,1] == 'U' then wnum0 else wnum1 end, 2, f)
293
+ when 'u', 'Ou'; emit_n(cwday, 1, f)
294
+ when 'V', 'OV'; emit_n(cweek, 2, f)
295
+ when 'v'; emit_a(strftime('%e-%b-%Y'), 0, f)
296
+ when 'w', 'Ow'; emit_n(wday, 1, f)
297
+ when 'X', 'EX'; emit_a(strftime('%H:%M:%S'), 0, f)
298
+ when 'x', 'Ex'; emit_a(strftime('%m/%d/%y'), 0, f)
299
+ when 'Y', 'EY'; emit_sn(year, 4, f)
300
+ when 'y', 'Ey', 'Oy'; emit_n(year % 100, 2, f)
301
+ when 'Z'; emit_au(strftime('%:z'), 0, f)
302
+ when /\A(:{0,3})z/
303
+ t = $1.size
304
+ sign = if offset < 0 then -1 else +1 end
305
+ fr = offset.abs
306
+ ss = fr.div(SECONDS_IN_DAY) # 4p
307
+ hh, ss = ss.divmod(3600)
308
+ mm, ss = ss.divmod(60)
309
+ if t == 3
310
+ if ss.nonzero? then t = 2
311
+ elsif mm.nonzero? then t = 1
312
+ else t = -1
313
+ end
314
+ end
315
+ case t
316
+ when -1
317
+ tail = []
318
+ sep = ''
319
+ when 0
320
+ f[:w] -= 2 if f[:w]
321
+ tail = ['%02d' % mm]
322
+ sep = ''
323
+ when 1
324
+ f[:w] -= 3 if f[:w]
325
+ tail = ['%02d' % mm]
326
+ sep = ':'
327
+ when 2
328
+ f[:w] -= 6 if f[:w]
329
+ tail = ['%02d' % mm, '%02d' % ss]
330
+ sep = ':'
331
+ end
332
+ ([emit_z(sign * hh, 2, f)] + tail).join(sep)
331
333
  when '%'; emit_a('%', 0, f)
332
334
  when '+'; emit_a(strftime('%a %b %e %H:%M:%S %Z %Y'), 0, f)
333
335
  else
334
- m
336
+ m
335
337
  end
336
338
  end
337
339
  end
338
340
 
339
- # alias_method :format, :strftime
341
+ # alias_method :format, :strftime
340
342
 
341
- def asctime() strftime('%c') end
343
+ def asctime() strftime('%c') end
342
344
 
343
- alias_method :ctime, :asctime
345
+ alias_method :ctime, :asctime
344
346
 
345
- def iso8601() strftime('%F') end
347
+ def iso8601() strftime('%F') end
346
348
 
347
- def rfc3339() iso8601 end
349
+ def rfc3339() iso8601 end
348
350
 
349
- def xmlschema() iso8601 end # :nodoc:
351
+ def xmlschema() iso8601 end # :nodoc:
350
352
 
351
- def rfc2822() strftime('%a, %-d %b %Y %T %z') end
353
+ def rfc2822() strftime('%a, %-d %b %Y %T %z') end
352
354
 
353
- alias_method :rfc822, :rfc2822
355
+ alias_method :rfc822, :rfc2822
354
356
 
355
- def httpdate() new_offset(0).strftime('%a, %d %b %Y %T GMT') end # :nodoc:
357
+ def httpdate() new_offset(0).strftime('%a, %d %b %Y %T GMT') end # :nodoc:
356
358
 
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)
359
+ def jisx0301
360
+ if jd < 2405160
361
+ iso8601
368
362
  else
369
- g = 'H%02d' % (year - 1988)
363
+ case jd
364
+ when 2405160...2419614
365
+ g = 'M%02d' % (year - 1867)
366
+ when 2419614...2424875
367
+ g = 'T%02d' % (year - 1911)
368
+ when 2424875...2447535
369
+ g = 'S%02d' % (year - 1925)
370
+ else
371
+ g = 'H%02d' % (year - 1988)
372
+ end
373
+ g + strftime('.%m.%d')
370
374
  end
371
- g + strftime('.%m.%d')
372
375
  end
373
- end
374
376
 
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?
377
+ # def beat(n=0)
378
+ # i, f = (new_offset(HOURS_IN_DAY).day_fraction * 1000).divmod(1)
379
+ # ('@%03d' % i) +
380
+ # if n < 1
381
+ # ''
382
+ # else
383
+ # '.%0*d' % [n, (f / Rational(1, 10**n)).round]
384
+ # end
385
+ # end
386
+
387
+ def self.num_pattern? (s) # :nodoc:
388
+ /\A%[EO]?[CDdeFGgHIjkLlMmNQRrSsTUuVvWwXxYy\d]/ =~ s || /\A\d/ =~ s
389
+ end
392
390
 
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
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
568
569
  end
569
570
  end
570
- end
571
571
 
572
- private_class_method :_strptime_i
572
+ private_class_method :_strptime_i
573
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
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
585
586
  end
586
- end
587
587
 
588
- if e._merid
589
- if e.hour
590
- e.hour %= 12
591
- e.hour += e._merid
588
+ if e._merid
589
+ if e.hour
590
+ e.hour %= 12
591
+ e.hour += e._merid
592
+ end
592
593
  end
593
- end
594
-
595
- unless str.empty?
596
- e.leftover = str
597
- end
598
594
 
599
- e.to_hash
600
- end
595
+ unless str.empty?
596
+ e.leftover = str
597
+ end
601
598
 
602
- def self.s3e(e, y, m, d, bc=false)
603
- unless String === m
604
- m = m.to_s
599
+ e.to_hash
605
600
  end
606
601
 
607
- if y && m && !d
608
- y, m, d = d, y, m
609
- end
602
+ def self.s3e(e, y, m, d, bc=false)
603
+ unless String === m
604
+ m = m.to_s
605
+ end
610
606
 
611
- if y == nil
612
- if d && d.size > 2
613
- y = d
614
- d = nil
607
+ if y && m && !d
608
+ y, m, d = d, y, m
615
609
  end
616
- if d && d[0,1] == "'"
617
- y = d
618
- d = nil
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
619
620
  end
620
- end
621
621
 
622
- if y
623
- y.scan(/(\d+)(.+)?/)
624
- if $2
625
- y, d = d, $1
622
+ if y
623
+ y.scan(/(\d+)(.+)?/)
624
+ if $2
625
+ y, d = d, $1
626
+ end
626
627
  end
627
- end
628
628
 
629
- if m
630
- if m[0,1] == "'" || m.size > 2
631
- y, m, d = m, d, y # us -> be
629
+ if m
630
+ if m[0,1] == "'" || m.size > 2
631
+ y, m, d = m, d, y # us -> be
632
+ end
632
633
  end
633
- end
634
634
 
635
- if d
636
- if d[0,1] == "'" || d.size > 2
637
- y, d = d, y
635
+ if d
636
+ if d[0,1] == "'" || d.size > 2
637
+ y, d = d, y
638
+ end
638
639
  end
639
- end
640
640
 
641
- if y
642
- y =~ /([-+])?(\d+)/
643
- if $1 || $2.size > 2
644
- c = false
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
645
651
  end
646
- iy = $&.to_i
647
- if bc
648
- iy = -iy + 1
652
+
653
+ if m
654
+ m =~ /\d+/
655
+ e.mon = $&.to_i
649
656
  end
650
- e.year = iy
651
- end
652
657
 
653
- if m
654
- m =~ /\d+/
655
- e.mon = $&.to_i
656
- end
658
+ if d
659
+ d =~ /\d+/
660
+ e.mday = $&.to_i
661
+ end
657
662
 
658
- if d
659
- d =~ /\d+/
660
- e.mday = $&.to_i
661
- end
663
+ if c != nil
664
+ e._comp = c
665
+ end
662
666
 
663
- if c != nil
664
- e._comp = c
665
667
  end
666
668
 
667
- end
669
+ private_class_method :s3e
668
670
 
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
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
+ # elsif str.sub!(/\b(?!\dth)(su|mo|tu|we|th|fr|sa)\b/i, ' ')
676
+ # e.wday = %w(su mo tu we th fr sa).index($1.downcase)
677
+ # true
678
+ end
680
679
  end
681
- end
682
680
 
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
681
+ def self._parse_time(str, e) # :nodoc:
682
+ if str.sub!(
683
+ /(
684
+ (?:
685
+ \d+\s*:\s*\d+
686
+ (?:
687
+ \s*:\s*\d+(?:[,.]\d*)?
688
+ )?
689
+ |
690
+ \d+\s*h(?:\s*\d+m?(?:\s*\d+s?)?)?
691
+ )
692
+ (?:
693
+ \s*
694
+ [ap](?:m\b|\.m\.)
695
+ )?
696
+ |
697
+ \d+\s*[ap](?:m\b|\.m\.)
698
+ )
699
+ (?:
700
+ \s*
701
+ (
702
+ (?:gmt|utc?)?[-+]\d+(?:[,.:]\d+(?::\d+)?)?
703
+ |
704
+ [[:alpha:].\s]+(?:standard|daylight)\stime\b
705
+ |
706
+ [[:alpha:]]+(?:\sdst)?\b
707
+ )
708
+ )?
709
+ /ix,
710
+ ' ')
711
+
712
+ t = $1
713
+ e.zone = $2 if $2
714
+
715
+ t =~ /\A(\d+)h?
716
+ (?:\s*:?\s*(\d+)m?
717
+ (?:
718
+ \s*:?\s*(\d+)(?:[,.](\d+))?s?
719
+ )?
720
+ )?
721
+ (?:\s*([ap])(?:m\b|\.m\.))?/ix
722
+
723
+ e.hour = $1.to_i
724
+ e.min = $2.to_i if $2
725
+ e.sec = $3.to_i if $3
726
+ e.sec_fraction = Rational($4.to_i, 10**$4.size) if $4
727
+
728
+ if $5
729
+ e.hour %= 12
730
+ if $5.downcase == 'p'
731
+ e.hour += 12
732
+ end
733
+ end
734
+ true
735
735
  end
736
- true
737
736
  end
738
- end
739
737
 
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
738
+ # def self._parse_beat(str, e) # :nodoc:
739
+ # if str.sub!(/@\s*(\d+)(?:[,.](\d*))?/, ' ')
740
+ # beat = Rational($1.to_i)
741
+ # beat += Rational($2.to_i, 10**$2.size) if $2
742
+ # secs = Rational(beat, 1000)
743
+ # h, min, s, fr = self.day_fraction_to_time(secs)
744
+ # e.hour = h
745
+ # e.min = min
746
+ # e.sec = s
747
+ # e.sec_fraction = fr * 86400
748
+ # e.zone = '+01:00'
749
+ # true
750
+ # end
751
+ # end
752
+
753
+ def self._parse_eu(str, e) # :nodoc:
754
+ if str.sub!(
755
+ /'?(\d+)[^-\d\s]*
756
+ \s*
757
+ (#{Format::ABBR_MONTHS.keys.join('|')})[^-\d\s']*
758
+ (?:
759
+ \s*
760
+ (c(?:e|\.e\.)|b(?:ce|\.c\.e\.)|a(?:d|\.d\.)|b(?:c|\.c\.))?
761
+ \s*
762
+ ('?-?\d+(?:(?:st|nd|rd|th)\b)?)
763
+ )?
764
+ /iox,
765
+ ' ') # '
766
+ s3e(e, $4, Format::ABBR_MONTHS[$2.downcase], $1,
767
+ $3 && $3[0,1].downcase == 'b')
768
+ true
769
+ end
773
770
  end
774
- end
775
771
 
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
772
+ def self._parse_us(str, e) # :nodoc:
773
+ if str.sub!(
774
+ /\b(#{Format::ABBR_MONTHS.keys.join('|')})[^-\d\s']*
775
+ \s*
776
+ ('?\d+)[^-\d\s']*
777
+ (?:
778
+ \s*
779
+ (c(?:e|\.e\.)|b(?:ce|\.c\.e\.)|a(?:d|\.d\.)|b(?:c|\.c\.))?
780
+ \s*
781
+ ('?-?\d+)
782
+ )?
783
+ /iox,
784
+ ' ') # '
785
+ s3e(e, $4, Format::ABBR_MONTHS[$1.downcase], $2,
786
+ $3 && $3[0,1].downcase == 'b')
787
+ true
788
+ end
792
789
  end
793
- end
794
790
 
795
- def self._parse_iso(str, e) # :nodoc:
796
- if str.sub!(/('?[-+]?\d+)-(\d+)-('?-?\d+)/, ' ')
797
- s3e(e, $1, $2, $3)
798
- true
791
+ def self._parse_iso(str, e) # :nodoc:
792
+ if str.sub!(/('?[-+]?\d+)-(\d+)-('?-?\d+)/, ' ')
793
+ s3e(e, $1, $2, $3)
794
+ true
795
+ end
799
796
  end
800
- end
801
797
 
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
798
+ def self._parse_iso2(str, e) # :nodoc:
799
+ if str.sub!(/\b(\d{2}|\d{4})?-?w(\d{2})(?:-?(\d))?\b/i, ' ')
800
+ e.cwyear = $1.to_i if $1
801
+ e.cweek = $2.to_i
802
+ e.cwday = $3.to_i if $3
803
+ true
804
+ elsif str.sub!(/-w-(\d)\b/i, ' ')
805
+ e.cwday = $1.to_i
806
+ true
807
+ elsif str.sub!(/--(\d{2})?-(\d{2})\b/, ' ')
808
+ e.mon = $1.to_i if $1
809
+ e.mday = $2.to_i
810
+ true
811
+ elsif str.sub!(/--(\d{2})(\d{2})?\b/, ' ')
812
+ e.mon = $1.to_i
813
+ e.mday = $2.to_i if $2
814
+ true
815
+ elsif /[,.](\d{2}|\d{4})-\d{3}\b/ !~ str &&
816
+ str.sub!(/\b(\d{2}|\d{4})-(\d{3})\b/, ' ')
817
+ e.year = $1.to_i
818
+ e.yday = $2.to_i
819
+ true
820
+ elsif /\d-\d{3}\b/ !~ str &&
821
+ str.sub!(/\b-(\d{3})\b/, ' ')
822
+ e.yday = $1.to_i
823
+ true
824
+ end
828
825
  end
829
- end
830
826
 
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
827
+ def self._parse_jis(str, e) # :nodoc:
828
+ if str.sub!(/\b([mtsh])(\d+)\.(\d+)\.(\d+)/i, ' ')
829
+ era = { 'm'=>1867,
830
+ 't'=>1911,
831
+ 's'=>1925,
832
+ 'h'=>1988
833
+ }[$1.downcase]
834
+ e.year = $2.to_i + era
835
+ e.mon = $3.to_i
836
+ e.mday = $4.to_i
837
+ true
838
+ end
842
839
  end
843
- end
844
840
 
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
841
+ def self._parse_vms(str, e) # :nodoc:
842
+ if str.sub!(/('?-?\d+)-(#{Format::ABBR_MONTHS.keys.join('|')})[^-]*
843
+ -('?-?\d+)/iox, ' ')
844
+ s3e(e, $3, Format::ABBR_MONTHS[$2.downcase], $1)
845
+ true
846
+ elsif str.sub!(/\b(#{Format::ABBR_MONTHS.keys.join('|')})[^-]*
847
+ -('?-?\d+)(?:-('?-?\d+))?/iox, ' ')
848
+ s3e(e, $3, Format::ABBR_MONTHS[$1.downcase], $2)
849
+ true
850
+ end
854
851
  end
855
- end
856
852
 
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
853
+ def self._parse_sla(str, e) # :nodoc:
854
+ if str.sub!(%r|('?-?\d+)/\s*('?\d+)(?:\D\s*('?-?\d+))?|, ' ') # '
855
+ s3e(e, $1, $2, $3)
856
+ true
857
+ end
861
858
  end
862
- end
863
859
 
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
860
+ def self._parse_dot(str, e) # :nodoc:
861
+ if str.sub!(%r|('?-?\d+)\.\s*('?\d+)\.\s*('?-?\d+)|, ' ') # '
862
+ s3e(e, $1, $2, $3)
863
+ true
864
+ end
868
865
  end
869
- end
870
866
 
871
- def self._parse_year(str, e) # :nodoc:
872
- if str.sub!(/'(\d+)\b/, ' ')
873
- e.year = $1.to_i
874
- true
867
+ def self._parse_year(str, e) # :nodoc:
868
+ if str.sub!(/'(\d+)\b/, ' ')
869
+ e.year = $1.to_i
870
+ true
871
+ end
875
872
  end
876
- end
877
873
 
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
874
+ def self._parse_mon(str, e) # :nodoc:
875
+ if str.sub!(/\b(#{Format::ABBR_MONTHS.keys.join('|')})\S*/io, ' ')
876
+ e.mon = Format::ABBR_MONTHS[$1.downcase]
877
+ true
878
+ end
882
879
  end
883
- end
884
880
 
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
881
+ def self._parse_mday(str, e) # :nodoc:
882
+ if str.sub!(/(\d+)(st|nd|rd|th)\b/i, ' ')
883
+ e.mday = $1.to_i
884
+ true
885
+ end
889
886
  end
890
- end
891
887
 
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)
888
+ def self._parse_ddd(str, e) # :nodoc:
889
+ if str.sub!(
890
+ /([-+]?)(\d{2,14})
891
+ (?:
892
+ \s*
893
+ t?
894
+ \s*
895
+ (\d{2,6})?(?:[,.](\d*))?
896
+ )?
897
+ (?:
898
+ \s*
899
+ (
900
+ z\b
901
+ |
902
+ [-+]\d{1,4}\b
903
+ |
904
+ \[[-+]?\d[^\]]*\]
905
+ )
906
+ )?
907
+ /ix,
908
+ ' ')
909
+ case $2.size
910
+ when 2
911
+ if $3.nil? && $4
912
+ e.sec = $2[-2, 2].to_i
913
+ else
914
+ e.mday = $2[ 0, 2].to_i
915
+ end
916
+ when 4
917
+ if $3.nil? && $4
918
+ e.sec = $2[-2, 2].to_i
919
+ e.min = $2[-4, 2].to_i
920
+ else
921
+ e.mon = $2[ 0, 2].to_i
922
+ e.mday = $2[ 2, 2].to_i
923
+ end
924
+ when 6
925
+ if $3.nil? && $4
926
+ e.sec = $2[-2, 2].to_i
927
+ e.min = $2[-4, 2].to_i
928
+ e.hour = $2[-6, 2].to_i
929
+ else
930
+ e.year = ($1 + $2[ 0, 2]).to_i
931
+ e.mon = $2[ 2, 2].to_i
932
+ e.mday = $2[ 4, 2].to_i
933
+ end
934
+ when 8, 10, 12, 14
935
+ if $3.nil? && $4
936
+ e.sec = $2[-2, 2].to_i
937
+ e.min = $2[-4, 2].to_i
938
+ e.hour = $2[-6, 2].to_i
939
+ e.mday = $2[-8, 2].to_i
940
+ if $2.size >= 10
941
+ e.mon = $2[-10, 2].to_i
942
+ end
943
+ if $2.size == 12
944
+ e.year = ($1 + $2[-12, 2]).to_i
945
+ end
946
+ if $2.size == 14
947
+ e.year = ($1 + $2[-14, 4]).to_i
948
+ e._comp = false
949
+ end
950
+ else
951
+ e.year = ($1 + $2[ 0, 4]).to_i
952
+ e.mon = $2[ 4, 2].to_i
953
+ e.mday = $2[ 6, 2].to_i
954
+ e.hour = $2[ 8, 2].to_i if $2.size >= 10
955
+ e.min = $2[10, 2].to_i if $2.size >= 12
956
+ e.sec = $2[12, 2].to_i if $2.size >= 14
957
+ e._comp = false
958
+ end
959
+ when 3
960
+ if $3.nil? && $4
961
+ e.sec = $2[-2, 2].to_i
962
+ e.min = $2[-3, 1].to_i
963
+ else
964
+ e.yday = $2[ 0, 3].to_i
965
+ end
966
+ when 5
967
+ if $3.nil? && $4
968
+ e.sec = $2[-2, 2].to_i
969
+ e.min = $2[-4, 2].to_i
970
+ e.hour = $2[-5, 1].to_i
971
+ else
972
+ e.year = ($1 + $2[ 0, 2]).to_i
973
+ e.yday = $2[ 2, 3].to_i
974
+ end
975
+ when 7
976
+ if $3.nil? && $4
977
+ e.sec = $2[-2, 2].to_i
978
+ e.min = $2[-4, 2].to_i
979
+ e.hour = $2[-6, 2].to_i
980
+ e.mday = $2[-7, 1].to_i
981
+ else
982
+ e.year = ($1 + $2[ 0, 4]).to_i
983
+ e.yday = $2[ 4, 3].to_i
984
+ end
985
+ end
986
+ if $3
987
+ if $4
988
+ case $3.size
989
+ when 2, 4, 6
990
+ e.sec = $3[-2, 2].to_i
991
+ e.min = $3[-4, 2].to_i if $3.size >= 4
992
+ e.hour = $3[-6, 2].to_i if $3.size >= 6
993
+ end
994
+ else
995
+ case $3.size
996
+ when 2, 4, 6
997
+ e.hour = $3[ 0, 2].to_i
998
+ e.min = $3[ 2, 2].to_i if $3.size >= 4
999
+ e.sec = $3[ 4, 2].to_i if $3.size >= 6
1000
+ end
1001
+ end
1002
+ end
1003
+ if $4
1004
+ e.sec_fraction = Rational($4.to_i, 10**$4.size)
1005
+ end
1006
+ if $5
1007
+ e.zone = $5
1008
+ if e.zone[0,1] == '['
1009
+ o, n, = e.zone[1..-2].split(':')
1010
+ e.zone = n || o
1011
+ if /\A\d/ =~ o
1012
+ o = format('+%s', o)
1013
+ end
1014
+ e.offset = zone_to_diff(o)
1015
+ end
1016
+ end
1017
+ true
1009
1018
  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
1019
  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
1020
 
1033
- e = Format::Bag.new
1021
+ private_class_method :_parse_day, :_parse_time, # :_parse_beat,
1022
+ :_parse_eu, :_parse_us, :_parse_iso, :_parse_iso2,
1023
+ :_parse_jis, :_parse_vms, :_parse_sla, :_parse_dot,
1024
+ :_parse_year, :_parse_mon, :_parse_mday, :_parse_ddd
1034
1025
 
1035
- e._comp = comp
1026
+ def self._parse(str, comp=true)
1027
+ str = str.dup
1036
1028
 
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)
1029
+ e = Format::Bag.new
1054
1030
 
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
1031
+ e._comp = comp
1032
+
1033
+ str.gsub!(/[^-+',.\/:@[:alnum:]\[\]]+/, ' ')
1034
+
1035
+ _parse_time(str, e) # || _parse_beat(str, e)
1036
+ _parse_day(str, e)
1037
+
1038
+ _parse_eu(str, e) ||
1039
+ _parse_us(str, e) ||
1040
+ _parse_iso(str, e) ||
1041
+ _parse_jis(str, e) ||
1042
+ _parse_vms(str, e) ||
1043
+ _parse_sla(str, e) ||
1044
+ _parse_dot(str, e) ||
1045
+ _parse_iso2(str, e) ||
1046
+ _parse_year(str, e) ||
1047
+ _parse_mon(str, e) ||
1048
+ _parse_mday(str, e) ||
1049
+ _parse_ddd(str, e)
1050
+
1051
+ if str.sub!(/\b(bc\b|bce\b|b\.c\.|b\.c\.e\.)/i, ' ')
1052
+ if e.year
1053
+ e.year = -e.year + 1
1054
+ end
1058
1055
  end
1059
- end
1060
1056
 
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
1057
+ if str.sub!(/\A\s*(\d{1,2})\s*\z/, ' ')
1058
+ if e.hour && !e.mday
1059
+ v = $1.to_i
1060
+ if (1..31) === v
1061
+ e.mday = v
1062
+ end
1063
+ end
1064
+ if e.mday && !e.hour
1065
+ v = $1.to_i
1066
+ if (0..24) === v
1067
+ e.hour = v
1068
+ end
1069
+ end
1073
1070
  end
1074
- end
1075
1071
 
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
1072
+ if e._comp
1073
+ if e.cwyear
1074
+ if e.cwyear >= 0 && e.cwyear <= 99
1075
+ e.cwyear += if e.cwyear >= 69
1076
+ then 1900 else 2000 end
1077
+ end
1078
+ end
1079
+ if e.year
1080
+ if e.year >= 0 && e.year <= 99
1081
+ e.year += if e.year >= 69
1082
+ then 1900 else 2000 end
1083
+ end
1084
+ end
1088
1085
  end
1089
- end
1090
1086
 
1091
- e.offset ||= zone_to_diff(e.zone) if e.zone
1087
+ e.offset ||= zone_to_diff(e.zone) if e.zone
1092
1088
 
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)
1089
+ e.to_hash
1118
1090
  end
1119
- end
1120
1091
 
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)
1092
+ def self._iso8601(str) # :nodoc:
1093
+ if /\A\s*(([-+]?\d{2,}|-)-\d{2}-\d{2}|
1094
+ ([-+]?\d{2,})?-\d{3}|
1095
+ (\d{2}|\d{4})?-w\d{2}-\d|
1096
+ -w-\d)
1097
+ (t
1098
+ \d{2}:\d{2}(:\d{2}([,.]\d+)?)?
1099
+ (z|[-+]\d{2}(:?\d{2})?)?)?\s*\z/ix =~ str
1100
+ _parse(str)
1101
+ elsif /\A\s*(([-+]?(\d{2}|\d{4})|--)\d{2}\d{2}|
1102
+ ([-+]?(\d{2}|\d{4}))?\d{3}|-\d{3}|
1103
+ (\d{2}|\d{4})?w\d{2}\d)
1104
+ (t?
1105
+ \d{2}\d{2}(\d{2}([,.]\d+)?)?
1106
+ (z|[-+]\d{2}(\d{2})?)?)?\s*\z/ix =~ str
1107
+ _parse(str)
1108
+ elsif /\A\s*(\d{2}:\d{2}(:\d{2}([,.]\d+)?)?
1109
+ (z|[-+]\d{2}(:?\d{2})?)?)?\s*\z/ix =~ str
1110
+ _parse(str)
1111
+ elsif /\A\s*(\d{2}\d{2}(\d{2}([,.]\d+)?)?
1112
+ (z|[-+]\d{2}(\d{2})?)?)?\s*\z/ix =~ str
1113
+ _parse(str)
1114
+ end
1127
1115
  end
1128
- end
1129
1116
 
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)
1117
+ def self._rfc3339(str) # :nodoc:
1118
+ if /\A\s*-?\d{4}-\d{2}-\d{2} # allow minus, anyway
1119
+ (t|\s)
1120
+ \d{2}:\d{2}:\d{2}(\.\d+)?
1121
+ (z|[-+]\d{2}:\d{2})\s*\z/ix =~ str
1122
+ _parse(str)
1158
1123
  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
1124
  end
1172
- end
1173
1125
 
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
1126
+ def self._xmlschema(str) # :nodoc:
1127
+ if /\A\s*(-?\d{4,})(?:-(\d{2})(?:-(\d{2}))?)?
1128
+ (?:t
1129
+ (\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?)?
1130
+ (z|[-+]\d{2}:\d{2})?\s*\z/ix =~ str
1131
+ e = Format::Bag.new
1132
+ e.year = $1.to_i
1133
+ e.mon = $2.to_i if $2
1134
+ e.mday = $3.to_i if $3
1135
+ e.hour = $4.to_i if $4
1136
+ e.min = $5.to_i if $5
1137
+ e.sec = $6.to_i if $6
1138
+ e.sec_fraction = Rational($7.to_i, 10**$7.size) if $7
1139
+ if $8
1140
+ e.zone = $8
1141
+ e.offset = zone_to_diff($8)
1142
+ end
1143
+ e.to_hash
1144
+ elsif /\A\s*(\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?
1145
+ (z|[-+]\d{2}:\d{2})?\s*\z/ix =~ str
1146
+ e = Format::Bag.new
1147
+ e.hour = $1.to_i if $1
1148
+ e.min = $2.to_i if $2
1149
+ e.sec = $3.to_i if $3
1150
+ e.sec_fraction = Rational($4.to_i, 10**$4.size) if $4
1151
+ if $5
1152
+ e.zone = $5
1153
+ e.offset = zone_to_diff($5)
1154
+ end
1155
+ e.to_hash
1156
+ elsif /\A\s*(?:--(\d{2})(?:-(\d{2}))?|---(\d{2}))
1157
+ (z|[-+]\d{2}:\d{2})?\s*\z/ix =~ str
1158
+ e = Format::Bag.new
1159
+ e.mon = $1.to_i if $1
1160
+ e.mday = $2.to_i if $2
1161
+ e.mday = $3.to_i if $3
1162
+ if $4
1163
+ e.zone = $4
1164
+ e.offset = zone_to_diff($4)
1165
+ end
1166
+ e.to_hash
1188
1167
  end
1189
- e
1190
1168
  end
1191
- end
1192
1169
 
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)
1170
+ def self._rfc2822(str) # :nodoc:
1171
+ if /\A\s*(?:(?:#{Format::ABBR_DAYS.keys.join('|')})\s*,\s+)?
1172
+ \d{1,2}\s+
1173
+ (?:#{Format::ABBR_MONTHS.keys.join('|')})\s+
1174
+ -?(\d{2,})\s+ # allow minus, anyway
1175
+ \d{2}:\d{2}(:\d{2})?\s*
1176
+ (?:[-+]\d{4}|ut|gmt|e[sd]t|c[sd]t|m[sd]t|p[sd]t|[a-ik-z])\s*\z/iox =~ str
1177
+ e = _parse(str, false)
1178
+ if $1.size < 4
1179
+ if e[:year] < 50
1180
+ e[:year] += 2000
1181
+ elsif e[:year] < 1000
1182
+ e[:year] += 1900
1183
+ end
1184
+ end
1185
+ e
1186
+ end
1216
1187
  end
1217
- end
1218
1188
 
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)
1189
+ class << self; alias_method :_rfc822, :_rfc2822 end
1190
+
1191
+ def self._httpdate(str) # :nodoc:
1192
+ if /\A\s*(#{Format::ABBR_DAYS.keys.join('|')})\s*,\s+
1193
+ \d{2}\s+
1194
+ (#{Format::ABBR_MONTHS.keys.join('|')})\s+
1195
+ -?\d{4}\s+ # allow minus, anyway
1196
+ \d{2}:\d{2}:\d{2}\s+
1197
+ gmt\s*\z/iox =~ str
1198
+ _rfc2822(str)
1199
+ elsif /\A\s*(#{Format::DAYS.keys.join('|')})\s*,\s+
1200
+ \d{2}\s*-\s*
1201
+ (#{Format::ABBR_MONTHS.keys.join('|')})\s*-\s*
1202
+ \d{2}\s+
1203
+ \d{2}:\d{2}:\d{2}\s+
1204
+ gmt\s*\z/iox =~ str
1205
+ _parse(str)
1206
+ elsif /\A\s*(#{Format::ABBR_DAYS.keys.join('|')})\s+
1207
+ (#{Format::ABBR_MONTHS.keys.join('|')})\s+
1208
+ \d{1,2}\s+
1209
+ \d{2}:\d{2}:\d{2}\s+
1210
+ \d{4}\s*\z/iox =~ str
1211
+ _parse(str)
1228
1212
  end
1229
- else
1230
- _iso8601(str)
1231
1213
  end
1232
- end
1233
-
1234
- t = Module.new do
1235
-
1236
- private
1237
1214
 
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'
1215
+ def self._jisx0301(str) # :nodoc:
1216
+ if /\A\s*[mtsh]?\d{2}\.\d{2}\.\d{2}
1217
+ (t
1218
+ (\d{2}:\d{2}(:\d{2}([,.]\d*)?)?
1219
+ (z|[-+]\d{2}(:?\d{2})?)?)?)?\s*\z/ix =~ str
1220
+ if /\A\s*\d/ =~ str
1221
+ _parse(str.sub(/\A\s*(\d)/, 'h\1'))
1222
+ else
1223
+ _parse(str)
1224
+ end
1242
1225
  else
1243
- dst = zone.sub!(/\s+dst\z/, '')
1226
+ _iso8601(str)
1244
1227
  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 == '-'
1228
+ end
1229
+
1230
+ t = Module.new do
1231
+
1232
+ private
1233
+
1234
+ def zone_to_diff(zone) # :nodoc:
1235
+ zone = zone.downcase
1236
+ if zone.sub!(/\s+(standard|daylight)\s+time\z/, '')
1237
+ dst = $1 == 'daylight'
1238
+ else
1239
+ dst = zone.sub!(/\s+dst\z/, '')
1240
+ end
1241
+ if Format::ZONES.include?(zone)
1242
+ offset = Format::ZONES[zone]
1243
+ offset += 3600 if dst
1244
+ elsif zone.sub!(/\A(?:gmt|utc?)?([-+])/, '')
1245
+ sign = $1
1246
+ if zone.include?(':')
1247
+ hour, min, sec, = zone.split(':')
1248
+ elsif zone.include?(',') || zone.include?('.')
1249
+ hour, fr, = zone.split(/[,.]/)
1250
+ min = Rational(fr.to_i, 10**fr.size) * 60
1251
+ else
1252
+ case zone.size
1253
+ when 3
1254
+ hour = zone[0,1]
1255
+ min = zone[1,2]
1256
+ else
1257
+ hour = zone[0,2]
1258
+ min = zone[2,2]
1259
+ sec = zone[4,2]
1260
+ end
1261
+ end
1262
+ offset = hour.to_i * 3600 + min.to_i * 60 + sec.to_i
1263
+ offset *= -1 if sign == '-'
1264
+ end
1265
+ offset
1268
1266
  end
1269
- offset
1267
+
1270
1268
  end
1271
1269
 
1272
- end
1270
+ extend t
1271
+ include t
1273
1272
 
1274
- extend t
1275
- include t
1273
+ end
1276
1274
 
1277
- end
1275
+ class DateTime < Date
1278
1276
 
1279
- class DateTime < Date
1277
+ def strftime(fmt='%FT%T%:z')
1278
+ super(fmt)
1279
+ end
1280
1280
 
1281
- def strftime(fmt='%FT%T%:z')
1282
- super(fmt)
1283
- end
1281
+ def self._strptime(str, fmt='%FT%T%z')
1282
+ super(str, fmt)
1283
+ end
1284
1284
 
1285
- def self._strptime(str, fmt='%FT%T%z')
1286
- super(str, fmt)
1287
- end
1285
+ def iso8601_timediv(n) # :nodoc:
1286
+ strftime('T%T' +
1287
+ if n < 1
1288
+ ''
1289
+ else
1290
+ '.%0*d' % [n, (sec_fraction / Rational(1, 10**n)).round]
1291
+ end +
1292
+ '%:z')
1293
+ end
1288
1294
 
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
1295
+ private :iso8601_timediv
1298
1296
 
1299
- private :iso8601_timediv
1297
+ def iso8601(n=0)
1298
+ super() + iso8601_timediv(n)
1299
+ end
1300
1300
 
1301
- def iso8601(n=0)
1302
- super() + iso8601_timediv(n)
1303
- end
1301
+ def rfc3339(n=0) iso8601(n) end
1304
1302
 
1305
- def rfc3339(n=0) iso8601(n) end
1303
+ def xmlschema(n=0) iso8601(n) end # :nodoc:
1306
1304
 
1307
- def xmlschema(n=0) iso8601(n) end # :nodoc:
1305
+ def jisx0301(n=0)
1306
+ super() + iso8601_timediv(n)
1307
+ end
1308
1308
 
1309
- def jisx0301(n=0)
1310
- super() + iso8601_timediv(n)
1311
1309
  end
1312
-
1313
- end
1310
+ end