/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.j2objc.util; import junit.framework.TestCase; import java.util.Arrays; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; import java.util.TimeZone; /** * Test the NSTimeZone-backed TimeZone implementation class. * * The testing strategy here is by no means comprehensive, but suffices for catching regressions: * if the underlying concrete TimeZone subclass is not based on a time zone database, it will not be * able to handle US time zone changes in 2005 as well as the historical transitions in Australia. * * @author Lukhnos Liu */ public class NativeTimeZoneTest extends TestCase { /** * Test that the TimeZone instance returns accurate offsets for instants in America/Los_Angeles * (commonly known as PT, which includes PST and PDT). This also accounts for the daylight * saving time (DST) change due to Energy Policy Act of 2005. */ public void testUSPacificTimeZoneTransitionsSince1970() { TimeZone la = TimeZone.getTimeZone("America/Los_Angeles"); assertEquals(-25200000, la.getOffset(1457863200000L)); // 2016-03-13T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1446368400000L)); // 2015-11-01T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(1425808800000L)); // 2015-03-08T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1414918800000L)); // 2014-11-02T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(1394359200000L)); // 2014-03-09T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1383469200000L)); // 2013-11-03T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(1362909600000L)); // 2013-03-10T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1352019600000L)); // 2012-11-04T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(1331460000000L)); // 2012-03-11T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1320570000000L)); // 2011-11-06T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(1300010400000L)); // 2011-03-13T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1289120400000L)); // 2010-11-07T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(1268560800000L)); // 2010-03-14T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1257066000000L)); // 2009-11-01T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(1236506400000L)); // 2009-03-08T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1225616400000L)); // 2008-11-02T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(1205056800000L)); // 2008-03-09T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1194166800000L)); // 2007-11-04T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(1173607200000L)); // 2007-03-11T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1162112400000L)); // 2006-10-29T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(1143972000000L)); // 2006-04-02T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1130662800000L)); // 2005-10-30T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(1112522400000L)); // 2005-04-03T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1099213200000L)); // 2004-10-31T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(1081072800000L)); // 2004-04-04T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1067158800000L)); // 2003-10-26T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(1049623200000L)); // 2003-04-06T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1035709200000L)); // 2002-10-27T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(1018173600000L)); // 2002-04-07T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(1004259600000L)); // 2001-10-28T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(986119200000L)); // 2001-04-01T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(972810000000L)); // 2000-10-29T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(954669600000L)); // 2000-04-02T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(941360400000L)); // 1999-10-31T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(923220000000L)); // 1999-04-04T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(909306000000L)); // 1998-10-25T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(891770400000L)); // 1998-04-05T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(877856400000L)); // 1997-10-26T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(860320800000L)); // 1997-04-06T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(846406800000L)); // 1996-10-27T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(828871200000L)); // 1996-04-07T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(814957200000L)); // 1995-10-29T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(796816800000L)); // 1995-04-02T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(783507600000L)); // 1994-10-30T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(765367200000L)); // 1994-04-03T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(752058000000L)); // 1993-10-31T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(733917600000L)); // 1993-04-04T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(720003600000L)); // 1992-10-25T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(702468000000L)); // 1992-04-05T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(688554000000L)); // 1991-10-27T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(671018400000L)); // 1991-04-07T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(657104400000L)); // 1990-10-28T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(638964000000L)); // 1990-04-01T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(625654800000L)); // 1989-10-29T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(607514400000L)); // 1989-04-02T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(594205200000L)); // 1988-10-30T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(576064800000L)); // 1988-04-03T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(562150800000L)); // 1987-10-25T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(544615200000L)); // 1987-04-05T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(530701200000L)); // 1986-10-26T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(514980000000L)); // 1986-04-27T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(499251600000L)); // 1985-10-27T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(483530400000L)); // 1985-04-28T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(467802000000L)); // 1984-10-28T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(452080800000L)); // 1984-04-29T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(436352400000L)); // 1983-10-30T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(420026400000L)); // 1983-04-24T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(404902800000L)); // 1982-10-31T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(388576800000L)); // 1982-04-25T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(372848400000L)); // 1981-10-25T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(357127200000L)); // 1981-04-26T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(341398800000L)); // 1980-10-26T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(325677600000L)); // 1980-04-27T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(309949200000L)); // 1979-10-28T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(294228000000L)); // 1979-04-29T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(278499600000L)); // 1978-10-29T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(262778400000L)); // 1978-04-30T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(247050000000L)); // 1977-10-30T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(230724000000L)); // 1977-04-24T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(215600400000L)); // 1976-10-31T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(199274400000L)); // 1976-04-25T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(183546000000L)); // 1975-10-26T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(162381600000L)); // 1975-02-23T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(152096400000L)); // 1974-10-27T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(126698400000L)); // 1974-01-06T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(120646800000L)); // 1973-10-28T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(104925600000L)); // 1973-04-29T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(89197200000L)); // 1972-10-29T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(73476000000L)); // 1972-04-30T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(57747600000L)); // 1971-10-31T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(41421600000L)); // 1971-04-25T03:00:00.000-07:00 assertEquals(-28800000, la.getOffset(25693200000L)); // 1970-10-25T01:00:00.000-08:00 assertEquals(-25200000, la.getOffset(9972000000L)); // 1970-04-26T03:00:00.000-07:00 } /** * New South Wales observed DST during World War I and World War II, and has been observing DST * since 1971. */ public void testAustraliaEasternTimeZoneTransitions() { TimeZone sydney = TimeZone.getTimeZone("Australia/Sydney"); assertEquals(36000000, sydney.getOffset(1459612800000L)); // 2016-04-03T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1443888000000L)); // 2015-10-04T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(1428163200000L)); // 2015-04-05T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1412438400000L)); // 2014-10-05T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(1396713600000L)); // 2014-04-06T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1380988800000L)); // 2013-10-06T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(1365264000000L)); // 2013-04-07T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1349539200000L)); // 2012-10-07T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(1333209600000L)); // 2012-04-01T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1317484800000L)); // 2011-10-02T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(1301760000000L)); // 2011-04-03T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1286035200000L)); // 2010-10-03T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(1270310400000L)); // 2010-04-04T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1254585600000L)); // 2009-10-04T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(1238860800000L)); // 2009-04-05T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1223136000000L)); // 2008-10-05T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(1207411200000L)); // 2008-04-06T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1193500800000L)); // 2007-10-28T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(1174752000000L)); // 2007-03-25T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1162051200000L)); // 2006-10-29T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(1143907200000L)); // 2006-04-02T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1130601600000L)); // 2005-10-30T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(1111852800000L)); // 2005-03-27T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1099152000000L)); // 2004-10-31T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(1080403200000L)); // 2004-03-28T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1067097600000L)); // 2003-10-26T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(1048953600000L)); // 2003-03-30T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1035648000000L)); // 2002-10-27T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(1017504000000L)); // 2002-03-31T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(1004198400000L)); // 2001-10-28T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(985449600000L)); // 2001-03-25T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(967305600000L)); // 2000-08-27T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(954000000000L)); // 2000-03-26T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(941299200000L)); // 1999-10-31T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(922550400000L)); // 1999-03-28T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(909244800000L)); // 1998-10-25T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(891100800000L)); // 1998-03-29T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(877795200000L)); // 1997-10-26T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(859651200000L)); // 1997-03-30T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(846345600000L)); // 1996-10-27T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(828201600000L)); // 1996-03-31T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(814896000000L)); // 1995-10-29T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(794332800000L)); // 1995-03-05T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(783446400000L)); // 1994-10-30T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(762883200000L)); // 1994-03-06T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(751996800000L)); // 1993-10-31T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(731433600000L)); // 1993-03-07T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(719942400000L)); // 1992-10-25T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(699379200000L)); // 1992-03-01T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(688492800000L)); // 1991-10-27T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(667929600000L)); // 1991-03-03T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(657043200000L)); // 1990-10-28T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(636480000000L)); // 1990-03-04T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(625593600000L)); // 1989-10-29T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(606240000000L)); // 1989-03-19T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(594144000000L)); // 1988-10-30T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(574790400000L)); // 1988-03-20T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(562089600000L)); // 1987-10-25T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(542736000000L)); // 1987-03-15T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(530035200000L)); // 1986-10-19T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(511286400000L)); // 1986-03-16T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(499190400000L)); // 1985-10-27T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(478627200000L)); // 1985-03-03T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(467740800000L)); // 1984-10-28T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(447177600000L)); // 1984-03-04T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(436291200000L)); // 1983-10-30T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(415728000000L)); // 1983-03-06T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(404841600000L)); // 1982-10-31T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(386697600000L)); // 1982-04-04T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(372787200000L)); // 1981-10-25T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(352224000000L)); // 1981-03-01T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(341337600000L)); // 1980-10-26T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(320774400000L)); // 1980-03-02T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(309888000000L)); // 1979-10-28T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(289324800000L)); // 1979-03-04T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(278438400000L)); // 1978-10-29T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(257875200000L)); // 1978-03-05T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(246988800000L)); // 1977-10-30T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(226425600000L)); // 1977-03-06T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(215539200000L)); // 1976-10-31T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(194976000000L)); // 1976-03-07T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(183484800000L)); // 1975-10-26T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(162921600000L)); // 1975-03-02T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(152035200000L)); // 1974-10-27T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(131472000000L)); // 1974-03-03T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(120585600000L)); // 1973-10-28T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(100022400000L)); // 1973-03-04T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(89136000000L)); // 1972-10-29T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(67968000000L)); // 1972-02-27T02:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(57686400000L)); // 1971-10-31T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(-813229200000L)); // 1944-03-26T01:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(-828345600000L)); // 1943-10-03T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(-844678800000L)); // 1943-03-28T01:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(-860400000000L)); // 1942-09-27T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(-876128400000L)); // 1942-03-29T01:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(-883641600000L)); // 1942-01-01T03:00:00.000+11:00 assertEquals(36000000, sydney.getOffset(-1665392400000L)); // 1917-03-25T01:00:00.000+10:00 assertEquals(39600000, sydney.getOffset(-1672567140000L)); // 1917-01-01T01:01:00.000+11:00 assertEquals(36000000, sydney.getOffset(-1672567140001L)); // 1917-01-01T01:00:59.999+10:00 } /** * Test the local date-based offset getter. */ public void testGetOffsetWithLocalDates() { TimeZone la = TimeZone.getTimeZone("America/Los_Angeles"); // Recall Java calendar month is 0-based, and the dayOfWeek, parameter is actually ignored by // some implementations. // 2016-03-12T03:00:00.000-08:00 assertEquals( -28800000, la.getOffset(GregorianCalendar.AD, 2016, 2, 12, Calendar.SATURDAY, 10800000)); // 2016-03-13T01:59:59.999-08:00 assertEquals( -28800000, la.getOffset(GregorianCalendar.AD, 2016, 2, 13, Calendar.SUNDAY, 7200000 - 1)); // 2016-03-13T02:00:00.000-08:00 (but 2 AM that day local time in America/Los_Angeles does not // exist, even though TimeZone returns something that is after the DST transition) assertEquals( -25200000, la.getOffset(GregorianCalendar.AD, 2016, 2, 13, Calendar.SUNDAY, 7200000)); // 2016-03-13T02:30:00.000-08:00 (but 2:30 AM is a non-existent local time) assertEquals( -25200000, la.getOffset(GregorianCalendar.AD, 2016, 2, 13, Calendar.SUNDAY, 9000000)); // 2016-03-13T02:59:59.999-08:00 (but 2:59:59.999 AM is a non-existent local time) assertEquals( -25200000, la.getOffset(GregorianCalendar.AD, 2016, 2, 13, Calendar.SUNDAY, 10800000 - 1)); // 2016-03-13T03:00:00.000-07:00 assertEquals( -25200000, la.getOffset(GregorianCalendar.AD, 2016, 2, 13, Calendar.SUNDAY, 10800000)); // 2016-03-13T03:00:00.001-07:00 assertEquals( -25200000, la.getOffset(GregorianCalendar.AD, 2016, 2, 13, Calendar.SUNDAY, 10800000 + 1)); // 2015-10-31T01:00:00.000-07:00 assertEquals( -25200000, la.getOffset(GregorianCalendar.AD, 2015, 9, 31, Calendar.SATURDAY, 3600000)); // 2015-11-01T00:00:00.000-07:00 assertEquals(-25200000, la.getOffset(GregorianCalendar.AD, 2015, 10, 1, Calendar.SUNDAY, 0)); // 2015-11-01T00:59:59.000-07:00 assertEquals( -25200000, la.getOffset(GregorianCalendar.AD, 2015, 10, 1, Calendar.SUNDAY, 3600000 - 1)); // 2015-11-01T01:00:00.000-08:00 (this is the evidence that TimeZone implementations always // prefer the local datetime in terms of the raw offset). assertEquals( -28800000, la.getOffset(GregorianCalendar.AD, 2015, 10, 1, Calendar.SUNDAY, 3600000)); // 2015-11-01T01:59:59.999-08:00 assertEquals( -28800000, la.getOffset(GregorianCalendar.AD, 2015, 10, 1, Calendar.SUNDAY, 7200000 - 1)); // 2015-11-01T02:00:00.000-08:00 assertEquals( -28800000, la.getOffset(GregorianCalendar.AD, 2015, 10, 1, Calendar.SUNDAY, 7200000)); // Don't test any BC dates as it's meaningless. } /** * Test the locale-dependent display name of a time zone. * * JVM and iOS/OS X don't agree on the localized names, nor do they have the same localization * coverage, and so we are just testing a few shared traits here. */ public void testGetDisplayName() { TimeZone tz = TimeZone.getTimeZone("Europe/Paris"); // JVM says Central European (Summer) Time, OS X/iOS uses Central European Standard/Summer Time. // Short names also differ and are not tested here. assertTrue( tz.getDisplayName(true, TimeZone.LONG, Locale.ENGLISH).startsWith("Central European")); assertTrue(tz.getDisplayName(true, TimeZone.LONG, Locale.ENGLISH).contains("Summer")); assertTrue( tz.getDisplayName(false, TimeZone.LONG, Locale.ENGLISH).startsWith("Central European")); assertFalse(tz.getDisplayName(false, TimeZone.LONG, Locale.ENGLISH).startsWith("Summer")); // French time zone names change across environment and OS versions, and so we only test common // substrings here. final String ete = "été"; // French for "summer" final String avancee = "avancée"; // French for "forward" String frStdName = tz.getDisplayName(false, TimeZone.LONG, Locale.FRANCE); String frDstName = tz.getDisplayName(true, TimeZone.LONG, Locale.FRANCE); assertTrue(frStdName.contains("Europe central")); assertFalse(frStdName.contains(ete) || frStdName.contains(avancee)); assertTrue(frDstName.contains("Europe central")); assertTrue(frDstName.contains(ete) || frDstName.contains(avancee)); // Similarly for German, though they finally agree on the DST name. assertTrue( tz.getDisplayName(true, TimeZone.LONG, Locale.GERMAN) .equals("Mitteleuropäische Sommerzeit")); assertTrue( tz.getDisplayName(false, TimeZone.LONG, Locale.GERMAN).startsWith("Mitteleuropäische")); assertFalse(tz.getDisplayName(false, TimeZone.LONG, Locale.GERMAN).contains("Sommer")); } public void testIsTimeZoneUsingDaylightSavingTime() { assertTrue(TimeZone.getTimeZone("America/Los_Angeles").useDaylightTime()); assertFalse(TimeZone.getTimeZone("America/Phonenix").useDaylightTime()); // No DST in Arizona. assertTrue(TimeZone.getTimeZone("America/Denver").useDaylightTime()); assertTrue(TimeZone.getTimeZone("Europe/Paris").useDaylightTime()); assertTrue(TimeZone.getTimeZone("Australia/Sydney").useDaylightTime()); assertFalse(TimeZone.getTimeZone("Asia/Tokyo").useDaylightTime()); assertFalse(TimeZone.getTimeZone("Asia/Kolkata").useDaylightTime()); } public void testCommonRawOffsets() { assertEquals(-8 * 3600000, TimeZone.getTimeZone("America/Los_Angeles").getRawOffset()); assertEquals(-7 * 3600000, TimeZone.getTimeZone("America/Phoenix").getRawOffset()); assertEquals(-7 * 3600000, TimeZone.getTimeZone("America/Denver").getRawOffset()); assertEquals(-5 * 3600000, TimeZone.getTimeZone("America/New_York").getRawOffset()); assertEquals(19800000, TimeZone.getTimeZone("Asia/Kolkata").getRawOffset()); // UTC+5.54 assertEquals(9 * 3600000, TimeZone.getTimeZone("Asia/Tokyo").getRawOffset()); assertEquals(10 * 3600000, TimeZone.getTimeZone("Australia/Sydney").getRawOffset()); } public void testGetAvailableIds() { List<String> availableIds = Arrays.asList(TimeZone.getAvailableIDs(-7 * 3600000)); assertTrue(availableIds.contains("America/Phoenix")); assertTrue(availableIds.contains("America/Denver")); assertFalse(availableIds.contains("America/Los_Angeles")); } public void testIds() { assertEquals("GMT", TimeZone.getTimeZone("GMT").getID()); assertEquals("UTC", TimeZone.getTimeZone("UTC").getID()); String vmName = System.getProperty("java.vendor"); if (vmName != null && vmName.startsWith("J2ObjC")) { // NSTimeZone handles this custom time zone format and normalizes it. assertEquals("GMT+0530", TimeZone.getTimeZone("GMT+05:30").getID()); } else { assertEquals("GMT+05:30", TimeZone.getTimeZone("GMT+05:30").getID()); } assertEquals("America/New_York", TimeZone.getTimeZone("America/New_York").getID()); assertEquals(TimeZone.getTimeZone("GMT").getID(), TimeZone.getTimeZone("").getID()); // WIP assertEquals(TimeZone.getTimeZone("GMT"), TimeZone.getTimeZone("america/new_york")); } /** * getTimeZone(String) always give you a new instance. */ public void testEqualityAndSameness() { TimeZone a; TimeZone b; a = TimeZone.getTimeZone("GMT"); b = TimeZone.getTimeZone("GMT"); assertEquals(a, b); assertNotSame(a, b); a = TimeZone.getTimeZone("UTC"); b = TimeZone.getTimeZone("UTC"); assertEquals(a, b); assertNotSame(a, b); a = TimeZone.getTimeZone("UTC"); b = TimeZone.getTimeZone("GMT"); assertFalse(a.equals(b)); assertNotSame(a, b); a = TimeZone.getTimeZone("America/New_York"); b = TimeZone.getTimeZone("America/New_York"); assertEquals(a, b); assertNotSame(a, b); } public void testHasSameRules() { TimeZone a; TimeZone b; a = TimeZone.getTimeZone("America/New_York"); b = TimeZone.getTimeZone("US/Eastern"); assertTrue(a.hasSameRules(b)); assertFalse(a.hasSameRules(null)); // Arizona does not observe DST, so even Phoenix and Denver have the same rawOffest, they have // different rules. a = TimeZone.getTimeZone("America/Phoenix"); b = TimeZone.getTimeZone("America/Denver"); assertEquals(a.getRawOffset(), b.getRawOffset()); assertFalse(a.hasSameRules(b)); } /** * Although Android SDK documentation says three-letter time zone IDs other than UTC and GMT are * not supported, actual implementations may still support them. The time zone "EST" is in * practice UTC-5 with the following properties. */ public void testEST() { TimeZone tz = TimeZone.getTimeZone("EST"); assertEquals("EST", tz.getID()); assertFalse(tz.useDaylightTime()); assertEquals(-5 * 3600000, tz.getRawOffset()); assertEquals(0, tz.getDSTSavings()); } /** * PDT is an abbreviation that all three platforms (JVM, Android, and iOS) agree that it's not * supported. On iOS it's not available via +[NSTimeZone timeZoneWithName:] though one can still * get it from +[NSTimeZone timeZoneWithAbbreviation:]. * * PST is a whole different matter. It's usable both as a name and as an abbreviation on iOS. * It's available on JVM, but not on Android. */ public void testNonAvailabilityOfPDT() { TimeZone tz = TimeZone.getTimeZone("PDT"); assertFalse(tz.getID().equals("PDT")); assertFalse(tz.getID().equals("America/Los_Angeles")); assertFalse(tz.getID().equals("US/Pacific")); assertFalse(tz.getRawOffset() == -5 * 3600000); assertFalse(tz.getRawOffset() == -4 * 3600000); } public void testUTCAndGMT() { TimeZone utc = TimeZone.getTimeZone("UTC"); TimeZone gmt = TimeZone.getTimeZone("GMT"); assertEquals("UTC", utc.getID()); assertEquals("GMT", gmt.getID()); // Same rules, but not equal. assertTrue(utc.hasSameRules(gmt)); assertFalse(utc.equals(gmt)); assertEquals(utc.getDSTSavings(), gmt.getDSTSavings()); assertEquals(utc.getRawOffset(), gmt.getRawOffset()); assertEquals(utc.useDaylightTime(), gmt.useDaylightTime()); assertEquals(0, utc.getRawOffset()); assertEquals(0, utc.getDSTSavings()); assertFalse(utc.useDaylightTime()); List<String> ids = Arrays.asList(TimeZone.getAvailableIDs()); assertTrue(ids.contains(gmt.getID())); assertTrue(ids.contains(utc.getID())); } /** * Different time zone libraries treat these two UTC alias differently. On OS X and iOS, * Etc/UTC and Etc/GMT are treated as two different time zones, even if their offset and other * fields are exactly the same as those in UTC. Therefore we don't even attempt to compare their * rules. */ public void testEtcUTCAndEtcGMT() { TimeZone utc = TimeZone.getTimeZone("UTC"); TimeZone etcUtc = TimeZone.getTimeZone("Etc/UTC"); TimeZone etcGmt = TimeZone.getTimeZone("Etc/GMT"); assertEquals("Etc/UTC", etcUtc.getID()); assertEquals("Etc/GMT", etcGmt.getID()); assertEquals(utc.getDSTSavings(), etcGmt.getDSTSavings()); assertEquals(utc.getRawOffset(), etcGmt.getRawOffset()); assertEquals(utc.useDaylightTime(), etcGmt.useDaylightTime()); assertEquals(utc.getDSTSavings(), etcUtc.getDSTSavings()); assertEquals(utc.getRawOffset(), etcUtc.getRawOffset()); assertEquals(utc.useDaylightTime(), etcUtc.useDaylightTime()); assertEquals(0, utc.getRawOffset()); assertEquals(0, utc.getDSTSavings()); assertFalse(utc.useDaylightTime()); List<String> ids = Arrays.asList(TimeZone.getAvailableIDs()); String vmName = System.getProperty("java.vendor"); if (vmName != null && vmName.startsWith("J2ObjC")) { // It's ok for Etc/UTC and Etc/GMT not to be part of TimeZone.getAvailableIDs(). } else { assertTrue(ids.contains(etcGmt.getID())); assertTrue(ids.contains(etcUtc.getID())); } } /** * US/Pacific is an alias to America/Los_Angeles, but the former is not part of the "known names" * reported by NSTimeZone. */ public void testAmericaLosAngelesAndUSPacific() { TimeZone la = TimeZone.getTimeZone("America/Los_Angeles"); TimeZone pacific = TimeZone.getTimeZone("US/Pacific"); assertEquals("America/Los_Angeles", la.getID()); assertEquals("US/Pacific", pacific.getID()); // Same rules, but not equal. assertTrue(pacific.hasSameRules(la)); assertFalse(pacific.equals(la)); assertEquals(la.getDSTSavings(), pacific.getDSTSavings()); assertEquals(la.getRawOffset(), pacific.getRawOffset()); assertEquals(la.useDaylightTime(), pacific.useDaylightTime()); assertEquals(-8 * 3600000L, la.getRawOffset()); assertEquals(3600000L, la.getDSTSavings()); assertTrue(la.useDaylightTime()); List<String> ids = Arrays.asList(TimeZone.getAvailableIDs()); assertTrue(ids.contains(la.getID())); String vmName = System.getProperty("java.vendor"); if (vmName != null && vmName.startsWith("J2ObjC")) { // It's ok for US/Pacific not to be part of TimeZone.getAvailableIDs(). } else { assertTrue(ids.contains(pacific.getID())); } } private static native void postNSSystemTimeZoneDidChangeNotification() /*-[ [[NSNotificationCenter defaultCenter] postNotificationName:NSSystemTimeZoneDidChangeNotification object:nil]; ]-*/; public void testResetDefaultTimeZone() { TimeZone defaultTz = TimeZone.getDefault(); if (defaultTz.getID().equals("Etc/UTC")) { // We assume that the test is never run with the environment TZ=Etc/UTC, but just to be safe. return; } TimeZone.setDefault(TimeZone.getTimeZone("Etc/UTC")); assertEquals("Etc/UTC", TimeZone.getDefault().getID()); // Manually post NSSystemTimeZoneDidChangeNotification, which is dispatched immediately to all // observers. postNSSystemTimeZoneDidChangeNotification(); // The default time zone should be updated. assertNotNull(TimeZone.getDefault()); assertFalse(TimeZone.getDefault().getID().equals("Etc/UTC")); } }