View Javadoc

1   /*
2    *  Copyright 2001-2013 Stephen Colebourne
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.joda.time;
17  
18  import junit.framework.TestCase;
19  import junit.framework.TestSuite;
20  
21  import org.joda.time.chrono.GregorianChronology;
22  import org.joda.time.tz.DateTimeZoneBuilder;
23  
24  /**
25   * This class is a JUnit test for DateTimeZone.
26   *
27   * @author Stephen Colebourne
28   */
29  public class TestDateTimeZoneCutover extends TestCase {
30  
31      public static void main(String[] args) {
32          junit.textui.TestRunner.run(suite());
33      }
34  
35      public static TestSuite suite() {
36          return new TestSuite(TestDateTimeZoneCutover.class);
37      }
38  
39      public TestDateTimeZoneCutover(String name) {
40          super(name);
41      }
42  
43      protected void setUp() throws Exception {
44      }
45  
46      protected void tearDown() throws Exception {
47      }
48  
49      //-----------------------------------------------------------------------
50      //------------------------ Bug [1710316] --------------------------------
51      //-----------------------------------------------------------------------
52      // The behaviour of getOffsetFromLocal is defined in its javadoc
53      // However, this definition doesn't work for all DateTimeField operations
54      
55      /** Mock zone simulating Asia/Gaza cutover at midnight 2007-04-01 */
56      private static long CUTOVER_GAZA = 1175378400000L;
57      private static int OFFSET_GAZA = 7200000;  // +02:00
58      private static final DateTimeZone MOCK_GAZA = new MockZone(CUTOVER_GAZA, OFFSET_GAZA, 3600);
59  
60      //-----------------------------------------------------------------------
61      public void test_MockGazaIsCorrect() {
62          DateTime pre = new DateTime(CUTOVER_GAZA - 1L, MOCK_GAZA);
63          assertEquals("2007-03-31T23:59:59.999+02:00", pre.toString());
64          DateTime at = new DateTime(CUTOVER_GAZA, MOCK_GAZA);
65          assertEquals("2007-04-01T01:00:00.000+03:00", at.toString());
66          DateTime post = new DateTime(CUTOVER_GAZA + 1L, MOCK_GAZA);
67          assertEquals("2007-04-01T01:00:00.001+03:00", post.toString());
68      }
69  
70      public void test_getOffsetFromLocal_Gaza() {
71          doTest_getOffsetFromLocal_Gaza(-1, 23, 0, "2007-03-31T23:00:00.000+02:00");
72          doTest_getOffsetFromLocal_Gaza(-1, 23, 30, "2007-03-31T23:30:00.000+02:00");
73          doTest_getOffsetFromLocal_Gaza(0, 0, 0, "2007-04-01T01:00:00.000+03:00");
74          doTest_getOffsetFromLocal_Gaza(0, 0, 30, "2007-04-01T01:30:00.000+03:00");
75          doTest_getOffsetFromLocal_Gaza(0, 1, 0, "2007-04-01T01:00:00.000+03:00");
76          doTest_getOffsetFromLocal_Gaza(0, 1, 30, "2007-04-01T01:30:00.000+03:00");
77          doTest_getOffsetFromLocal_Gaza(0, 2, 0, "2007-04-01T02:00:00.000+03:00");
78          doTest_getOffsetFromLocal_Gaza(0, 3, 0, "2007-04-01T03:00:00.000+03:00");
79          doTest_getOffsetFromLocal_Gaza(0, 4, 0, "2007-04-01T04:00:00.000+03:00");
80          doTest_getOffsetFromLocal_Gaza(0, 5, 0, "2007-04-01T05:00:00.000+03:00");
81          doTest_getOffsetFromLocal_Gaza(0, 6, 0, "2007-04-01T06:00:00.000+03:00");
82      }
83  
84      private void doTest_getOffsetFromLocal_Gaza(int days, int hour, int min, String expected) {
85          DateTime dt = new DateTime(2007, 4, 1, hour, min, 0, 0, DateTimeZone.UTC).plusDays(days);
86          int offset = MOCK_GAZA.getOffsetFromLocal(dt.getMillis());
87          DateTime res = new DateTime(dt.getMillis() - offset, MOCK_GAZA);
88          assertEquals(res.toString(), expected, res.toString());
89      }
90  
91      public void test_DateTime_roundFloor_Gaza() {
92          DateTime dt = new DateTime(2007, 4, 1, 8, 0, 0, 0, MOCK_GAZA);
93          assertEquals("2007-04-01T08:00:00.000+03:00", dt.toString());
94          DateTime rounded = dt.dayOfMonth().roundFloorCopy();
95          assertEquals("2007-04-01T01:00:00.000+03:00", rounded.toString());
96      }
97  
98      public void test_DateTime_roundCeiling_Gaza() {
99          DateTime dt = new DateTime(2007, 3, 31, 20, 0, 0, 0, MOCK_GAZA);
100         assertEquals("2007-03-31T20:00:00.000+02:00", dt.toString());
101         DateTime rounded = dt.dayOfMonth().roundCeilingCopy();
102         assertEquals("2007-04-01T01:00:00.000+03:00", rounded.toString());
103     }
104 
105     public void test_DateTime_setHourZero_Gaza() {
106         DateTime dt = new DateTime(2007, 4, 1, 8, 0, 0, 0, MOCK_GAZA);
107         assertEquals("2007-04-01T08:00:00.000+03:00", dt.toString());
108         try {
109             dt.hourOfDay().setCopy(0);
110             fail();
111         } catch (IllegalFieldValueException ex) {
112             // expected
113         }
114     }
115 
116     public void test_DateTime_withHourZero_Gaza() {
117         DateTime dt = new DateTime(2007, 4, 1, 8, 0, 0, 0, MOCK_GAZA);
118         assertEquals("2007-04-01T08:00:00.000+03:00", dt.toString());
119         try {
120             dt.withHourOfDay(0);
121             fail();
122         } catch (IllegalFieldValueException ex) {
123             // expected
124         }
125     }
126 
127     public void test_DateTime_withDay_Gaza() {
128         DateTime dt = new DateTime(2007, 4, 2, 0, 0, 0, 0, MOCK_GAZA);
129         assertEquals("2007-04-02T00:00:00.000+03:00", dt.toString());
130         DateTime res = dt.withDayOfMonth(1);
131         assertEquals("2007-04-01T01:00:00.000+03:00", res.toString());
132     }
133 
134     public void test_DateTime_minusHour_Gaza() {
135         DateTime dt = new DateTime(2007, 4, 1, 8, 0, 0, 0, MOCK_GAZA);
136         assertEquals("2007-04-01T08:00:00.000+03:00", dt.toString());
137         
138         DateTime minus7 = dt.minusHours(7);
139         assertEquals("2007-04-01T01:00:00.000+03:00", minus7.toString());
140         DateTime minus8 = dt.minusHours(8);
141         assertEquals("2007-03-31T23:00:00.000+02:00", minus8.toString());
142         DateTime minus9 = dt.minusHours(9);
143         assertEquals("2007-03-31T22:00:00.000+02:00", minus9.toString());
144     }
145 
146     public void test_DateTime_plusHour_Gaza() {
147         DateTime dt = new DateTime(2007, 3, 31, 16, 0, 0, 0, MOCK_GAZA);
148         assertEquals("2007-03-31T16:00:00.000+02:00", dt.toString());
149         
150         DateTime plus7 = dt.plusHours(7);
151         assertEquals("2007-03-31T23:00:00.000+02:00", plus7.toString());
152         DateTime plus8 = dt.plusHours(8);
153         assertEquals("2007-04-01T01:00:00.000+03:00", plus8.toString());
154         DateTime plus9 = dt.plusHours(9);
155         assertEquals("2007-04-01T02:00:00.000+03:00", plus9.toString());
156     }
157 
158     public void test_DateTime_minusDay_Gaza() {
159         DateTime dt = new DateTime(2007, 4, 2, 0, 0, 0, 0, MOCK_GAZA);
160         assertEquals("2007-04-02T00:00:00.000+03:00", dt.toString());
161         
162         DateTime minus1 = dt.minusDays(1);
163         assertEquals("2007-04-01T01:00:00.000+03:00", minus1.toString());
164         DateTime minus2 = dt.minusDays(2);
165         assertEquals("2007-03-31T00:00:00.000+02:00", minus2.toString());
166     }
167 
168     public void test_DateTime_plusDay_Gaza() {
169         DateTime dt = new DateTime(2007, 3, 31, 0, 0, 0, 0, MOCK_GAZA);
170         assertEquals("2007-03-31T00:00:00.000+02:00", dt.toString());
171         
172         DateTime plus1 = dt.plusDays(1);
173         assertEquals("2007-04-01T01:00:00.000+03:00", plus1.toString());
174         DateTime plus2 = dt.plusDays(2);
175         assertEquals("2007-04-02T00:00:00.000+03:00", plus2.toString());
176     }
177 
178     public void test_DateTime_plusDayMidGap_Gaza() {
179         DateTime dt = new DateTime(2007, 3, 31, 0, 30, 0, 0, MOCK_GAZA);
180         assertEquals("2007-03-31T00:30:00.000+02:00", dt.toString());
181         
182         DateTime plus1 = dt.plusDays(1);
183         assertEquals("2007-04-01T01:30:00.000+03:00", plus1.toString());
184         DateTime plus2 = dt.plusDays(2);
185         assertEquals("2007-04-02T00:30:00.000+03:00", plus2.toString());
186     }
187 
188     public void test_DateTime_addWrapFieldDay_Gaza() {
189         DateTime dt = new DateTime(2007, 4, 30, 0, 0, 0, 0, MOCK_GAZA);
190         assertEquals("2007-04-30T00:00:00.000+03:00", dt.toString());
191         
192         DateTime plus1 = dt.dayOfMonth().addWrapFieldToCopy(1);
193         assertEquals("2007-04-01T01:00:00.000+03:00", plus1.toString());
194         DateTime plus2 = dt.dayOfMonth().addWrapFieldToCopy(2);
195         assertEquals("2007-04-02T00:00:00.000+03:00", plus2.toString());
196     }
197 
198     public void test_DateTime_withZoneRetainFields_Gaza() {
199         DateTime dt = new DateTime(2007, 4, 1, 0, 0, 0, 0, DateTimeZone.UTC);
200         assertEquals("2007-04-01T00:00:00.000Z", dt.toString());
201         
202         DateTime res = dt.withZoneRetainFields(MOCK_GAZA);
203         assertEquals("2007-04-01T01:00:00.000+03:00", res.toString());
204     }
205 
206     public void test_MutableDateTime_withZoneRetainFields_Gaza() {
207         MutableDateTime dt = new MutableDateTime(2007, 4, 1, 0, 0, 0, 0, DateTimeZone.UTC);
208         assertEquals("2007-04-01T00:00:00.000Z", dt.toString());
209         
210         dt.setZoneRetainFields(MOCK_GAZA);
211         assertEquals("2007-04-01T01:00:00.000+03:00", dt.toString());
212     }
213 
214     public void test_LocalDate_new_Gaza() {
215         LocalDate date1 = new LocalDate(CUTOVER_GAZA, MOCK_GAZA);
216         assertEquals("2007-04-01", date1.toString());
217         
218         LocalDate date2 = new LocalDate(CUTOVER_GAZA - 1, MOCK_GAZA);
219         assertEquals("2007-03-31", date2.toString());
220     }
221 
222     public void test_LocalDate_toDateMidnight_Gaza() {
223         LocalDate date = new LocalDate(2007, 4, 1);
224         try {
225             date.toDateMidnight(MOCK_GAZA);
226             fail();
227         } catch (IllegalInstantException ex) {
228             assertEquals(true, ex.getMessage().startsWith("Illegal instant due to time zone offset transition"));
229         }
230     }
231 
232     public void test_DateTime_new_Gaza() {
233         try {
234             new DateTime(2007, 4, 1, 0, 0, 0, 0, MOCK_GAZA);
235             fail();
236         } catch (IllegalInstantException ex) {
237             assertEquals(true, ex.getMessage().indexOf("Illegal instant due to time zone offset transition") >= 0);
238         }
239     }
240 
241     public void test_DateTime_newValid_Gaza() {
242         new DateTime(2007, 3, 31, 19, 0, 0, 0, MOCK_GAZA);
243         new DateTime(2007, 3, 31, 20, 0, 0, 0, MOCK_GAZA);
244         new DateTime(2007, 3, 31, 21, 0, 0, 0, MOCK_GAZA);
245         new DateTime(2007, 3, 31, 22, 0, 0, 0, MOCK_GAZA);
246         new DateTime(2007, 3, 31, 23, 0, 0, 0, MOCK_GAZA);
247         new DateTime(2007, 4, 1, 1, 0, 0, 0, MOCK_GAZA);
248         new DateTime(2007, 4, 1, 2, 0, 0, 0, MOCK_GAZA);
249         new DateTime(2007, 4, 1, 3, 0, 0, 0, MOCK_GAZA);
250     }
251 
252     public void test_DateTime_parse_Gaza() {
253         try {
254             new DateTime("2007-04-01T00:00", MOCK_GAZA);
255             fail();
256         } catch (IllegalInstantException ex) {
257             assertEquals(true, ex.getMessage().indexOf("Illegal instant due to time zone offset transition") >= 0);
258         }
259     }
260 
261     //-----------------------------------------------------------------------
262     //------------------------ Bug [1710316] --------------------------------
263     //-----------------------------------------------------------------------
264     /** Mock zone simulating America/Grand_Turk cutover at midnight 2007-04-01 */
265     private static long CUTOVER_TURK = 1175403600000L;
266     private static int OFFSET_TURK = -18000000;  // -05:00
267     private static final DateTimeZone MOCK_TURK = new MockZone(CUTOVER_TURK, OFFSET_TURK, 3600);
268 
269     //-----------------------------------------------------------------------
270     public void test_MockTurkIsCorrect() {
271         DateTime pre = new DateTime(CUTOVER_TURK - 1L, MOCK_TURK);
272         assertEquals("2007-03-31T23:59:59.999-05:00", pre.toString());
273         DateTime at = new DateTime(CUTOVER_TURK, MOCK_TURK);
274         assertEquals("2007-04-01T01:00:00.000-04:00", at.toString());
275         DateTime post = new DateTime(CUTOVER_TURK + 1L, MOCK_TURK);
276         assertEquals("2007-04-01T01:00:00.001-04:00", post.toString());
277     }
278 
279     public void test_getOffsetFromLocal_Turk() {
280         doTest_getOffsetFromLocal_Turk(-1, 23, 0, "2007-03-31T23:00:00.000-05:00");
281         doTest_getOffsetFromLocal_Turk(-1, 23, 30, "2007-03-31T23:30:00.000-05:00");
282         doTest_getOffsetFromLocal_Turk(0, 0, 0, "2007-04-01T01:00:00.000-04:00");
283         doTest_getOffsetFromLocal_Turk(0, 0, 30, "2007-04-01T01:30:00.000-04:00");
284         doTest_getOffsetFromLocal_Turk(0, 1, 0, "2007-04-01T01:00:00.000-04:00");
285         doTest_getOffsetFromLocal_Turk(0, 1, 30, "2007-04-01T01:30:00.000-04:00");
286         doTest_getOffsetFromLocal_Turk(0, 2, 0, "2007-04-01T02:00:00.000-04:00");
287         doTest_getOffsetFromLocal_Turk(0, 3, 0, "2007-04-01T03:00:00.000-04:00");
288         doTest_getOffsetFromLocal_Turk(0, 4, 0, "2007-04-01T04:00:00.000-04:00");
289         doTest_getOffsetFromLocal_Turk(0, 5, 0, "2007-04-01T05:00:00.000-04:00");
290         doTest_getOffsetFromLocal_Turk(0, 6, 0, "2007-04-01T06:00:00.000-04:00");
291     }
292 
293     private void doTest_getOffsetFromLocal_Turk(int days, int hour, int min, String expected) {
294         DateTime dt = new DateTime(2007, 4, 1, hour, min, 0, 0, DateTimeZone.UTC).plusDays(days);
295         int offset = MOCK_TURK.getOffsetFromLocal(dt.getMillis());
296         DateTime res = new DateTime(dt.getMillis() - offset, MOCK_TURK);
297         assertEquals(res.toString(), expected, res.toString());
298     }
299 
300     public void test_DateTime_roundFloor_Turk() {
301         DateTime dt = new DateTime(2007, 4, 1, 8, 0, 0, 0, MOCK_TURK);
302         assertEquals("2007-04-01T08:00:00.000-04:00", dt.toString());
303         DateTime rounded = dt.dayOfMonth().roundFloorCopy();
304         assertEquals("2007-04-01T01:00:00.000-04:00", rounded.toString());
305     }
306 
307     public void test_DateTime_roundFloorNotDST_Turk() {
308         DateTime dt = new DateTime(2007, 4, 2, 8, 0, 0, 0, MOCK_TURK);
309         assertEquals("2007-04-02T08:00:00.000-04:00", dt.toString());
310         DateTime rounded = dt.dayOfMonth().roundFloorCopy();
311         assertEquals("2007-04-02T00:00:00.000-04:00", rounded.toString());
312     }
313 
314     public void test_DateTime_roundCeiling_Turk() {
315         DateTime dt = new DateTime(2007, 3, 31, 20, 0, 0, 0, MOCK_TURK);
316         assertEquals("2007-03-31T20:00:00.000-05:00", dt.toString());
317         DateTime rounded = dt.dayOfMonth().roundCeilingCopy();
318         assertEquals("2007-04-01T01:00:00.000-04:00", rounded.toString());
319     }
320 
321     public void test_DateTime_setHourZero_Turk() {
322         DateTime dt = new DateTime(2007, 4, 1, 8, 0, 0, 0, MOCK_TURK);
323         assertEquals("2007-04-01T08:00:00.000-04:00", dt.toString());
324         try {
325             dt.hourOfDay().setCopy(0);
326             fail();
327         } catch (IllegalFieldValueException ex) {
328             // expected
329         }
330     }
331 
332     public void test_DateTime_withHourZero_Turk() {
333         DateTime dt = new DateTime(2007, 4, 1, 8, 0, 0, 0, MOCK_TURK);
334         assertEquals("2007-04-01T08:00:00.000-04:00", dt.toString());
335         try {
336             dt.withHourOfDay(0);
337             fail();
338         } catch (IllegalFieldValueException ex) {
339             // expected
340         }
341     }
342 
343     public void test_DateTime_withDay_Turk() {
344         DateTime dt = new DateTime(2007, 4, 2, 0, 0, 0, 0, MOCK_TURK);
345         assertEquals("2007-04-02T00:00:00.000-04:00", dt.toString());
346         DateTime res = dt.withDayOfMonth(1);
347         assertEquals("2007-04-01T01:00:00.000-04:00", res.toString());
348     }
349 
350     public void test_DateTime_minusHour_Turk() {
351         DateTime dt = new DateTime(2007, 4, 1, 8, 0, 0, 0, MOCK_TURK);
352         assertEquals("2007-04-01T08:00:00.000-04:00", dt.toString());
353         
354         DateTime minus7 = dt.minusHours(7);
355         assertEquals("2007-04-01T01:00:00.000-04:00", minus7.toString());
356         DateTime minus8 = dt.minusHours(8);
357         assertEquals("2007-03-31T23:00:00.000-05:00", minus8.toString());
358         DateTime minus9 = dt.minusHours(9);
359         assertEquals("2007-03-31T22:00:00.000-05:00", minus9.toString());
360     }
361 
362     public void test_DateTime_plusHour_Turk() {
363         DateTime dt = new DateTime(2007, 3, 31, 16, 0, 0, 0, MOCK_TURK);
364         assertEquals("2007-03-31T16:00:00.000-05:00", dt.toString());
365         
366         DateTime plus7 = dt.plusHours(7);
367         assertEquals("2007-03-31T23:00:00.000-05:00", plus7.toString());
368         DateTime plus8 = dt.plusHours(8);
369         assertEquals("2007-04-01T01:00:00.000-04:00", plus8.toString());
370         DateTime plus9 = dt.plusHours(9);
371         assertEquals("2007-04-01T02:00:00.000-04:00", plus9.toString());
372     }
373 
374     public void test_DateTime_minusDay_Turk() {
375         DateTime dt = new DateTime(2007, 4, 2, 0, 0, 0, 0, MOCK_TURK);
376         assertEquals("2007-04-02T00:00:00.000-04:00", dt.toString());
377         
378         DateTime minus1 = dt.minusDays(1);
379         assertEquals("2007-04-01T01:00:00.000-04:00", minus1.toString());
380         DateTime minus2 = dt.minusDays(2);
381         assertEquals("2007-03-31T00:00:00.000-05:00", minus2.toString());
382     }
383 
384     public void test_DateTime_plusDay_Turk() {
385         DateTime dt = new DateTime(2007, 3, 31, 0, 0, 0, 0, MOCK_TURK);
386         assertEquals("2007-03-31T00:00:00.000-05:00", dt.toString());
387         
388         DateTime plus1 = dt.plusDays(1);
389         assertEquals("2007-04-01T01:00:00.000-04:00", plus1.toString());
390         DateTime plus2 = dt.plusDays(2);
391         assertEquals("2007-04-02T00:00:00.000-04:00", plus2.toString());
392     }
393 
394     public void test_DateTime_plusDayMidGap_Turk() {
395         DateTime dt = new DateTime(2007, 3, 31, 0, 30, 0, 0, MOCK_TURK);
396         assertEquals("2007-03-31T00:30:00.000-05:00", dt.toString());
397         
398         DateTime plus1 = dt.plusDays(1);
399         assertEquals("2007-04-01T01:30:00.000-04:00", plus1.toString());
400         DateTime plus2 = dt.plusDays(2);
401         assertEquals("2007-04-02T00:30:00.000-04:00", plus2.toString());
402     }
403 
404     public void test_DateTime_addWrapFieldDay_Turk() {
405         DateTime dt = new DateTime(2007, 4, 30, 0, 0, 0, 0, MOCK_TURK);
406         assertEquals("2007-04-30T00:00:00.000-04:00", dt.toString());
407         
408         DateTime plus1 = dt.dayOfMonth().addWrapFieldToCopy(1);
409         assertEquals("2007-04-01T01:00:00.000-04:00", plus1.toString());
410         DateTime plus2 = dt.dayOfMonth().addWrapFieldToCopy(2);
411         assertEquals("2007-04-02T00:00:00.000-04:00", plus2.toString());
412     }
413 
414     public void test_DateTime_withZoneRetainFields_Turk() {
415         DateTime dt = new DateTime(2007, 4, 1, 0, 0, 0, 0, DateTimeZone.UTC);
416         assertEquals("2007-04-01T00:00:00.000Z", dt.toString());
417         
418         DateTime res = dt.withZoneRetainFields(MOCK_TURK);
419         assertEquals("2007-04-01T01:00:00.000-04:00", res.toString());
420     }
421 
422     public void test_MutableDateTime_setZoneRetainFields_Turk() {
423         MutableDateTime dt = new MutableDateTime(2007, 4, 1, 0, 0, 0, 0, DateTimeZone.UTC);
424         assertEquals("2007-04-01T00:00:00.000Z", dt.toString());
425         
426         dt.setZoneRetainFields(MOCK_TURK);
427         assertEquals("2007-04-01T01:00:00.000-04:00", dt.toString());
428     }
429 
430     public void test_LocalDate_new_Turk() {
431         LocalDate date1 = new LocalDate(CUTOVER_TURK, MOCK_TURK);
432         assertEquals("2007-04-01", date1.toString());
433         
434         LocalDate date2 = new LocalDate(CUTOVER_TURK - 1, MOCK_TURK);
435         assertEquals("2007-03-31", date2.toString());
436     }
437 
438     public void test_LocalDate_toDateMidnight_Turk() {
439         LocalDate date = new LocalDate(2007, 4, 1);
440         try {
441             date.toDateMidnight(MOCK_TURK);
442             fail();
443         } catch (IllegalInstantException ex) {
444             assertEquals(true, ex.getMessage().startsWith("Illegal instant due to time zone offset transition"));
445         }
446     }
447 
448     public void test_DateTime_new_Turk() {
449         try {
450             new DateTime(2007, 4, 1, 0, 0, 0, 0, MOCK_TURK);
451             fail();
452         } catch (IllegalInstantException ex) {
453             assertEquals(true, ex.getMessage().indexOf("Illegal instant due to time zone offset transition") >= 0);
454         }
455     }
456 
457     public void test_DateTime_newValid_Turk() {
458         new DateTime(2007, 3, 31, 23, 0, 0, 0, MOCK_TURK);
459         new DateTime(2007, 4, 1, 1, 0, 0, 0, MOCK_TURK);
460         new DateTime(2007, 4, 1, 2, 0, 0, 0, MOCK_TURK);
461         new DateTime(2007, 4, 1, 3, 0, 0, 0, MOCK_TURK);
462         new DateTime(2007, 4, 1, 4, 0, 0, 0, MOCK_TURK);
463         new DateTime(2007, 4, 1, 5, 0, 0, 0, MOCK_TURK);
464         new DateTime(2007, 4, 1, 6, 0, 0, 0, MOCK_TURK);
465     }
466 
467     public void test_DateTime_parse_Turk() {
468         try {
469             new DateTime("2007-04-01T00:00", MOCK_TURK);
470             fail();
471         } catch (IllegalInstantException ex) {
472             assertEquals(true, ex.getMessage().indexOf("Illegal instant due to time zone offset transition") >= 0);
473         }
474     }
475 
476     //-----------------------------------------------------------------------
477     //-----------------------------------------------------------------------
478     //-----------------------------------------------------------------------
479     /** America/New_York cutover from 01:59 to 03:00 on 2007-03-11 */
480     private static long CUTOVER_NEW_YORK_SPRING = 1173596400000L;  // 2007-03-11T03:00:00.000-04:00
481     private static final DateTimeZone ZONE_NEW_YORK = DateTimeZone.forID("America/New_York");
482 //  DateTime x = new DateTime(2007, 1, 1, 0, 0, 0, 0, ZONE_NEW_YORK);
483 //  System.out.println(ZONE_NEW_YORK.nextTransition(x.getMillis()));
484 //  DateTime y = new DateTime(ZONE_NEW_YORK.nextTransition(x.getMillis()), ZONE_NEW_YORK);
485 //  System.out.println(y);
486 
487     //-----------------------------------------------------------------------
488     public void test_NewYorkIsCorrect_Spring() {
489         DateTime pre = new DateTime(CUTOVER_NEW_YORK_SPRING - 1L, ZONE_NEW_YORK);
490         assertEquals("2007-03-11T01:59:59.999-05:00", pre.toString());
491         DateTime at = new DateTime(CUTOVER_NEW_YORK_SPRING, ZONE_NEW_YORK);
492         assertEquals("2007-03-11T03:00:00.000-04:00", at.toString());
493         DateTime post = new DateTime(CUTOVER_NEW_YORK_SPRING + 1L, ZONE_NEW_YORK);
494         assertEquals("2007-03-11T03:00:00.001-04:00", post.toString());
495     }
496 
497     public void test_getOffsetFromLocal_NewYork_Spring() {
498         doTest_getOffsetFromLocal(3, 11, 1, 0, "2007-03-11T01:00:00.000-05:00", ZONE_NEW_YORK);
499         doTest_getOffsetFromLocal(3, 11, 1,30, "2007-03-11T01:30:00.000-05:00", ZONE_NEW_YORK);
500         
501         doTest_getOffsetFromLocal(3, 11, 2, 0, "2007-03-11T03:00:00.000-04:00", ZONE_NEW_YORK);
502         doTest_getOffsetFromLocal(3, 11, 2,30, "2007-03-11T03:30:00.000-04:00", ZONE_NEW_YORK);
503         
504         doTest_getOffsetFromLocal(3, 11, 3, 0, "2007-03-11T03:00:00.000-04:00", ZONE_NEW_YORK);
505         doTest_getOffsetFromLocal(3, 11, 3,30, "2007-03-11T03:30:00.000-04:00", ZONE_NEW_YORK);
506         doTest_getOffsetFromLocal(3, 11, 4, 0, "2007-03-11T04:00:00.000-04:00", ZONE_NEW_YORK);
507         doTest_getOffsetFromLocal(3, 11, 5, 0, "2007-03-11T05:00:00.000-04:00", ZONE_NEW_YORK);
508         doTest_getOffsetFromLocal(3, 11, 6, 0, "2007-03-11T06:00:00.000-04:00", ZONE_NEW_YORK);
509         doTest_getOffsetFromLocal(3, 11, 7, 0, "2007-03-11T07:00:00.000-04:00", ZONE_NEW_YORK);
510         doTest_getOffsetFromLocal(3, 11, 8, 0, "2007-03-11T08:00:00.000-04:00", ZONE_NEW_YORK);
511     }
512 
513     public void test_DateTime_setHourAcross_NewYork_Spring() {
514         DateTime dt = new DateTime(2007, 3, 11, 0, 0, 0, 0, ZONE_NEW_YORK);
515         assertEquals("2007-03-11T00:00:00.000-05:00", dt.toString());
516         DateTime res = dt.hourOfDay().setCopy(4);
517         assertEquals("2007-03-11T04:00:00.000-04:00", res.toString());
518     }
519 
520     public void test_DateTime_setHourForward_NewYork_Spring() {
521         DateTime dt = new DateTime(2007, 3, 11, 0, 0, 0, 0, ZONE_NEW_YORK);
522         assertEquals("2007-03-11T00:00:00.000-05:00", dt.toString());
523         
524         try {
525             dt.hourOfDay().setCopy(2);
526             fail();
527         } catch (IllegalFieldValueException ex) {
528             // expected
529         }
530     }
531 
532     public void test_DateTime_setHourBack_NewYork_Spring() {
533         DateTime dt = new DateTime(2007, 3, 11, 8, 0, 0, 0, ZONE_NEW_YORK);
534         assertEquals("2007-03-11T08:00:00.000-04:00", dt.toString());
535         
536         try {
537             dt.hourOfDay().setCopy(2);
538             fail();
539         } catch (IllegalFieldValueException ex) {
540             // expected
541         }
542     }
543 
544     //-----------------------------------------------------------------------
545     public void test_DateTime_roundFloor_day_NewYork_Spring_preCutover() {
546         DateTime dt = new DateTime(2007, 3, 11, 1, 30, 0, 0, ZONE_NEW_YORK);
547         assertEquals("2007-03-11T01:30:00.000-05:00", dt.toString());
548         DateTime rounded = dt.dayOfMonth().roundFloorCopy();
549         assertEquals("2007-03-11T00:00:00.000-05:00", rounded.toString());
550     }
551 
552     public void test_DateTime_roundFloor_day_NewYork_Spring_postCutover() {
553         DateTime dt = new DateTime(2007, 3, 11, 3, 30, 0, 0, ZONE_NEW_YORK);
554         assertEquals("2007-03-11T03:30:00.000-04:00", dt.toString());
555         DateTime rounded = dt.dayOfMonth().roundFloorCopy();
556         assertEquals("2007-03-11T00:00:00.000-05:00", rounded.toString());
557     }
558 
559     public void test_DateTime_roundFloor_hour_NewYork_Spring_preCutover() {
560         DateTime dt = new DateTime(2007, 3, 11, 1, 30, 0, 0, ZONE_NEW_YORK);
561         assertEquals("2007-03-11T01:30:00.000-05:00", dt.toString());
562         DateTime rounded = dt.hourOfDay().roundFloorCopy();
563         assertEquals("2007-03-11T01:00:00.000-05:00", rounded.toString());
564     }
565 
566     public void test_DateTime_roundFloor_hour_NewYork_Spring_postCutover() {
567         DateTime dt = new DateTime(2007, 3, 11, 3, 30, 0, 0, ZONE_NEW_YORK);
568         assertEquals("2007-03-11T03:30:00.000-04:00", dt.toString());
569         DateTime rounded = dt.hourOfDay().roundFloorCopy();
570         assertEquals("2007-03-11T03:00:00.000-04:00", rounded.toString());
571     }
572 
573     public void test_DateTime_roundFloor_minute_NewYork_Spring_preCutover() {
574         DateTime dt = new DateTime(2007, 3, 11, 1, 30, 40, 0, ZONE_NEW_YORK);
575         assertEquals("2007-03-11T01:30:40.000-05:00", dt.toString());
576         DateTime rounded = dt.minuteOfHour().roundFloorCopy();
577         assertEquals("2007-03-11T01:30:00.000-05:00", rounded.toString());
578     }
579 
580     public void test_DateTime_roundFloor_minute_NewYork_Spring_postCutover() {
581         DateTime dt = new DateTime(2007, 3, 11, 3, 30, 40, 0, ZONE_NEW_YORK);
582         assertEquals("2007-03-11T03:30:40.000-04:00", dt.toString());
583         DateTime rounded = dt.minuteOfHour().roundFloorCopy();
584         assertEquals("2007-03-11T03:30:00.000-04:00", rounded.toString());
585     }
586 
587     //-----------------------------------------------------------------------
588     public void test_DateTime_roundCeiling_day_NewYork_Spring_preCutover() {
589         DateTime dt = new DateTime(2007, 3, 11, 1, 30, 0, 0, ZONE_NEW_YORK);
590         assertEquals("2007-03-11T01:30:00.000-05:00", dt.toString());
591         DateTime rounded = dt.dayOfMonth().roundCeilingCopy();
592         assertEquals("2007-03-12T00:00:00.000-04:00", rounded.toString());
593     }
594 
595     public void test_DateTime_roundCeiling_day_NewYork_Spring_postCutover() {
596         DateTime dt = new DateTime(2007, 3, 11, 3, 30, 0, 0, ZONE_NEW_YORK);
597         assertEquals("2007-03-11T03:30:00.000-04:00", dt.toString());
598         DateTime rounded = dt.dayOfMonth().roundCeilingCopy();
599         assertEquals("2007-03-12T00:00:00.000-04:00", rounded.toString());
600     }
601 
602     public void test_DateTime_roundCeiling_hour_NewYork_Spring_preCutover() {
603         DateTime dt = new DateTime(2007, 3, 11, 1, 30, 0, 0, ZONE_NEW_YORK);
604         assertEquals("2007-03-11T01:30:00.000-05:00", dt.toString());
605         DateTime rounded = dt.hourOfDay().roundCeilingCopy();
606         assertEquals("2007-03-11T03:00:00.000-04:00", rounded.toString());
607     }
608 
609     public void test_DateTime_roundCeiling_hour_NewYork_Spring_postCutover() {
610         DateTime dt = new DateTime(2007, 3, 11, 3, 30, 0, 0, ZONE_NEW_YORK);
611         assertEquals("2007-03-11T03:30:00.000-04:00", dt.toString());
612         DateTime rounded = dt.hourOfDay().roundCeilingCopy();
613         assertEquals("2007-03-11T04:00:00.000-04:00", rounded.toString());
614     }
615 
616     public void test_DateTime_roundCeiling_minute_NewYork_Spring_preCutover() {
617         DateTime dt = new DateTime(2007, 3, 11, 1, 30, 40, 0, ZONE_NEW_YORK);
618         assertEquals("2007-03-11T01:30:40.000-05:00", dt.toString());
619         DateTime rounded = dt.minuteOfHour().roundCeilingCopy();
620         assertEquals("2007-03-11T01:31:00.000-05:00", rounded.toString());
621     }
622 
623     public void test_DateTime_roundCeiling_minute_NewYork_Spring_postCutover() {
624         DateTime dt = new DateTime(2007, 3, 11, 3, 30, 40, 0, ZONE_NEW_YORK);
625         assertEquals("2007-03-11T03:30:40.000-04:00", dt.toString());
626         DateTime rounded = dt.minuteOfHour().roundCeilingCopy();
627         assertEquals("2007-03-11T03:31:00.000-04:00", rounded.toString());
628     }
629 
630     //-----------------------------------------------------------------------
631     /** America/New_York cutover from 01:59 to 01:00 on 2007-11-04 */
632     private static long CUTOVER_NEW_YORK_AUTUMN = 1194156000000L;  // 2007-11-04T01:00:00.000-05:00
633 
634     //-----------------------------------------------------------------------
635     public void test_NewYorkIsCorrect_Autumn() {
636         DateTime pre = new DateTime(CUTOVER_NEW_YORK_AUTUMN - 1L, ZONE_NEW_YORK);
637         assertEquals("2007-11-04T01:59:59.999-04:00", pre.toString());
638         DateTime at = new DateTime(CUTOVER_NEW_YORK_AUTUMN, ZONE_NEW_YORK);
639         assertEquals("2007-11-04T01:00:00.000-05:00", at.toString());
640         DateTime post = new DateTime(CUTOVER_NEW_YORK_AUTUMN + 1L, ZONE_NEW_YORK);
641         assertEquals("2007-11-04T01:00:00.001-05:00", post.toString());
642     }
643 
644     public void test_getOffsetFromLocal_NewYork_Autumn() {
645         doTest_getOffsetFromLocal(11, 4, 0, 0, "2007-11-04T00:00:00.000-04:00", ZONE_NEW_YORK);
646         doTest_getOffsetFromLocal(11, 4, 0,30, "2007-11-04T00:30:00.000-04:00", ZONE_NEW_YORK);
647         
648         doTest_getOffsetFromLocal(11, 4, 1, 0, "2007-11-04T01:00:00.000-04:00", ZONE_NEW_YORK);
649         doTest_getOffsetFromLocal(11, 4, 1,30, "2007-11-04T01:30:00.000-04:00", ZONE_NEW_YORK);
650         
651         doTest_getOffsetFromLocal(11, 4, 2, 0, "2007-11-04T02:00:00.000-05:00", ZONE_NEW_YORK);
652         doTest_getOffsetFromLocal(11, 4, 2,30, "2007-11-04T02:30:00.000-05:00", ZONE_NEW_YORK);
653         doTest_getOffsetFromLocal(11, 4, 3, 0, "2007-11-04T03:00:00.000-05:00", ZONE_NEW_YORK);
654         doTest_getOffsetFromLocal(11, 4, 3,30, "2007-11-04T03:30:00.000-05:00", ZONE_NEW_YORK);
655         doTest_getOffsetFromLocal(11, 4, 4, 0, "2007-11-04T04:00:00.000-05:00", ZONE_NEW_YORK);
656         doTest_getOffsetFromLocal(11, 4, 5, 0, "2007-11-04T05:00:00.000-05:00", ZONE_NEW_YORK);
657         doTest_getOffsetFromLocal(11, 4, 6, 0, "2007-11-04T06:00:00.000-05:00", ZONE_NEW_YORK);
658         doTest_getOffsetFromLocal(11, 4, 7, 0, "2007-11-04T07:00:00.000-05:00", ZONE_NEW_YORK);
659         doTest_getOffsetFromLocal(11, 4, 8, 0, "2007-11-04T08:00:00.000-05:00", ZONE_NEW_YORK);
660     }
661 
662     public void test_DateTime_constructor_NewYork_Autumn() {
663         DateTime dt = new DateTime(2007, 11, 4, 1, 30, ZONE_NEW_YORK);
664         assertEquals("2007-11-04T01:30:00.000-04:00", dt.toString());
665     }
666 
667     public void test_DateTime_plusHour_NewYork_Autumn() {
668         DateTime dt = new DateTime(2007, 11, 3, 18, 0, 0, 0, ZONE_NEW_YORK);
669         assertEquals("2007-11-03T18:00:00.000-04:00", dt.toString());
670         
671         DateTime plus6 = dt.plusHours(6);
672         assertEquals("2007-11-04T00:00:00.000-04:00", plus6.toString());
673         DateTime plus7 = dt.plusHours(7);
674         assertEquals("2007-11-04T01:00:00.000-04:00", plus7.toString());
675         DateTime plus8 = dt.plusHours(8);
676         assertEquals("2007-11-04T01:00:00.000-05:00", plus8.toString());
677         DateTime plus9 = dt.plusHours(9);
678         assertEquals("2007-11-04T02:00:00.000-05:00", plus9.toString());
679     }
680 
681     public void test_DateTime_minusHour_NewYork_Autumn() {
682         DateTime dt = new DateTime(2007, 11, 4, 8, 0, 0, 0, ZONE_NEW_YORK);
683         assertEquals("2007-11-04T08:00:00.000-05:00", dt.toString());
684         
685         DateTime minus6 = dt.minusHours(6);
686         assertEquals("2007-11-04T02:00:00.000-05:00", minus6.toString());
687         DateTime minus7 = dt.minusHours(7);
688         assertEquals("2007-11-04T01:00:00.000-05:00", minus7.toString());
689         DateTime minus8 = dt.minusHours(8);
690         assertEquals("2007-11-04T01:00:00.000-04:00", minus8.toString());
691         DateTime minus9 = dt.minusHours(9);
692         assertEquals("2007-11-04T00:00:00.000-04:00", minus9.toString());
693     }
694 
695     //-----------------------------------------------------------------------
696     public void test_DateTime_roundFloor_day_NewYork_Autumn_preCutover() {
697         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 0, 0, ZONE_NEW_YORK);
698         assertEquals("2007-11-04T01:30:00.000-04:00", dt.toString());
699         DateTime rounded = dt.dayOfMonth().roundFloorCopy();
700         assertEquals("2007-11-04T00:00:00.000-04:00", rounded.toString());
701     }
702 
703     public void test_DateTime_roundFloor_day_NewYork_Autumn_postCutover() {
704         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 0, 0, ZONE_NEW_YORK).plusHours(1);
705         assertEquals("2007-11-04T01:30:00.000-05:00", dt.toString());
706         DateTime rounded = dt.dayOfMonth().roundFloorCopy();
707         assertEquals("2007-11-04T00:00:00.000-04:00", rounded.toString());
708     }
709 
710     public void test_DateTime_roundFloor_hourOfDay_NewYork_Autumn_preCutover() {
711         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 0, 0, ZONE_NEW_YORK);
712         assertEquals("2007-11-04T01:30:00.000-04:00", dt.toString());
713         DateTime rounded = dt.hourOfDay().roundFloorCopy();
714         assertEquals("2007-11-04T01:00:00.000-04:00", rounded.toString());
715     }
716 
717     public void test_DateTime_roundFloor_hourOfDay_NewYork_Autumn_postCutover() {
718         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 0, 0, ZONE_NEW_YORK).plusHours(1);
719         assertEquals("2007-11-04T01:30:00.000-05:00", dt.toString());
720         DateTime rounded = dt.hourOfDay().roundFloorCopy();
721         assertEquals("2007-11-04T01:00:00.000-05:00", rounded.toString());
722     }
723 
724     public void test_DateTime_roundFloor_minuteOfHour_NewYork_Autumn_preCutover() {
725         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 40, 0, ZONE_NEW_YORK);
726         assertEquals("2007-11-04T01:30:40.000-04:00", dt.toString());
727         DateTime rounded = dt.minuteOfHour().roundFloorCopy();
728         assertEquals("2007-11-04T01:30:00.000-04:00", rounded.toString());
729     }
730 
731     public void test_DateTime_roundFloor_minuteOfHour_NewYork_Autumn_postCutover() {
732         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 40, 0, ZONE_NEW_YORK).plusHours(1);
733         assertEquals("2007-11-04T01:30:40.000-05:00", dt.toString());
734         DateTime rounded = dt.minuteOfHour().roundFloorCopy();
735         assertEquals("2007-11-04T01:30:00.000-05:00", rounded.toString());
736     }
737 
738     public void test_DateTime_roundFloor_secondOfMinute_NewYork_Autumn_preCutover() {
739         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 40, 500, ZONE_NEW_YORK);
740         assertEquals("2007-11-04T01:30:40.500-04:00", dt.toString());
741         DateTime rounded = dt.secondOfMinute().roundFloorCopy();
742         assertEquals("2007-11-04T01:30:40.000-04:00", rounded.toString());
743     }
744 
745     public void test_DateTime_roundFloor_secondOfMinute_NewYork_Autumn_postCutover() {
746         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 40, 500, ZONE_NEW_YORK).plusHours(1);
747         assertEquals("2007-11-04T01:30:40.500-05:00", dt.toString());
748         DateTime rounded = dt.secondOfMinute().roundFloorCopy();
749         assertEquals("2007-11-04T01:30:40.000-05:00", rounded.toString());
750     }
751 
752     //-----------------------------------------------------------------------
753     public void test_DateTime_roundCeiling_day_NewYork_Autumn_preCutover() {
754         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 0, 0, ZONE_NEW_YORK);
755         assertEquals("2007-11-04T01:30:00.000-04:00", dt.toString());
756         DateTime rounded = dt.dayOfMonth().roundCeilingCopy();
757         assertEquals("2007-11-05T00:00:00.000-05:00", rounded.toString());
758     }
759 
760     public void test_DateTime_roundCeiling_day_NewYork_Autumn_postCutover() {
761         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 0, 0, ZONE_NEW_YORK).plusHours(1);
762         assertEquals("2007-11-04T01:30:00.000-05:00", dt.toString());
763         DateTime rounded = dt.dayOfMonth().roundCeilingCopy();
764         assertEquals("2007-11-05T00:00:00.000-05:00", rounded.toString());
765     }
766 
767     public void test_DateTime_roundCeiling_hourOfDay_NewYork_Autumn_preCutover() {
768         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 0, 0, ZONE_NEW_YORK);
769         assertEquals("2007-11-04T01:30:00.000-04:00", dt.toString());
770         DateTime rounded = dt.hourOfDay().roundCeilingCopy();
771         assertEquals("2007-11-04T01:00:00.000-05:00", rounded.toString());
772     }
773 
774     public void test_DateTime_roundCeiling_hourOfDay_NewYork_Autumn_postCutover() {
775         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 0, 0, ZONE_NEW_YORK).plusHours(1);
776         assertEquals("2007-11-04T01:30:00.000-05:00", dt.toString());
777         DateTime rounded = dt.hourOfDay().roundCeilingCopy();
778         assertEquals("2007-11-04T02:00:00.000-05:00", rounded.toString());
779     }
780 
781     public void test_DateTime_roundCeiling_minuteOfHour_NewYork_Autumn_preCutover() {
782         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 40, 0, ZONE_NEW_YORK);
783         assertEquals("2007-11-04T01:30:40.000-04:00", dt.toString());
784         DateTime rounded = dt.minuteOfHour().roundCeilingCopy();
785         assertEquals("2007-11-04T01:31:00.000-04:00", rounded.toString());
786     }
787 
788     public void test_DateTime_roundCeiling_minuteOfHour_NewYork_Autumn_postCutover() {
789         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 40, 0, ZONE_NEW_YORK).plusHours(1);
790         assertEquals("2007-11-04T01:30:40.000-05:00", dt.toString());
791         DateTime rounded = dt.minuteOfHour().roundCeilingCopy();
792         assertEquals("2007-11-04T01:31:00.000-05:00", rounded.toString());
793     }
794 
795     public void test_DateTime_roundCeiling_secondOfMinute_NewYork_Autumn_preCutover() {
796         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 40, 500, ZONE_NEW_YORK);
797         assertEquals("2007-11-04T01:30:40.500-04:00", dt.toString());
798         DateTime rounded = dt.secondOfMinute().roundCeilingCopy();
799         assertEquals("2007-11-04T01:30:41.000-04:00", rounded.toString());
800     }
801 
802     public void test_DateTime_roundCeiling_secondOfMinute_NewYork_Autumn_postCutover() {
803         DateTime dt = new DateTime(2007, 11, 4, 1, 30, 40, 500, ZONE_NEW_YORK).plusHours(1);
804         assertEquals("2007-11-04T01:30:40.500-05:00", dt.toString());
805         DateTime rounded = dt.secondOfMinute().roundCeilingCopy();
806         assertEquals("2007-11-04T01:30:41.000-05:00", rounded.toString());
807     }
808 
809     //-----------------------------------------------------------------------
810     /** Europe/Moscow cutover from 01:59 to 03:00 on 2007-03-25 */
811     private static long CUTOVER_MOSCOW_SPRING = 1174777200000L;  // 2007-03-25T03:00:00.000+04:00
812     private static final DateTimeZone ZONE_MOSCOW = DateTimeZone.forID("Europe/Moscow");
813 
814     //-----------------------------------------------------------------------
815     public void test_MoscowIsCorrect_Spring() {
816 //      DateTime x = new DateTime(2007, 7, 1, 0, 0, 0, 0, ZONE_MOSCOW);
817 //      System.out.println(ZONE_MOSCOW.nextTransition(x.getMillis()));
818 //      DateTime y = new DateTime(ZONE_MOSCOW.nextTransition(x.getMillis()), ZONE_MOSCOW);
819 //      System.out.println(y);
820         DateTime pre = new DateTime(CUTOVER_MOSCOW_SPRING - 1L, ZONE_MOSCOW);
821         assertEquals("2007-03-25T01:59:59.999+03:00", pre.toString());
822         DateTime at = new DateTime(CUTOVER_MOSCOW_SPRING, ZONE_MOSCOW);
823         assertEquals("2007-03-25T03:00:00.000+04:00", at.toString());
824         DateTime post = new DateTime(CUTOVER_MOSCOW_SPRING + 1L, ZONE_MOSCOW);
825         assertEquals("2007-03-25T03:00:00.001+04:00", post.toString());
826     }
827 
828     public void test_getOffsetFromLocal_Moscow_Spring() {
829         doTest_getOffsetFromLocal(3, 25, 1, 0, "2007-03-25T01:00:00.000+03:00", ZONE_MOSCOW);
830         doTest_getOffsetFromLocal(3, 25, 1,30, "2007-03-25T01:30:00.000+03:00", ZONE_MOSCOW);
831         
832         doTest_getOffsetFromLocal(3, 25, 2, 0, "2007-03-25T03:00:00.000+04:00", ZONE_MOSCOW);
833         doTest_getOffsetFromLocal(3, 25, 2,30, "2007-03-25T03:30:00.000+04:00", ZONE_MOSCOW);
834         
835         doTest_getOffsetFromLocal(3, 25, 3, 0, "2007-03-25T03:00:00.000+04:00", ZONE_MOSCOW);
836         doTest_getOffsetFromLocal(3, 25, 3,30, "2007-03-25T03:30:00.000+04:00", ZONE_MOSCOW);
837         doTest_getOffsetFromLocal(3, 25, 4, 0, "2007-03-25T04:00:00.000+04:00", ZONE_MOSCOW);
838         doTest_getOffsetFromLocal(3, 25, 5, 0, "2007-03-25T05:00:00.000+04:00", ZONE_MOSCOW);
839         doTest_getOffsetFromLocal(3, 25, 6, 0, "2007-03-25T06:00:00.000+04:00", ZONE_MOSCOW);
840         doTest_getOffsetFromLocal(3, 25, 7, 0, "2007-03-25T07:00:00.000+04:00", ZONE_MOSCOW);
841         doTest_getOffsetFromLocal(3, 25, 8, 0, "2007-03-25T08:00:00.000+04:00", ZONE_MOSCOW);
842     }
843 
844     public void test_DateTime_setHourAcross_Moscow_Spring() {
845         DateTime dt = new DateTime(2007, 3, 25, 0, 0, 0, 0, ZONE_MOSCOW);
846         assertEquals("2007-03-25T00:00:00.000+03:00", dt.toString());
847         DateTime res = dt.hourOfDay().setCopy(4);
848         assertEquals("2007-03-25T04:00:00.000+04:00", res.toString());
849     }
850 
851     public void test_DateTime_setHourForward_Moscow_Spring() {
852         DateTime dt = new DateTime(2007, 3, 25, 0, 0, 0, 0, ZONE_MOSCOW);
853         assertEquals("2007-03-25T00:00:00.000+03:00", dt.toString());
854         
855         try {
856             dt.hourOfDay().setCopy(2);
857             fail();
858         } catch (IllegalFieldValueException ex) {
859             // expected
860         }
861     }
862 
863     public void test_DateTime_setHourBack_Moscow_Spring() {
864         DateTime dt = new DateTime(2007, 3, 25, 8, 0, 0, 0, ZONE_MOSCOW);
865         assertEquals("2007-03-25T08:00:00.000+04:00", dt.toString());
866         
867         try {
868             dt.hourOfDay().setCopy(2);
869             fail();
870         } catch (IllegalFieldValueException ex) {
871             // expected
872         }
873     }
874 
875     //-----------------------------------------------------------------------
876     /** America/New_York cutover from 02:59 to 02:00 on 2007-10-28 */
877     private static long CUTOVER_MOSCOW_AUTUMN = 1193526000000L;  // 2007-10-28T02:00:00.000+03:00
878 
879     //-----------------------------------------------------------------------
880     public void test_MoscowIsCorrect_Autumn() {
881         DateTime pre = new DateTime(CUTOVER_MOSCOW_AUTUMN - 1L, ZONE_MOSCOW);
882         assertEquals("2007-10-28T02:59:59.999+04:00", pre.toString());
883         DateTime at = new DateTime(CUTOVER_MOSCOW_AUTUMN, ZONE_MOSCOW);
884         assertEquals("2007-10-28T02:00:00.000+03:00", at.toString());
885         DateTime post = new DateTime(CUTOVER_MOSCOW_AUTUMN + 1L, ZONE_MOSCOW);
886         assertEquals("2007-10-28T02:00:00.001+03:00", post.toString());
887     }
888 
889     public void test_getOffsetFromLocal_Moscow_Autumn() {
890         doTest_getOffsetFromLocal(10, 28, 0, 0, "2007-10-28T00:00:00.000+04:00", ZONE_MOSCOW);
891         doTest_getOffsetFromLocal(10, 28, 0,30, "2007-10-28T00:30:00.000+04:00", ZONE_MOSCOW);
892         doTest_getOffsetFromLocal(10, 28, 1, 0, "2007-10-28T01:00:00.000+04:00", ZONE_MOSCOW);
893         doTest_getOffsetFromLocal(10, 28, 1,30, "2007-10-28T01:30:00.000+04:00", ZONE_MOSCOW);
894         
895         doTest_getOffsetFromLocal(10, 28, 2, 0, "2007-10-28T02:00:00.000+04:00", ZONE_MOSCOW);
896         doTest_getOffsetFromLocal(10, 28, 2,30, "2007-10-28T02:30:00.000+04:00", ZONE_MOSCOW);
897         doTest_getOffsetFromLocal(10, 28, 2,30,59,999, "2007-10-28T02:30:59.999+04:00", ZONE_MOSCOW);
898         doTest_getOffsetFromLocal(10, 28, 2,59,59,998, "2007-10-28T02:59:59.998+04:00", ZONE_MOSCOW);
899         doTest_getOffsetFromLocal(10, 28, 2,59,59,999, "2007-10-28T02:59:59.999+04:00", ZONE_MOSCOW);
900         
901         doTest_getOffsetFromLocal(10, 28, 3, 0, "2007-10-28T03:00:00.000+03:00", ZONE_MOSCOW);
902         doTest_getOffsetFromLocal(10, 28, 3,30, "2007-10-28T03:30:00.000+03:00", ZONE_MOSCOW);
903         doTest_getOffsetFromLocal(10, 28, 4, 0, "2007-10-28T04:00:00.000+03:00", ZONE_MOSCOW);
904         doTest_getOffsetFromLocal(10, 28, 5, 0, "2007-10-28T05:00:00.000+03:00", ZONE_MOSCOW);
905         doTest_getOffsetFromLocal(10, 28, 6, 0, "2007-10-28T06:00:00.000+03:00", ZONE_MOSCOW);
906         doTest_getOffsetFromLocal(10, 28, 7, 0, "2007-10-28T07:00:00.000+03:00", ZONE_MOSCOW);
907         doTest_getOffsetFromLocal(10, 28, 8, 0, "2007-10-28T08:00:00.000+03:00", ZONE_MOSCOW);
908     }
909 
910     public void test_getOffsetFromLocal_Moscow_Autumn_overlap_mins() {
911         for (int min = 0; min < 60; min++) {
912             if (min < 10) {
913                 doTest_getOffsetFromLocal(10, 28, 2, min, "2007-10-28T02:0" + min + ":00.000+04:00", ZONE_MOSCOW);
914             } else {
915                 doTest_getOffsetFromLocal(10, 28, 2, min, "2007-10-28T02:" + min + ":00.000+04:00", ZONE_MOSCOW);
916             }
917         }
918     }
919 
920     public void test_DateTime_constructor_Moscow_Autumn() {
921         DateTime dt = new DateTime(2007, 10, 28, 2, 30, ZONE_MOSCOW);
922         assertEquals("2007-10-28T02:30:00.000+04:00", dt.toString());
923     }
924 
925     public void test_DateTime_plusHour_Moscow_Autumn() {
926         DateTime dt = new DateTime(2007, 10, 27, 19, 0, 0, 0, ZONE_MOSCOW);
927         assertEquals("2007-10-27T19:00:00.000+04:00", dt.toString());
928         
929         DateTime plus6 = dt.plusHours(6);
930         assertEquals("2007-10-28T01:00:00.000+04:00", plus6.toString());
931         DateTime plus7 = dt.plusHours(7);
932         assertEquals("2007-10-28T02:00:00.000+04:00", plus7.toString());
933         DateTime plus8 = dt.plusHours(8);
934         assertEquals("2007-10-28T02:00:00.000+03:00", plus8.toString());
935         DateTime plus9 = dt.plusHours(9);
936         assertEquals("2007-10-28T03:00:00.000+03:00", plus9.toString());
937     }
938 
939     public void test_DateTime_minusHour_Moscow_Autumn() {
940         DateTime dt = new DateTime(2007, 10, 28, 9, 0, 0, 0, ZONE_MOSCOW);
941         assertEquals("2007-10-28T09:00:00.000+03:00", dt.toString());
942         
943         DateTime minus6 = dt.minusHours(6);
944         assertEquals("2007-10-28T03:00:00.000+03:00", minus6.toString());
945         DateTime minus7 = dt.minusHours(7);
946         assertEquals("2007-10-28T02:00:00.000+03:00", minus7.toString());
947         DateTime minus8 = dt.minusHours(8);
948         assertEquals("2007-10-28T02:00:00.000+04:00", minus8.toString());
949         DateTime minus9 = dt.minusHours(9);
950         assertEquals("2007-10-28T01:00:00.000+04:00", minus9.toString());
951     }
952 
953     //-----------------------------------------------------------------------
954     //-----------------------------------------------------------------------
955     //-----------------------------------------------------------------------
956     /** America/Guatemala cutover from 23:59 to 23:00 on 2006-09-30 */
957     private static long CUTOVER_GUATEMALA_AUTUMN = 1159678800000L; // 2006-09-30T23:00:00.000-06:00
958     private static final DateTimeZone ZONE_GUATEMALA = DateTimeZone.forID("America/Guatemala");
959 
960     //-----------------------------------------------------------------------
961     public void test_GuatemataIsCorrect_Autumn() {
962         DateTime pre = new DateTime(CUTOVER_GUATEMALA_AUTUMN - 1L, ZONE_GUATEMALA);
963         assertEquals("2006-09-30T23:59:59.999-05:00", pre.toString());
964         DateTime at = new DateTime(CUTOVER_GUATEMALA_AUTUMN, ZONE_GUATEMALA);
965         assertEquals("2006-09-30T23:00:00.000-06:00", at.toString());
966         DateTime post = new DateTime(CUTOVER_GUATEMALA_AUTUMN + 1L, ZONE_GUATEMALA);
967         assertEquals("2006-09-30T23:00:00.001-06:00", post.toString());
968     }
969 
970     public void test_getOffsetFromLocal_Guatemata_Autumn() {
971         doTest_getOffsetFromLocal( 2006, 9,30,23, 0,
972                                   "2006-09-30T23:00:00.000-05:00", ZONE_GUATEMALA);
973         doTest_getOffsetFromLocal( 2006, 9,30,23,30,
974                                   "2006-09-30T23:30:00.000-05:00", ZONE_GUATEMALA);
975         
976         doTest_getOffsetFromLocal( 2006, 9,30,23, 0,
977                                   "2006-09-30T23:00:00.000-05:00", ZONE_GUATEMALA);
978         doTest_getOffsetFromLocal( 2006, 9,30,23,30,
979                                   "2006-09-30T23:30:00.000-05:00", ZONE_GUATEMALA);
980         
981         doTest_getOffsetFromLocal( 2006,10, 1, 0, 0,
982                                   "2006-10-01T00:00:00.000-06:00", ZONE_GUATEMALA);
983         doTest_getOffsetFromLocal( 2006,10, 1, 0,30,
984                                   "2006-10-01T00:30:00.000-06:00", ZONE_GUATEMALA);
985         doTest_getOffsetFromLocal( 2006,10, 1, 1, 0,
986                                   "2006-10-01T01:00:00.000-06:00", ZONE_GUATEMALA);
987         doTest_getOffsetFromLocal( 2006,10, 1, 1,30,
988                                   "2006-10-01T01:30:00.000-06:00", ZONE_GUATEMALA);
989         doTest_getOffsetFromLocal( 2006,10, 1, 2, 0,
990                                   "2006-10-01T02:00:00.000-06:00", ZONE_GUATEMALA);
991         doTest_getOffsetFromLocal( 2006,10, 1, 2,30,
992                                   "2006-10-01T02:30:00.000-06:00", ZONE_GUATEMALA);
993         doTest_getOffsetFromLocal( 2006,10, 1, 3, 0,
994                                   "2006-10-01T03:00:00.000-06:00", ZONE_GUATEMALA);
995         doTest_getOffsetFromLocal( 2006,10, 1, 3,30,
996                                   "2006-10-01T03:30:00.000-06:00", ZONE_GUATEMALA);
997         doTest_getOffsetFromLocal( 2006,10, 1, 4, 0,
998                                   "2006-10-01T04:00:00.000-06:00", ZONE_GUATEMALA);
999         doTest_getOffsetFromLocal( 2006,10, 1, 4,30,
1000                                   "2006-10-01T04:30:00.000-06:00", ZONE_GUATEMALA);
1001         doTest_getOffsetFromLocal( 2006,10, 1, 5, 0,
1002                                   "2006-10-01T05:00:00.000-06:00", ZONE_GUATEMALA);
1003         doTest_getOffsetFromLocal( 2006,10, 1, 5,30,
1004                                   "2006-10-01T05:30:00.000-06:00", ZONE_GUATEMALA);
1005         doTest_getOffsetFromLocal( 2006,10, 1, 6, 0,
1006                                   "2006-10-01T06:00:00.000-06:00", ZONE_GUATEMALA);
1007         doTest_getOffsetFromLocal( 2006,10, 1, 6,30,
1008                                   "2006-10-01T06:30:00.000-06:00", ZONE_GUATEMALA);
1009     }
1010 
1011     public void test_DateTime_plusHour_Guatemata_Autumn() {
1012         DateTime dt = new DateTime(2006, 9, 30, 20, 0, 0, 0, ZONE_GUATEMALA);
1013         assertEquals("2006-09-30T20:00:00.000-05:00", dt.toString());
1014         
1015         DateTime plus1 = dt.plusHours(1);
1016         assertEquals("2006-09-30T21:00:00.000-05:00", plus1.toString());
1017         DateTime plus2 = dt.plusHours(2);
1018         assertEquals("2006-09-30T22:00:00.000-05:00", plus2.toString());
1019         DateTime plus3 = dt.plusHours(3);
1020         assertEquals("2006-09-30T23:00:00.000-05:00", plus3.toString());
1021         DateTime plus4 = dt.plusHours(4);
1022         assertEquals("2006-09-30T23:00:00.000-06:00", plus4.toString());
1023         DateTime plus5 = dt.plusHours(5);
1024         assertEquals("2006-10-01T00:00:00.000-06:00", plus5.toString());
1025         DateTime plus6 = dt.plusHours(6);
1026         assertEquals("2006-10-01T01:00:00.000-06:00", plus6.toString());
1027         DateTime plus7 = dt.plusHours(7);
1028         assertEquals("2006-10-01T02:00:00.000-06:00", plus7.toString());
1029     }
1030 
1031     public void test_DateTime_minusHour_Guatemata_Autumn() {
1032         DateTime dt = new DateTime(2006, 10, 1, 2, 0, 0, 0, ZONE_GUATEMALA);
1033         assertEquals("2006-10-01T02:00:00.000-06:00", dt.toString());
1034         
1035         DateTime minus1 = dt.minusHours(1);
1036         assertEquals("2006-10-01T01:00:00.000-06:00", minus1.toString());
1037         DateTime minus2 = dt.minusHours(2);
1038         assertEquals("2006-10-01T00:00:00.000-06:00", minus2.toString());
1039         DateTime minus3 = dt.minusHours(3);
1040         assertEquals("2006-09-30T23:00:00.000-06:00", minus3.toString());
1041         DateTime minus4 = dt.minusHours(4);
1042         assertEquals("2006-09-30T23:00:00.000-05:00", minus4.toString());
1043         DateTime minus5 = dt.minusHours(5);
1044         assertEquals("2006-09-30T22:00:00.000-05:00", minus5.toString());
1045         DateTime minus6 = dt.minusHours(6);
1046         assertEquals("2006-09-30T21:00:00.000-05:00", minus6.toString());
1047         DateTime minus7 = dt.minusHours(7);
1048         assertEquals("2006-09-30T20:00:00.000-05:00", minus7.toString());
1049     }
1050 
1051     //-----------------------------------------------------------------------
1052     //-----------------------------------------------------------------------
1053     //-----------------------------------------------------------------------
1054 
1055     public void test_DateTime_JustAfterLastEverOverlap() {
1056         // based on America/Argentina/Catamarca in file 2009s
1057         DateTimeZone zone = new DateTimeZoneBuilder()
1058             .setStandardOffset(-3 * DateTimeConstants.MILLIS_PER_HOUR)
1059             .addRecurringSavings("SUMMER", 1 * DateTimeConstants.MILLIS_PER_HOUR, 2000, 2008,
1060                                     'w', 4, 10, 0, true, 23 * DateTimeConstants.MILLIS_PER_HOUR)
1061             .addRecurringSavings("WINTER", 0, 2000, 2008,
1062                                     'w', 8, 10, 0, true, 0 * DateTimeConstants.MILLIS_PER_HOUR)
1063             .toDateTimeZone("Zone", false);
1064         
1065         LocalDate date = new LocalDate(2008, 8, 10);
1066         assertEquals("2008-08-10", date.toString());
1067         
1068         DateTime dt = date.toDateTimeAtStartOfDay(zone);
1069         assertEquals("2008-08-10T00:00:00.000-03:00", dt.toString());
1070     }
1071 
1072 //    public void test_toDateMidnight_SaoPaolo() {
1073 //        // RFE: 1684259
1074 //        DateTimeZone zone = DateTimeZone.forID("America/Sao_Paulo");
1075 //        LocalDate baseDate = new LocalDate(2006, 11, 5);
1076 //        DateMidnight dm = baseDate.toDateMidnight(zone);
1077 //        assertEquals("2006-11-05T00:00:00.000-03:00", dm.toString());
1078 //        DateTime dt = baseDate.toDateTimeAtMidnight(zone);
1079 //        assertEquals("2006-11-05T00:00:00.000-03:00", dt.toString());
1080 //    }
1081 
1082     //-----------------------------------------------------------------------
1083     private static final DateTimeZone ZONE_PARIS = DateTimeZone.forID("Europe/Paris");
1084 
1085     public void testWithMinuteOfHourInDstChange_mockZone() {
1086         DateTime cutover = new DateTime(2010, 10, 31, 1, 15, DateTimeZone.forOffsetHoursMinutes(0, 30));
1087         assertEquals("2010-10-31T01:15:00.000+00:30", cutover.toString());
1088         DateTimeZone halfHourZone = new MockZone(cutover.getMillis(), 3600000, -1800);
1089         DateTime pre = new DateTime(2010, 10, 31, 1, 0, halfHourZone);
1090         assertEquals("2010-10-31T01:00:00.000+01:00", pre.toString());
1091         DateTime post = new DateTime(2010, 10, 31, 1, 59, halfHourZone);
1092         assertEquals("2010-10-31T01:59:00.000+00:30", post.toString());
1093         
1094         DateTime testPre1 = pre.withMinuteOfHour(30);
1095         assertEquals("2010-10-31T01:30:00.000+01:00", testPre1.toString());  // retain offset
1096         DateTime testPre2 = pre.withMinuteOfHour(50);
1097         assertEquals("2010-10-31T01:50:00.000+00:30", testPre2.toString());
1098         
1099         DateTime testPost1 = post.withMinuteOfHour(30);
1100         assertEquals("2010-10-31T01:30:00.000+00:30", testPost1.toString());  // retain offset
1101         DateTime testPost2 = post.withMinuteOfHour(10);
1102         assertEquals("2010-10-31T01:10:00.000+01:00", testPost2.toString());
1103     }
1104 
1105     public void testWithHourOfDayInDstChange() {
1106         DateTime dateTime = new DateTime("2010-10-31T02:30:10.123+02:00", ZONE_PARIS);
1107         assertEquals("2010-10-31T02:30:10.123+02:00", dateTime.toString());
1108         DateTime test = dateTime.withHourOfDay(2);
1109         assertEquals("2010-10-31T02:30:10.123+02:00", test.toString());
1110     }
1111 
1112     public void testWithMinuteOfHourInDstChange() {
1113         DateTime dateTime = new DateTime("2010-10-31T02:30:10.123+02:00", ZONE_PARIS);
1114         assertEquals("2010-10-31T02:30:10.123+02:00", dateTime.toString());
1115         DateTime test = dateTime.withMinuteOfHour(0);
1116         assertEquals("2010-10-31T02:00:10.123+02:00", test.toString());
1117     }
1118 
1119     public void testWithSecondOfMinuteInDstChange() {
1120         DateTime dateTime = new DateTime("2010-10-31T02:30:10.123+02:00", ZONE_PARIS);
1121         assertEquals("2010-10-31T02:30:10.123+02:00", dateTime.toString());
1122         DateTime test = dateTime.withSecondOfMinute(0);
1123         assertEquals("2010-10-31T02:30:00.123+02:00", test.toString());
1124     }
1125 
1126     public void testWithMillisOfSecondInDstChange_Paris_summer() {
1127         DateTime dateTime = new DateTime("2010-10-31T02:30:10.123+02:00", ZONE_PARIS);
1128         assertEquals("2010-10-31T02:30:10.123+02:00", dateTime.toString());
1129         DateTime test = dateTime.withMillisOfSecond(0);
1130         assertEquals("2010-10-31T02:30:10.000+02:00", test.toString());
1131     }
1132 
1133     public void testWithMillisOfSecondInDstChange_Paris_winter() {
1134         DateTime dateTime = new DateTime("2010-10-31T02:30:10.123+01:00", ZONE_PARIS);
1135         assertEquals("2010-10-31T02:30:10.123+01:00", dateTime.toString());
1136         DateTime test = dateTime.withMillisOfSecond(0);
1137         assertEquals("2010-10-31T02:30:10.000+01:00", test.toString());
1138     }
1139 
1140     public void testWithMillisOfSecondInDstChange_NewYork_summer() {
1141         DateTime dateTime = new DateTime("2007-11-04T01:30:00.123-04:00", ZONE_NEW_YORK);
1142         assertEquals("2007-11-04T01:30:00.123-04:00", dateTime.toString());
1143         DateTime test = dateTime.withMillisOfSecond(0);
1144         assertEquals("2007-11-04T01:30:00.000-04:00", test.toString());
1145     }
1146 
1147     public void testWithMillisOfSecondInDstChange_NewYork_winter() {
1148         DateTime dateTime = new DateTime("2007-11-04T01:30:00.123-05:00", ZONE_NEW_YORK);
1149         assertEquals("2007-11-04T01:30:00.123-05:00", dateTime.toString());
1150         DateTime test = dateTime.withMillisOfSecond(0);
1151         assertEquals("2007-11-04T01:30:00.000-05:00", test.toString());
1152     }
1153 
1154     public void testPlusMinutesInDstChange() {
1155         DateTime dateTime = new DateTime("2010-10-31T02:30:10.123+02:00", ZONE_PARIS);
1156         assertEquals("2010-10-31T02:30:10.123+02:00", dateTime.toString());
1157         DateTime test = dateTime.plusMinutes(1);
1158         assertEquals("2010-10-31T02:31:10.123+02:00", test.toString());
1159     }
1160 
1161     public void testPlusSecondsInDstChange() {
1162         DateTime dateTime = new DateTime("2010-10-31T02:30:10.123+02:00", ZONE_PARIS);
1163         assertEquals("2010-10-31T02:30:10.123+02:00", dateTime.toString());
1164         DateTime test = dateTime.plusSeconds(1);
1165         assertEquals("2010-10-31T02:30:11.123+02:00", test.toString());
1166     }
1167 
1168     public void testPlusMillisInDstChange() {
1169         DateTime dateTime = new DateTime("2010-10-31T02:30:10.123+02:00", ZONE_PARIS);
1170         assertEquals("2010-10-31T02:30:10.123+02:00", dateTime.toString());
1171         DateTime test = dateTime.plusMillis(1);
1172         assertEquals("2010-10-31T02:30:10.124+02:00", test.toString());
1173     }
1174 
1175     public void testBug2182444_usCentral() {
1176         Chronology chronUSCentral = GregorianChronology.getInstance(DateTimeZone.forID("US/Central"));
1177         Chronology chronUTC = GregorianChronology.getInstance(DateTimeZone.UTC);
1178         DateTime usCentralStandardInUTC = new DateTime(2008, 11, 2, 7, 0, 0, 0, chronUTC);
1179         DateTime usCentralDaylightInUTC = new DateTime(2008, 11, 2, 6, 0, 0, 0, chronUTC);
1180         assertTrue("Should be standard time", chronUSCentral.getZone().isStandardOffset(usCentralStandardInUTC.getMillis()));
1181         assertFalse("Should be daylight time", chronUSCentral.getZone().isStandardOffset(usCentralDaylightInUTC.getMillis()));
1182         
1183         DateTime usCentralStandardInUSCentral = usCentralStandardInUTC.toDateTime(chronUSCentral);
1184         DateTime usCentralDaylightInUSCentral = usCentralDaylightInUTC.toDateTime(chronUSCentral);
1185         assertEquals(1, usCentralStandardInUSCentral.getHourOfDay());
1186         assertEquals(usCentralStandardInUSCentral.getHourOfDay(), usCentralDaylightInUSCentral.getHourOfDay());
1187         assertTrue(usCentralStandardInUSCentral.getMillis() != usCentralDaylightInUSCentral.getMillis());
1188         assertEquals(usCentralStandardInUSCentral, usCentralStandardInUSCentral.withHourOfDay(1));
1189         assertEquals(usCentralStandardInUSCentral.getMillis() + 3, usCentralStandardInUSCentral.withMillisOfSecond(3).getMillis());
1190         assertEquals(usCentralDaylightInUSCentral, usCentralDaylightInUSCentral.withHourOfDay(1));
1191         assertEquals(usCentralDaylightInUSCentral.getMillis() + 3, usCentralDaylightInUSCentral.withMillisOfSecond(3).getMillis());
1192     }
1193 
1194     public void testBug2182444_ausNSW() {
1195         Chronology chronAusNSW = GregorianChronology.getInstance(DateTimeZone.forID("Australia/NSW"));
1196         Chronology chronUTC = GregorianChronology.getInstance(DateTimeZone.UTC);
1197         DateTime australiaNSWStandardInUTC = new DateTime(2008, 4, 5, 16, 0, 0, 0, chronUTC);
1198         DateTime australiaNSWDaylightInUTC = new DateTime(2008, 4, 5, 15, 0, 0, 0, chronUTC);
1199         assertTrue("Should be standard time", chronAusNSW.getZone().isStandardOffset(australiaNSWStandardInUTC.getMillis()));
1200         assertFalse("Should be daylight time", chronAusNSW.getZone().isStandardOffset(australiaNSWDaylightInUTC.getMillis()));
1201         
1202         DateTime australiaNSWStandardInAustraliaNSW = australiaNSWStandardInUTC.toDateTime(chronAusNSW);
1203         DateTime australiaNSWDaylightInAusraliaNSW = australiaNSWDaylightInUTC.toDateTime(chronAusNSW);
1204         assertEquals(2, australiaNSWStandardInAustraliaNSW.getHourOfDay());
1205         assertEquals(australiaNSWStandardInAustraliaNSW.getHourOfDay(), australiaNSWDaylightInAusraliaNSW.getHourOfDay());
1206         assertTrue(australiaNSWStandardInAustraliaNSW.getMillis() != australiaNSWDaylightInAusraliaNSW.getMillis());
1207         assertEquals(australiaNSWStandardInAustraliaNSW, australiaNSWStandardInAustraliaNSW.withHourOfDay(2));
1208         assertEquals(australiaNSWStandardInAustraliaNSW.getMillis() + 3, australiaNSWStandardInAustraliaNSW.withMillisOfSecond(3).getMillis());
1209         assertEquals(australiaNSWDaylightInAusraliaNSW, australiaNSWDaylightInAusraliaNSW.withHourOfDay(2));
1210         assertEquals(australiaNSWDaylightInAusraliaNSW.getMillis() + 3, australiaNSWDaylightInAusraliaNSW.withMillisOfSecond(3).getMillis());
1211     }
1212 
1213     public void testPeriod() {
1214         DateTime a = new DateTime("2010-10-31T02:00:00.000+02:00", ZONE_PARIS);
1215         DateTime b = new DateTime("2010-10-31T02:01:00.000+02:00", ZONE_PARIS);
1216         Period period = new Period(a, b, PeriodType.standard());
1217         assertEquals("PT1M", period.toString());
1218     }
1219 
1220     public void testForum4013394_retainOffsetWhenRetainFields_sameOffsetsDifferentZones() {
1221         final DateTimeZone fromDTZ = DateTimeZone.forID("Europe/London");
1222         final DateTimeZone toDTZ = DateTimeZone.forID("Europe/Lisbon");
1223         DateTime baseBefore = new DateTime(2007, 10, 28, 1, 15, fromDTZ).minusHours(1);
1224         DateTime baseAfter = new DateTime(2007, 10, 28, 1, 15, fromDTZ);
1225         DateTime testBefore = baseBefore.withZoneRetainFields(toDTZ);
1226         DateTime testAfter = baseAfter.withZoneRetainFields(toDTZ);
1227         // toString ignores time-zone but includes offset
1228         assertEquals(baseBefore.toString(), testBefore.toString());
1229         assertEquals(baseAfter.toString(), testAfter.toString());
1230     }
1231 
1232     //-------------------------------------------------------------------------
1233     public void testBug3192457_adjustOffset() {
1234         final DateTimeZone zone = DateTimeZone.forID("Europe/Paris");
1235         DateTime base = new DateTime(2007, 10, 28, 3, 15, zone);
1236         DateTime baseBefore = base.minusHours(2);
1237         DateTime baseAfter = base.minusHours(1);
1238         
1239         assertSame(base, base.withEarlierOffsetAtOverlap());
1240         assertSame(base, base.withLaterOffsetAtOverlap());
1241         
1242         assertSame(baseBefore, baseBefore.withEarlierOffsetAtOverlap());
1243         assertEquals(baseAfter, baseBefore.withLaterOffsetAtOverlap());
1244         
1245         assertSame(baseAfter, baseAfter.withLaterOffsetAtOverlap());
1246         assertEquals(baseBefore, baseAfter.withEarlierOffsetAtOverlap());
1247     }
1248 
1249     public void testBug3476684_adjustOffset() {
1250         final DateTimeZone zone = DateTimeZone.forID("America/Sao_Paulo");
1251         DateTime base = new DateTime(2012, 2, 25, 22, 15, zone);
1252         DateTime baseBefore = base.plusHours(1);  // 23:15 (first)
1253         DateTime baseAfter = base.plusHours(2);  // 23:15 (second)
1254         
1255         assertSame(base, base.withEarlierOffsetAtOverlap());
1256         assertSame(base, base.withLaterOffsetAtOverlap());
1257         
1258         assertSame(baseBefore, baseBefore.withEarlierOffsetAtOverlap());
1259         assertEquals(baseAfter, baseBefore.withLaterOffsetAtOverlap());
1260         
1261         assertSame(baseAfter, baseAfter.withLaterOffsetAtOverlap());
1262         assertEquals(baseBefore, baseAfter.withEarlierOffsetAtOverlap());
1263     }
1264 
1265     public void testBug3476684_adjustOffset_springGap() {
1266       final DateTimeZone zone = DateTimeZone.forID("America/Sao_Paulo");
1267       DateTime base = new DateTime(2011, 10, 15, 22, 15, zone);
1268       DateTime baseBefore = base.plusHours(1);  // 23:15
1269       DateTime baseAfter = base.plusHours(2);  // 01:15
1270       
1271       assertSame(base, base.withEarlierOffsetAtOverlap());
1272       assertSame(base, base.withLaterOffsetAtOverlap());
1273       
1274       assertSame(baseBefore, baseBefore.withEarlierOffsetAtOverlap());
1275       assertEquals(baseBefore, baseBefore.withLaterOffsetAtOverlap());
1276       
1277       assertSame(baseAfter, baseAfter.withLaterOffsetAtOverlap());
1278       assertEquals(baseAfter, baseAfter.withEarlierOffsetAtOverlap());
1279   }
1280 
1281     // ensure Summer time picked
1282     //-----------------------------------------------------------------------
1283     public void testDateTimeCreation_athens() {
1284         DateTimeZone zone = DateTimeZone.forID("Europe/Athens");
1285         DateTime base = new DateTime(2011, 10, 30, 3, 15, zone);
1286         assertEquals("2011-10-30T03:15:00.000+03:00", base.toString());
1287         assertEquals("2011-10-30T03:15:00.000+02:00", base.plusHours(1).toString());
1288     }
1289 
1290     public void testDateTimeCreation_paris() {
1291         DateTimeZone zone = DateTimeZone.forID("Europe/Paris");
1292         DateTime base = new DateTime(2011, 10, 30, 2, 15, zone);
1293         assertEquals("2011-10-30T02:15:00.000+02:00", base.toString());
1294         assertEquals("2011-10-30T02:15:00.000+01:00", base.plusHours(1).toString());
1295     }
1296 
1297     public void testDateTimeCreation_london() {
1298         DateTimeZone zone = DateTimeZone.forID("Europe/London");
1299         DateTime base = new DateTime(2011, 10, 30, 1, 15, zone);
1300         assertEquals("2011-10-30T01:15:00.000+01:00", base.toString());
1301         assertEquals("2011-10-30T01:15:00.000Z", base.plusHours(1).toString());
1302     }
1303 
1304     public void testDateTimeCreation_newYork() {
1305         DateTimeZone zone = DateTimeZone.forID("America/New_York");
1306         DateTime base = new DateTime(2010, 11, 7, 1, 15, zone);
1307         assertEquals("2010-11-07T01:15:00.000-04:00", base.toString());
1308         assertEquals("2010-11-07T01:15:00.000-05:00", base.plusHours(1).toString());
1309     }
1310 
1311     public void testDateTimeCreation_losAngeles() {
1312         DateTimeZone zone = DateTimeZone.forID("America/Los_Angeles");
1313         DateTime base = new DateTime(2010, 11, 7, 1, 15, zone);
1314         assertEquals("2010-11-07T01:15:00.000-07:00", base.toString());
1315         assertEquals("2010-11-07T01:15:00.000-08:00", base.plusHours(1).toString());
1316     }
1317 
1318     //-----------------------------------------------------------------------
1319     //-----------------------------------------------------------------------
1320     //-----------------------------------------------------------------------
1321     private void doTest_getOffsetFromLocal(int month, int day, int hour, int min, String expected, DateTimeZone zone) {
1322         doTest_getOffsetFromLocal(2007, month, day, hour, min, 0, 0, expected, zone);
1323     }
1324 
1325     private void doTest_getOffsetFromLocal(int month, int day, int hour, int min, int sec, int milli, String expected, DateTimeZone zone) {
1326         doTest_getOffsetFromLocal(2007, month, day, hour, min, sec, milli, expected, zone);
1327     }
1328 
1329     private void doTest_getOffsetFromLocal(int year, int month, int day, int hour, int min, String expected, DateTimeZone zone) {
1330         doTest_getOffsetFromLocal(year, month, day, hour, min, 0, 0, expected, zone);
1331     }
1332 
1333     private void doTest_getOffsetFromLocal(int year, int month, int day, int hour, int min, int sec, int milli, String expected, DateTimeZone zone) {
1334         DateTime dt = new DateTime(year, month, day, hour, min, sec, milli, DateTimeZone.UTC);
1335         int offset = zone.getOffsetFromLocal(dt.getMillis());
1336         DateTime res = new DateTime(dt.getMillis() - offset, zone);
1337         assertEquals(res.toString(), expected, res.toString());
1338     }
1339 
1340 }