1# frozen_string_literal: true
2require 'test/unit'
3require 'date'
4
5class TestDateStrptime < Test::Unit::TestCase
6
7  STRFTIME_2001_02_03 = {
8    '%A'=>['Saturday',{:wday=>6}],
9    '%a'=>['Sat',{:wday=>6}],
10    '%B'=>['February',{:mon=>2}],
11    '%b'=>['Feb',{:mon=>2}],
12    '%c'=>['Sat Feb  3 00:00:00 2001',
13      {:wday=>6,:mon=>2,:mday=>3,:hour=>0,:min=>0,:sec=>0,:year=>2001}],
14    '%d'=>['03',{:mday=>3}],
15    '%e'=>[' 3',{:mday=>3}],
16    '%H'=>['00',{:hour=>0}],
17    '%I'=>['12',{:hour=>0}],
18    '%j'=>['034',{:yday=>34}],
19    '%M'=>['00',{:min=>0}],
20    '%m'=>['02',{:mon=>2}],
21    '%p'=>['AM',{}],
22    '%S'=>['00',{:sec=>0}],
23    '%U'=>['04',{:wnum0=>4}],
24    '%W'=>['05',{:wnum1=>5}],
25    '%X'=>['00:00:00',{:hour=>0,:min=>0,:sec=>0}],
26    '%x'=>['02/03/01',{:mon=>2,:mday=>3,:year=>2001}],
27    '%Y'=>['2001',{:year=>2001}],
28    '%y'=>['01',{:year=>2001}],
29    '%Z'=>['+00:00',{:zone=>'+00:00',:offset=>0}],
30    '%%'=>['%',{}],
31    '%C'=>['20',{}],
32    '%D'=>['02/03/01',{:mon=>2,:mday=>3,:year=>2001}],
33    '%F'=>['2001-02-03',{:year=>2001,:mon=>2,:mday=>3}],
34    '%G'=>['2001',{:cwyear=>2001}],
35    '%g'=>['01',{:cwyear=>2001}],
36    '%h'=>['Feb',{:mon=>2}],
37    '%k'=>[' 0',{:hour=>0}],
38    '%L'=>['000',{:sec_fraction=>0}],
39    '%l'=>['12',{:hour=>0}],
40    '%N'=>['000000000',{:sec_fraction=>0}],
41    '%n'=>["\n",{}],
42    '%P'=>['am',{}],
43    '%Q'=>['981158400000',{:seconds=>981158400.to_r}],
44    '%R'=>['00:00',{:hour=>0,:min=>0}],
45    '%r'=>['12:00:00 AM',{:hour=>0,:min=>0,:sec=>0}],
46    '%s'=>['981158400',{:seconds=>981158400}],
47    '%T'=>['00:00:00',{:hour=>0,:min=>0,:sec=>0}],
48    '%t'=>["\t",{}],
49    '%u'=>['6',{:cwday=>6}],
50    '%V'=>['05',{:cweek=>5}],
51    '%v'=>[' 3-Feb-2001',{:mday=>3,:mon=>2,:year=>2001}],
52    '%z'=>['+0000',{:zone=>'+0000',:offset=>0}],
53    '%+'=>['Sat Feb  3 00:00:00 +00:00 2001',
54      {:wday=>6,:mon=>2,:mday=>3,
55	:hour=>0,:min=>0,:sec=>0,:zone=>'+00:00',:offset=>0,:year=>2001}],
56  }
57
58  STRFTIME_2001_02_03_CVS19 = {
59  }
60
61  STRFTIME_2001_02_03_GNUext = {
62    '%:z'=>['+00:00',{:zone=>'+00:00',:offset=>0}],
63    '%::z'=>['+00:00:00',{:zone=>'+00:00:00',:offset=>0}],
64    '%:::z'=>['+00',{:zone=>'+00',:offset=>0}],
65  }
66
67  STRFTIME_2001_02_03.update(STRFTIME_2001_02_03_CVS19)
68  STRFTIME_2001_02_03.update(STRFTIME_2001_02_03_GNUext)
69
70  def test__strptime
71    STRFTIME_2001_02_03.each do |f, s|
72      if (f == '%I' and s[0] == '12') or
73	 (f == '%l' and s[0] == '12') # hour w/o merid
74	s[1][:hour] = 12
75      end
76      assert_equal(s[1], Date._strptime(s[0], f), [f, s].inspect)
77      case f[-1,1]
78      when 'c', 'C', 'x', 'X', 'y', 'Y'
79	f2 = f.sub(/\A%/, '%E')
80	assert_equal(s[1], Date._strptime(s[0], f2), [f2, s].inspect)
81      else
82	f2 = f.sub(/\A%/, '%E')
83	assert_equal(nil, Date._strptime(s[0], f2), [f2, s].inspect)
84	assert_equal({}, Date._strptime(f2, f2), [f2, s].inspect)
85      end
86      case f[-1,1]
87      when 'd', 'e', 'H', 'I', 'm', 'M', 'S', 'u', 'U', 'V', 'w', 'W', 'y'
88	f2 = f.sub(/\A%/, '%O')
89	assert_equal(s[1], Date._strptime(s[0], f2), [f2, s].inspect)
90      else
91	f2 = f.sub(/\A%/, '%O')
92	assert_equal(nil, Date._strptime(s[0], f2), [f2, s].inspect)
93	assert_equal({}, Date._strptime(f2, f2), [f2, s].inspect)
94      end
95    end
96  end
97
98  def test__strptime__2
99    h = Date._strptime('2001-02-03')
100    assert_equal([2001,2,3], h.values_at(:year,:mon,:mday))
101
102    h = DateTime._strptime('2001-02-03T12:13:14Z')
103    assert_equal([2001,2,3,12,13,14],
104		 h.values_at(:year,:mon,:mday,:hour,:min,:sec))
105
106    assert_equal({}, Date._strptime('', ''))
107    assert_equal({:leftover=>"\s"*3}, Date._strptime("\s"*3, ''))
108    assert_equal({:leftover=>'x'}, Date._strptime("\nx", "\n"))
109    assert_equal({}, Date._strptime('', "\s"*3))
110    assert_equal({}, Date._strptime("\s"*3, "\s"*3))
111    assert_equal({}, Date._strptime("\tfoo\n\000\r", "\tfoo\n\000\r"))
112    assert_equal({}, Date._strptime("foo\n\nbar", "foo\sbar"))
113    assert_equal({}, Date._strptime("%\n", "%\n")) # gnu
114    assert_equal({}, Date._strptime('%%', '%%%'))
115    assert_equal({:wday=>6}, Date._strptime('Saturday'*1024 + ',', '%A'*1024 + ','))
116    assert_equal({:wday=>6}, Date._strptime('Saturday'*1024 + ',', '%a'*1024 + ','))
117    assert_equal({}, Date._strptime('Anton von Webern', 'Anton von Webern'))
118  end
119
120  def test__strptime__3
121    [
122     # iso8601
123     [['2001-02-03', '%Y-%m-%d'], [2001,2,3,nil,nil,nil,nil,nil,nil], __LINE__],
124     [['2001-02-03T23:59:60', '%Y-%m-%dT%H:%M:%S'], [2001,2,3,23,59,60,nil,nil,nil], __LINE__],
125     [['2001-02-03T23:59:60+09:00', '%Y-%m-%dT%H:%M:%S%Z'], [2001,2,3,23,59,60,'+09:00',9*3600,nil], __LINE__],
126     [['-2001-02-03T23:59:60+09:00', '%Y-%m-%dT%H:%M:%S%Z'], [-2001,2,3,23,59,60,'+09:00',9*3600,nil], __LINE__],
127     [['+012345-02-03T23:59:60+09:00', '%Y-%m-%dT%H:%M:%S%Z'], [12345,2,3,23,59,60,'+09:00',9*3600,nil], __LINE__],
128     [['-012345-02-03T23:59:60+09:00', '%Y-%m-%dT%H:%M:%S%Z'], [-12345,2,3,23,59,60,'+09:00',9*3600,nil], __LINE__],
129
130     # ctime(3), asctime(3)
131     [['Thu Jul 29 14:47:19 1999', '%c'], [1999,7,29,14,47,19,nil,nil,4], __LINE__],
132     [['Thu Jul 29 14:47:19 -1999', '%c'], [-1999,7,29,14,47,19,nil,nil,4], __LINE__],
133
134     # date(1)
135     [['Thu Jul 29 16:39:41 EST 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'EST',-5*3600,4], __LINE__],
136     [['Thu Jul 29 16:39:41 MET DST 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'MET DST',2*3600,4], __LINE__],
137     [['Thu Jul 29 16:39:41 AMT 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'AMT',nil,4], __LINE__],
138     [['Thu Jul 29 16:39:41 AMT -1999', '%a %b %d %H:%M:%S %Z %Y'], [-1999,7,29,16,39,41,'AMT',nil,4], __LINE__],
139     [['Thu Jul 29 16:39:41 GMT+09 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT+09',9*3600,4], __LINE__],
140     [['Thu Jul 29 16:39:41 GMT+0908 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT+0908',9*3600+8*60,4], __LINE__],
141     [['Thu Jul 29 16:39:41 GMT+090807 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT+090807',9*3600+8*60+7,4], __LINE__],
142     [['Thu Jul 29 16:39:41 GMT-09 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT-09',-9*3600,4], __LINE__],
143     [['Thu Jul 29 16:39:41 GMT-09:08 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT-09:08',-9*3600-8*60,4], __LINE__],
144     [['Thu Jul 29 16:39:41 GMT-09:08:07 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT-09:08:07',-9*3600-8*60-7,4], __LINE__],
145     [['Thu Jul 29 16:39:41 GMT-3.5 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT-3.5',-3*3600-30*60,4], __LINE__],
146     [['Thu Jul 29 16:39:41 GMT-3,5 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'GMT-3,5',-3*3600-30*60,4], __LINE__],
147     [['Thu Jul 29 16:39:41 Mountain Daylight Time 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'Mountain Daylight Time',-6*3600,4], __LINE__],
148     [['Thu Jul 29 16:39:41 E. Australia Standard Time 1999', '%a %b %d %H:%M:%S %Z %Y'], [1999,7,29,16,39,41,'E. Australia Standard Time',10*3600,4], __LINE__],
149
150     # rfc822
151     [['Thu, 29 Jul 1999 09:54:21 UT', '%a, %d %b %Y %H:%M:%S %Z'], [1999,7,29,9,54,21,'UT',0,4], __LINE__],
152     [['Thu, 29 Jul 1999 09:54:21 GMT', '%a, %d %b %Y %H:%M:%S %Z'], [1999,7,29,9,54,21,'GMT',0,4], __LINE__],
153     [['Thu, 29 Jul 1999 09:54:21 PDT', '%a, %d %b %Y %H:%M:%S %Z'], [1999,7,29,9,54,21,'PDT',-7*3600,4], __LINE__],
154     [['Thu, 29 Jul 1999 09:54:21 z', '%a, %d %b %Y %H:%M:%S %Z'], [1999,7,29,9,54,21,'z',0,4], __LINE__],
155     [['Thu, 29 Jul 1999 09:54:21 +0900', '%a, %d %b %Y %H:%M:%S %Z'], [1999,7,29,9,54,21,'+0900',9*3600,4], __LINE__],
156     [['Thu, 29 Jul 1999 09:54:21 +0430', '%a, %d %b %Y %H:%M:%S %Z'], [1999,7,29,9,54,21,'+0430',4*3600+30*60,4], __LINE__],
157     [['Thu, 29 Jul 1999 09:54:21 -0430', '%a, %d %b %Y %H:%M:%S %Z'], [1999,7,29,9,54,21,'-0430',-4*3600-30*60,4], __LINE__],
158     [['Thu, 29 Jul -1999 09:54:21 -0430', '%a, %d %b %Y %H:%M:%S %Z'], [-1999,7,29,9,54,21,'-0430',-4*3600-30*60,4], __LINE__],
159
160     # etc
161     [['06-DEC-99', '%d-%b-%y'], [1999,12,6,nil,nil,nil,nil,nil,nil], __LINE__],
162     [['sUnDay oCtoBer 31 01', '%A %B %d %y'], [2001,10,31,nil,nil,nil,nil,nil,0], __LINE__],
163     [["October\t\n\v\f\r 15,\t\n\v\f\r99", '%B %d, %y'], [1999,10,15,nil,nil,nil,nil,nil,nil], __LINE__],
164     [["October\t\n\v\f\r 15,\t\n\v\f\r99", '%B%t%d,%n%y'], [1999,10,15,nil,nil,nil,nil,nil,nil], __LINE__],
165
166     [['09:02:11 AM', '%I:%M:%S %p'], [nil,nil,nil,9,2,11,nil,nil,nil], __LINE__],
167     [['09:02:11 A.M.', '%I:%M:%S %p'], [nil,nil,nil,9,2,11,nil,nil,nil], __LINE__],
168     [['09:02:11 PM', '%I:%M:%S %p'], [nil,nil,nil,21,2,11,nil,nil,nil], __LINE__],
169     [['09:02:11 P.M.', '%I:%M:%S %p'], [nil,nil,nil,21,2,11,nil,nil,nil], __LINE__],
170
171     [['12:33:44 AM', '%r'], [nil,nil,nil,0,33,44,nil,nil,nil], __LINE__],
172     [['01:33:44 AM', '%r'], [nil,nil,nil,1,33,44,nil,nil,nil], __LINE__],
173     [['11:33:44 AM', '%r'], [nil,nil,nil,11,33,44,nil,nil,nil], __LINE__],
174     [['12:33:44 PM', '%r'], [nil,nil,nil,12,33,44,nil,nil,nil], __LINE__],
175     [['01:33:44 PM', '%r'], [nil,nil,nil,13,33,44,nil,nil,nil], __LINE__],
176     [['11:33:44 PM', '%r'], [nil,nil,nil,23,33,44,nil,nil,nil], __LINE__],
177
178     [['11:33:44 PM AMT', '%I:%M:%S %p %Z'], [nil,nil,nil,23,33,44,'AMT',nil,nil], __LINE__],
179     [['11:33:44 P.M. AMT', '%I:%M:%S %p %Z'], [nil,nil,nil,23,33,44,'AMT',nil,nil], __LINE__],
180
181     [['fri1feb034pm+5', '%a%d%b%y%H%p%Z'], [2003,2,1,16,nil,nil,'+5',5*3600,5]]
182    ].each do |x, y|
183      h = Date._strptime(*x)
184      a = h.values_at(:year,:mon,:mday,:hour,:min,:sec,:zone,:offset,:wday)
185      if y[1] == -1
186	a[1] = -1
187	a[2] = h[:yday]
188      end
189      assert_equal(y, a, [x, y, a].inspect)
190    end
191  end
192
193  def test__strptime__width
194    [
195     [['99', '%y'], [1999,nil,nil,nil,nil,nil,nil,nil,nil], __LINE__],
196     [['01', '%y'], [2001,nil,nil,nil,nil,nil,nil,nil,nil], __LINE__],
197     [['19 99', '%C %y'], [1999,nil,nil,nil,nil,nil,nil,nil,nil], __LINE__],
198     [['20 01', '%C %y'], [2001,nil,nil,nil,nil,nil,nil,nil,nil], __LINE__],
199     [['30 99', '%C %y'], [3099,nil,nil,nil,nil,nil,nil,nil,nil], __LINE__],
200     [['30 01', '%C %y'], [3001,nil,nil,nil,nil,nil,nil,nil,nil], __LINE__],
201     [['1999', '%C%y'], [1999,nil,nil,nil,nil,nil,nil,nil,nil], __LINE__],
202     [['2001', '%C%y'], [2001,nil,nil,nil,nil,nil,nil,nil,nil], __LINE__],
203     [['3099', '%C%y'], [3099,nil,nil,nil,nil,nil,nil,nil,nil], __LINE__],
204     [['3001', '%C%y'], [3001,nil,nil,nil,nil,nil,nil,nil,nil], __LINE__],
205
206     [['20060806', '%Y'], [20060806,nil,nil,nil,nil,nil,nil,nil,nil], __LINE__],
207     [['20060806', "%Y\s"], [20060806,nil,nil,nil,nil,nil,nil,nil,nil], __LINE__],
208     [['20060806', '%Y%m%d'], [2006,8,6,nil,nil,nil,nil,nil,nil], __LINE__],
209     [['2006908906', '%Y9%m9%d'], [2006,8,6,nil,nil,nil,nil,nil,nil], __LINE__],
210     [['12006 08 06', '%Y %m %d'], [12006,8,6,nil,nil,nil,nil,nil,nil], __LINE__],
211     [['12006-08-06', '%Y-%m-%d'], [12006,8,6,nil,nil,nil,nil,nil,nil], __LINE__],
212     [['200608 6', '%Y%m%e'], [2006,8,6,nil,nil,nil,nil,nil,nil], __LINE__],
213
214     [['2006333', '%Y%j'], [2006,-1,333,nil,nil,nil,nil,nil,nil], __LINE__],
215     [['20069333', '%Y9%j'], [2006,-1,333,nil,nil,nil,nil,nil,nil], __LINE__],
216     [['12006 333', '%Y %j'], [12006,-1,333,nil,nil,nil,nil,nil,nil], __LINE__],
217     [['12006-333', '%Y-%j'], [12006,-1,333,nil,nil,nil,nil,nil,nil], __LINE__],
218
219     [['232425', '%H%M%S'], [nil,nil,nil,23,24,25,nil,nil,nil], __LINE__],
220     [['23924925', '%H9%M9%S'], [nil,nil,nil,23,24,25,nil,nil,nil], __LINE__],
221     [['23 24 25', '%H %M %S'], [nil,nil,nil,23,24,25,nil,nil,nil], __LINE__],
222     [['23:24:25', '%H:%M:%S'], [nil,nil,nil,23,24,25,nil,nil,nil], __LINE__],
223     [[' 32425', '%k%M%S'], [nil,nil,nil,3,24,25,nil,nil,nil], __LINE__],
224     [[' 32425', '%l%M%S'], [nil,nil,nil,3,24,25,nil,nil,nil], __LINE__],
225
226     [['FriAug', '%a%b'], [nil,8,nil,nil,nil,nil,nil,nil,5], __LINE__],
227     [['FriAug', '%A%B'], [nil,8,nil,nil,nil,nil,nil,nil,5], __LINE__],
228     [['FridayAugust', '%A%B'], [nil,8,nil,nil,nil,nil,nil,nil,5], __LINE__],
229     [['FridayAugust', '%a%b'], [nil,8,nil,nil,nil,nil,nil,nil,5], __LINE__],
230    ].each do |x,y,l|
231      h = Date._strptime(*x)
232      a = (h || {}).values_at(:year,:mon,:mday,:hour,:min,:sec,:zone,:offset,:wday)
233      if y[1] == -1
234	a[1] = -1
235	a[2] = h[:yday]
236      end
237      assert_equal(y, a, format('<failed at line %d>', l))
238    end
239  end
240
241  def test__strptime__fail
242    assert_not_nil(Date._strptime('2001.', '%Y.'))
243    assert_not_nil(Date._strptime("2001.\s", '%Y.'))
244    assert_not_nil(Date._strptime('2001.', "%Y.\s"))
245    assert_not_nil(Date._strptime("2001.\s", "%Y.\s"))
246
247    assert_nil(Date._strptime('2001', '%Y.'))
248    assert_nil(Date._strptime("2001\s", '%Y.'))
249    assert_nil(Date._strptime('2001', "%Y.\s"))
250    assert_nil(Date._strptime("2001\s", "%Y.\s"))
251
252    assert_nil(Date._strptime('2001-13-31', '%Y-%m-%d'))
253    assert_nil(Date._strptime('2001-12-00', '%Y-%m-%d'))
254    assert_nil(Date._strptime('2001-12-32', '%Y-%m-%d'))
255    assert_nil(Date._strptime('2001-12-00', '%Y-%m-%e'))
256    assert_nil(Date._strptime('2001-12-32', '%Y-%m-%e'))
257    assert_nil(Date._strptime('2001-12-31', '%y-%m-%d'))
258
259    assert_nil(Date._strptime('2004-000', '%Y-%j'))
260    assert_nil(Date._strptime('2004-367', '%Y-%j'))
261    assert_nil(Date._strptime('2004-366', '%y-%j'))
262
263    assert_not_nil(Date._strptime('24:59:59', '%H:%M:%S'))
264    assert_not_nil(Date._strptime('24:59:59', '%k:%M:%S'))
265    assert_not_nil(Date._strptime('24:59:60', '%H:%M:%S'))
266    assert_not_nil(Date._strptime('24:59:60', '%k:%M:%S'))
267
268    assert_nil(Date._strptime('24:60:59', '%H:%M:%S'))
269    assert_nil(Date._strptime('24:60:59', '%k:%M:%S'))
270    assert_nil(Date._strptime('24:59:61', '%H:%M:%S'))
271    assert_nil(Date._strptime('24:59:61', '%k:%M:%S'))
272    assert_nil(Date._strptime('00:59:59', '%I:%M:%S'))
273    assert_nil(Date._strptime('13:59:59', '%I:%M:%S'))
274    assert_nil(Date._strptime('00:59:59', '%l:%M:%S'))
275    assert_nil(Date._strptime('13:59:59', '%l:%M:%S'))
276
277    assert_not_nil(Date._strptime('0', '%U'))
278    assert_nil(Date._strptime('54', '%U'))
279    assert_not_nil(Date._strptime('0', '%W'))
280    assert_nil(Date._strptime('54', '%W'))
281    assert_nil(Date._strptime('0', '%V'))
282    assert_nil(Date._strptime('54', '%V'))
283    assert_nil(Date._strptime('0', '%u'))
284    assert_not_nil(Date._strptime('7', '%u'))
285    assert_not_nil(Date._strptime('0', '%w'))
286    assert_nil(Date._strptime('7', '%w'))
287
288    assert_nil(Date._strptime('Sanday', '%A'))
289    assert_nil(Date._strptime('Jenuary', '%B'))
290    assert_not_nil(Date._strptime('Sundai', '%A'))
291    assert_not_nil(Date._strptime('Januari', '%B'))
292    assert_nil(Date._strptime('Sundai,', '%A,'))
293    assert_nil(Date._strptime('Januari,', '%B,'))
294  end
295
296  def test_strptime
297    assert_equal(Date.new, Date.strptime)
298    d = Date.new(2002,3,14)
299    assert_equal(d, Date.strptime(d.to_s))
300    assert_equal(Date.new(2002,3,14), Date.strptime('2002-03-14'))
301
302    d = DateTime.new(2002,3,14,11,22,33, 0)
303    assert_equal(d, DateTime.strptime(d.to_s))
304    assert_equal(DateTime.new(2002,3,14,11,22,33, 0),
305		 DateTime.strptime('2002-03-14T11:22:33Z'))
306    assert_equal(DateTime.new(2002,3,14,11,22,33, 0),
307		 DateTime.strptime('2002-03-14T11:22:33Z', '%Y-%m-%dT%H:%M:%S%Z'))
308    assert_equal(DateTime.new(2002,3,14,11,22,33, 9.to_r/24),
309		 DateTime.strptime('2002-03-14T11:22:33+09:00', '%Y-%m-%dT%H:%M:%S%Z'))
310    assert_equal(DateTime.new(2002,3,14,11,22,33, -9.to_r/24),
311		 DateTime.strptime('2002-03-14T11:22:33-09:00', '%FT%T%Z'))
312    assert_equal(DateTime.new(2002,3,14,11,22,33, -9.to_r/24) + 123456789.to_r/1000000000/86400,
313		 DateTime.strptime('2002-03-14T11:22:33.123456789-09:00', '%FT%T.%N%Z'))
314  end
315
316  def test_strptime__2
317    (Date.new(2006,6,1)..Date.new(2007,6,1)).each do |d|
318      [
319       '%Y %m %d',
320       '%C %y %m %d',
321
322       '%Y %j',
323       '%C %y %j',
324
325       '%G %V %w',
326       '%G %V %u',
327       '%C %g %V %w',
328       '%C %g %V %u',
329
330       '%Y %U %w',
331       '%Y %U %u',
332       '%Y %W %w',
333       '%Y %W %u',
334       '%C %y %U %w',
335       '%C %y %U %u',
336       '%C %y %W %w',
337       '%C %y %W %u',
338       ].each do |fmt|
339	s = d.strftime(fmt)
340	d2 = Date.strptime(s, fmt)
341	assert_equal(d, d2, [fmt, d.to_s, d2.to_s].inspect)
342      end
343
344      [
345       '%Y %m %d %H %M %S',
346       '%Y %m %d %H %M %S %N',
347       '%C %y %m %d %H %M %S',
348       '%C %y %m %d %H %M %S %N',
349
350       '%Y %j %H %M %S',
351       '%Y %j %H %M %S %N',
352       '%C %y %j %H %M %S',
353       '%C %y %j %H %M %S %N',
354
355       '%s',
356       '%s %N',
357       '%Q',
358       '%Q %N',
359      ].each do |fmt|
360	s = d.strftime(fmt)
361	d2 = DateTime.strptime(s, fmt)
362	assert_equal(d, d2, [fmt, d.to_s, d2.to_s].inspect)
363      end
364    end
365  end
366
367  def test_strptime__minus
368    d = DateTime.strptime('-1', '%s')
369    assert_equal([1969, 12, 31, 23, 59, 59],
370		 [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
371    d = DateTime.strptime('-86400', '%s')
372    assert_equal([1969, 12, 31, 0, 0, 0],
373		 [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
374
375    d = DateTime.strptime('-999', '%Q')
376    assert_equal([1969, 12, 31, 23, 59, 59, 1.to_r/10**3],
377		 [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.sec_fraction])
378    d = DateTime.strptime('-1000', '%Q')
379    assert_equal([1969, 12, 31, 23, 59, 59, 0],
380		 [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.sec_fraction])
381  end
382
383  def test_strptime__comp
384    n = DateTime.now
385
386    d = DateTime.strptime('073', '%j')
387    assert_equal([n.year, 73, 0, 0, 0],
388		 [d.year, d.yday, d.hour, d.min, d.sec])
389    d = DateTime.strptime('13', '%d')
390    assert_equal([n.year, n.mon, 13, 0, 0, 0],
391		 [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
392
393    d = DateTime.strptime('Mar', '%b')
394    assert_equal([n.year, 3, 1, 0, 0, 0],
395		 [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
396    d = DateTime.strptime('2004', '%Y')
397    assert_equal([2004, 1, 1, 0, 0, 0],
398		 [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
399
400    d = DateTime.strptime('Mar 13', '%b %d')
401    assert_equal([n.year, 3, 13, 0, 0, 0],
402		 [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
403    d = DateTime.strptime('Mar 2004', '%b %Y')
404    assert_equal([2004, 3, 1, 0, 0, 0],
405		 [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
406    d = DateTime.strptime('23:55', '%H:%M')
407    assert_equal([n.year, n.mon, n.mday, 23, 55, 0],
408		 [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
409    d = DateTime.strptime('23:55:30', '%H:%M:%S')
410    assert_equal([n.year, n.mon, n.mday, 23, 55, 30],
411		 [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
412
413    d = DateTime.strptime('Sun 23:55', '%a %H:%M')
414    d2 = d - d.wday
415    assert_equal([d2.year, d2.mon, d2.mday, 23, 55, 0],
416		 [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
417    d = DateTime.strptime('Aug 23:55', '%b %H:%M')
418    assert_equal([n.year, 8, 1, 23, 55, 0],
419		 [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
420
421    d = DateTime.strptime('2004', '%G')
422    assert_equal([2004, 1, 1, 0, 0, 0],
423		 [d.cwyear, d.cweek, d.cwday, d.hour, d.min, d.sec])
424    d = DateTime.strptime('11', '%V')
425    assert_equal([n.cwyear, 11, 1, 0, 0, 0],
426		 [d.cwyear, d.cweek, d.cwday, d.hour, d.min, d.sec])
427    d = DateTime.strptime('6', '%u')
428    assert_equal([n.cwyear, n.cweek, 6, 0, 0, 0],
429		 [d.cwyear, d.cweek, d.cwday, d.hour, d.min, d.sec])
430
431    d = DateTime.strptime('11-6', '%V-%u')
432    assert_equal([n.cwyear, 11, 6, 0, 0, 0],
433		 [d.cwyear, d.cweek, d.cwday, d.hour, d.min, d.sec])
434    d = DateTime.strptime('2004-11', '%G-%V')
435    assert_equal([2004, 11, 1, 0, 0, 0],
436		 [d.cwyear, d.cweek, d.cwday, d.hour, d.min, d.sec])
437
438    d = DateTime.strptime('11-6', '%U-%w')
439    assert_equal([n.year, 11, 6, 0, 0, 0],
440		 [d.year, d.strftime('%U').to_i, d.wday, d.hour, d.min, d.sec])
441    d = DateTime.strptime('2004-11', '%Y-%U')
442    assert_equal([2004, 11, 0, 0, 0, 0],
443		 [d.year, d.strftime('%U').to_i, d.wday, d.hour, d.min, d.sec])
444
445    d = DateTime.strptime('11-6', '%W-%w')
446    assert_equal([n.year, 11, 6, 0, 0, 0],
447		 [d.year, d.strftime('%W').to_i, d.wday, d.hour, d.min, d.sec])
448    d = DateTime.strptime('2004-11', '%Y-%W')
449    assert_equal([2004, 11, 1, 0, 0, 0],
450		 [d.year, d.strftime('%W').to_i, d.wday, d.hour, d.min, d.sec])
451  end
452
453  def test_strptime__d_to_s
454    d = Date.new(2002,3,14)
455    assert_equal(d, Date.strptime(d.to_s))
456
457    d = DateTime.new(2002,3,14,11,22,33, 9.to_r/24)
458    assert_equal(d, DateTime.strptime(d.to_s))
459  end
460
461  def test_strptime__ex
462    assert_raise(ArgumentError) do
463      Date.strptime('')
464    end
465    assert_raise(ArgumentError) do
466      DateTime.strptime('')
467    end
468    assert_raise(ArgumentError) do
469      Date.strptime('2001-02-29', '%F')
470    end
471    assert_raise(ArgumentError) do
472      DateTime.strptime('2001-02-29T23:59:60', '%FT%T')
473    end
474    assert_nothing_raised(ArgumentError) do
475      DateTime.strptime('2001-03-01T23:59:60', '%FT%T')
476    end
477    assert_raise(ArgumentError) do
478      DateTime.strptime('2001-03-01T23:59:61', '%FT%T')
479    end
480    assert_raise(ArgumentError) do
481      Date.strptime('23:55', '%H:%M')
482    end
483    assert_raise(ArgumentError) do
484      Date.strptime('01-31-2011', '%m/%d/%Y')
485    end
486  end
487
488  def test_given_string
489    s = '2001-02-03T04:05:06Z'
490    s0 = s.dup
491
492    assert_not_equal({}, Date._strptime(s, '%FT%T%Z'))
493    assert_equal(s0, s)
494  end
495
496  def test_sz
497    d = DateTime.strptime('0 -0200', '%s %z')
498    assert_equal([1969, 12, 31, 22, 0, 0], [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
499    assert_equal(Rational(-2, 24), d.offset)
500    d = DateTime.strptime('9 +0200', '%s %z')
501    assert_equal([1970, 1, 1, 2, 0, 9], [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
502    assert_equal(Rational(2, 24), d.offset)
503
504    d = DateTime.strptime('0 -0200', '%Q %z')
505    assert_equal([1969, 12, 31, 22, 0, 0], [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
506    assert_equal(Rational(-2, 24), d.offset)
507    d = DateTime.strptime('9000 +0200', '%Q %z')
508    assert_equal([1970, 1, 1, 2, 0, 9], [d.year, d.mon, d.mday, d.hour, d.min, d.sec])
509    assert_equal(Rational(2, 24), d.offset)
510
511  end
512
513end
514