001    /*
002     *  Copyright 2001-2013 Stephen Colebourne
003     *
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     *  Unless required by applicable law or agreed to in writing, software
011     *  distributed under the License is distributed on an "AS IS" BASIS,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package org.joda.time;
017    
018    import junit.framework.TestCase;
019    import junit.framework.TestSuite;
020    
021    import org.joda.time.chrono.GregorianChronology;
022    import org.joda.time.tz.DateTimeZoneBuilder;
023    
024    /**
025     * This class is a JUnit test for DateTimeZone.
026     *
027     * @author Stephen Colebourne
028     */
029    public class TestDateTimeZoneCutover extends TestCase {
030    
031        public static void main(String[] args) {
032            junit.textui.TestRunner.run(suite());
033        }
034    
035        public static TestSuite suite() {
036            return new TestSuite(TestDateTimeZoneCutover.class);
037        }
038    
039        public TestDateTimeZoneCutover(String name) {
040            super(name);
041        }
042    
043        protected void setUp() throws Exception {
044        }
045    
046        protected void tearDown() throws Exception {
047        }
048    
049        //-----------------------------------------------------------------------
050        //------------------------ Bug [1710316] --------------------------------
051        //-----------------------------------------------------------------------
052        // The behaviour of getOffsetFromLocal is defined in its javadoc
053        // However, this definition doesn't work for all DateTimeField operations
054        
055        /** Mock zone simulating Asia/Gaza cutover at midnight 2007-04-01 */
056        private static long CUTOVER_GAZA = 1175378400000L;
057        private static int OFFSET_GAZA = 7200000;  // +02:00
058        private static final DateTimeZone MOCK_GAZA = new MockZone(CUTOVER_GAZA, OFFSET_GAZA, 3600);
059    
060        //-----------------------------------------------------------------------
061        public void test_MockGazaIsCorrect() {
062            DateTime pre = new DateTime(CUTOVER_GAZA - 1L, MOCK_GAZA);
063            assertEquals("2007-03-31T23:59:59.999+02:00", pre.toString());
064            DateTime at = new DateTime(CUTOVER_GAZA, MOCK_GAZA);
065            assertEquals("2007-04-01T01:00:00.000+03:00", at.toString());
066            DateTime post = new DateTime(CUTOVER_GAZA + 1L, MOCK_GAZA);
067            assertEquals("2007-04-01T01:00:00.001+03:00", post.toString());
068        }
069    
070        public void test_getOffsetFromLocal_Gaza() {
071            doTest_getOffsetFromLocal_Gaza(-1, 23, 0, "2007-03-31T23:00:00.000+02:00");
072            doTest_getOffsetFromLocal_Gaza(-1, 23, 30, "2007-03-31T23:30:00.000+02:00");
073            doTest_getOffsetFromLocal_Gaza(0, 0, 0, "2007-04-01T01:00:00.000+03:00");
074            doTest_getOffsetFromLocal_Gaza(0, 0, 30, "2007-04-01T01:30:00.000+03:00");
075            doTest_getOffsetFromLocal_Gaza(0, 1, 0, "2007-04-01T01:00:00.000+03:00");
076            doTest_getOffsetFromLocal_Gaza(0, 1, 30, "2007-04-01T01:30:00.000+03:00");
077            doTest_getOffsetFromLocal_Gaza(0, 2, 0, "2007-04-01T02:00:00.000+03:00");
078            doTest_getOffsetFromLocal_Gaza(0, 3, 0, "2007-04-01T03:00:00.000+03:00");
079            doTest_getOffsetFromLocal_Gaza(0, 4, 0, "2007-04-01T04:00:00.000+03:00");
080            doTest_getOffsetFromLocal_Gaza(0, 5, 0, "2007-04-01T05:00:00.000+03:00");
081            doTest_getOffsetFromLocal_Gaza(0, 6, 0, "2007-04-01T06:00:00.000+03:00");
082        }
083    
084        private void doTest_getOffsetFromLocal_Gaza(int days, int hour, int min, String expected) {
085            DateTime dt = new DateTime(2007, 4, 1, hour, min, 0, 0, DateTimeZone.UTC).plusDays(days);
086            int offset = MOCK_GAZA.getOffsetFromLocal(dt.getMillis());
087            DateTime res = new DateTime(dt.getMillis() - offset, MOCK_GAZA);
088            assertEquals(res.toString(), expected, res.toString());
089        }
090    
091        public void test_DateTime_roundFloor_Gaza() {
092            DateTime dt = new DateTime(2007, 4, 1, 8, 0, 0, 0, MOCK_GAZA);
093            assertEquals("2007-04-01T08:00:00.000+03:00", dt.toString());
094            DateTime rounded = dt.dayOfMonth().roundFloorCopy();
095            assertEquals("2007-04-01T01:00:00.000+03:00", rounded.toString());
096        }
097    
098        public void test_DateTime_roundCeiling_Gaza() {
099            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    }