001 /* 002 * Copyright 2001-2005 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.tz; 017 018 import java.io.ByteArrayInputStream; 019 import java.io.ByteArrayOutputStream; 020 import java.io.IOException; 021 022 import junit.framework.TestCase; 023 import junit.framework.TestSuite; 024 025 import org.joda.time.DateTime; 026 import org.joda.time.DateTimeZone; 027 import org.joda.time.format.DateTimeFormatter; 028 import org.joda.time.format.DateTimeFormatterBuilder; 029 030 /** 031 * Test cases for DateTimeZoneBuilder. 032 * 033 * @author Brian S O'Neill 034 */ 035 public class TestBuilder extends TestCase { 036 public static void main(String[] args) { 037 junit.textui.TestRunner.run(suite()); 038 } 039 040 public static TestSuite suite() { 041 return new TestSuite(TestBuilder.class); 042 } 043 044 static final DateTimeFormatter OFFSET_FORMATTER = new DateTimeFormatterBuilder() 045 .appendTimeZoneOffset(null, true, 2, 4) 046 .toFormatter(); 047 048 // Each row is {transition, nameKey, standardOffset, offset} 049 static final String[][] AMERICA_LOS_ANGELES_DATA = { 050 {null, "LMT", "-07:52:58", "-07:52:58"}, 051 {"1883-11-18T19:52:58.000Z", "PST", "-08:00", "-08:00"}, 052 {"1918-03-31T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 053 {"1918-10-27T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 054 {"1919-03-30T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 055 {"1919-10-26T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 056 {"1942-02-09T02:00:00.000-08:00", "PWT", "-08:00", "-07:00"}, 057 {"1945-08-14T23:00:00.000Z", "PPT", "-08:00", "-07:00"}, 058 {"1945-09-30T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 059 {"1948-03-14T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 060 {"1949-01-01T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 061 {"1950-04-30T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 062 {"1950-09-24T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 063 {"1951-04-29T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 064 {"1951-09-30T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 065 {"1952-04-27T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 066 {"1952-09-28T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 067 {"1953-04-26T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 068 {"1953-09-27T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 069 {"1954-04-25T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 070 {"1954-09-26T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 071 {"1955-04-24T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 072 {"1955-09-25T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 073 {"1956-04-29T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 074 {"1956-09-30T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 075 {"1957-04-28T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 076 {"1957-09-29T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 077 {"1958-04-27T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 078 {"1958-09-28T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 079 {"1959-04-26T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 080 {"1959-09-27T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 081 {"1960-04-24T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 082 {"1960-09-25T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 083 {"1961-04-30T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 084 {"1961-09-24T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 085 {"1962-04-29T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 086 {"1962-10-28T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 087 {"1963-04-28T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 088 {"1963-10-27T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 089 {"1964-04-26T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 090 {"1964-10-25T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 091 {"1965-04-25T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 092 {"1965-10-31T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 093 {"1966-04-24T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 094 {"1966-10-30T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 095 {"1967-04-30T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 096 {"1967-10-29T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 097 {"1968-04-28T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 098 {"1968-10-27T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 099 {"1969-04-27T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 100 {"1969-10-26T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 101 {"1970-04-26T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 102 {"1970-10-25T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 103 {"1971-04-25T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 104 {"1971-10-31T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 105 {"1972-04-30T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 106 {"1972-10-29T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 107 {"1973-04-29T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 108 {"1973-10-28T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 109 {"1974-01-06T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 110 {"1974-10-27T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 111 {"1975-02-23T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 112 {"1975-10-26T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 113 {"1976-04-25T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 114 {"1976-10-31T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 115 {"1977-04-24T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 116 {"1977-10-30T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 117 {"1978-04-30T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 118 {"1978-10-29T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 119 {"1979-04-29T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 120 {"1979-10-28T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 121 {"1980-04-27T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 122 {"1980-10-26T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 123 {"1981-04-26T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 124 {"1981-10-25T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 125 {"1982-04-25T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 126 {"1982-10-31T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 127 {"1983-04-24T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 128 {"1983-10-30T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 129 {"1984-04-29T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 130 {"1984-10-28T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 131 {"1985-04-28T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 132 {"1985-10-27T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 133 {"1986-04-27T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 134 {"1986-10-26T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 135 {"1987-04-05T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 136 {"1987-10-25T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 137 {"1988-04-03T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 138 {"1988-10-30T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 139 {"1989-04-02T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 140 {"1989-10-29T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 141 {"1990-04-01T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 142 {"1990-10-28T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 143 {"1991-04-07T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 144 {"1991-10-27T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 145 {"1992-04-05T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 146 {"1992-10-25T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 147 {"1993-04-04T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 148 {"1993-10-31T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 149 {"1994-04-03T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 150 {"1994-10-30T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 151 {"1995-04-02T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 152 {"1995-10-29T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 153 {"1996-04-07T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 154 {"1996-10-27T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 155 {"1997-04-06T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 156 {"1997-10-26T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 157 {"1998-04-05T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 158 {"1998-10-25T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 159 {"1999-04-04T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 160 {"1999-10-31T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 161 {"2000-04-02T02:00:00.000-08:00", "PDT", "-08:00", "-07:00"}, 162 {"2000-10-29T02:00:00.000-07:00", "PST", "-08:00", "-08:00"}, 163 }; 164 165 static DateTimeZoneBuilder buildAmericaLosAngelesBuilder() { 166 return new DateTimeZoneBuilder() 167 .addCutover(-2147483648, 'w', 1, 1, 0, false, 0) 168 .setStandardOffset(-28378000) 169 .setFixedSavings("LMT", 0) 170 .addCutover(1883, 'w', 11, 18, 0, false, 43200000) 171 .setStandardOffset(-28800000) 172 .addRecurringSavings("PDT", 3600000, 1918, 1919, 'w', 3, -1, 7, false, 7200000) 173 .addRecurringSavings("PST", 0, 1918, 1919, 'w', 10, -1, 7, false, 7200000) 174 .addRecurringSavings("PWT", 3600000, 1942, 1942, 'w', 2, 9, 0, false, 7200000) 175 .addRecurringSavings("PPT", 3600000, 1945, 1945, 'u', 8, 14, 0, false, 82800000) 176 .addRecurringSavings("PST", 0, 1945, 1945, 'w', 9, 30, 0, false, 7200000) 177 .addRecurringSavings("PDT", 3600000, 1948, 1948, 'w', 3, 14, 0, false, 7200000) 178 .addRecurringSavings("PST", 0, 1949, 1949, 'w', 1, 1, 0, false, 7200000) 179 .addRecurringSavings("PDT", 3600000, 1950, 1966, 'w', 4, -1, 7, false, 7200000) 180 .addRecurringSavings("PST", 0, 1950, 1961, 'w', 9, -1, 7, false, 7200000) 181 .addRecurringSavings("PST", 0, 1962, 1966, 'w', 10, -1, 7, false, 7200000) 182 .addRecurringSavings("PST", 0, 1967, 2147483647, 'w', 10, -1, 7, false, 7200000) 183 .addRecurringSavings("PDT", 3600000, 1967, 1973, 'w', 4, -1, 7, false, 7200000) 184 .addRecurringSavings("PDT", 3600000, 1974, 1974, 'w', 1, 6, 0, false, 7200000) 185 .addRecurringSavings("PDT", 3600000, 1975, 1975, 'w', 2, 23, 0, false, 7200000) 186 .addRecurringSavings("PDT", 3600000, 1976, 1986, 'w', 4, -1, 7, false, 7200000) 187 .addRecurringSavings("PDT", 3600000, 1987, 2147483647, 'w', 4, 1, 7, true, 7200000); 188 } 189 190 static DateTimeZone buildAmericaLosAngeles() { 191 return buildAmericaLosAngelesBuilder().toDateTimeZone("America/Los_Angeles", true); 192 } 193 194 private DateTimeZone originalDateTimeZone = null; 195 196 public TestBuilder(String name) { 197 super(name); 198 } 199 200 protected void setUp() throws Exception { 201 originalDateTimeZone = DateTimeZone.getDefault(); 202 DateTimeZone.setDefault(DateTimeZone.UTC); 203 } 204 205 protected void tearDown() throws Exception { 206 DateTimeZone.setDefault(originalDateTimeZone); 207 } 208 209 public void testID() { 210 DateTimeZone tz = buildAmericaLosAngeles(); 211 assertEquals("America/Los_Angeles", tz.getID()); 212 assertEquals(false, tz.isFixed()); 213 } 214 215 public void testForwardTransitions() { 216 DateTimeZone tz = buildAmericaLosAngeles(); 217 testForwardTransitions(tz, AMERICA_LOS_ANGELES_DATA); 218 } 219 220 static void testForwardTransitions(DateTimeZone tz, String[][] data) { 221 long instant = Long.MIN_VALUE; 222 for (int i=0; i<data.length; i++) { 223 String[] row = data[i]; 224 long expectedInstant = instant; 225 if (row[0] != null) { 226 instant = tz.nextTransition(instant); 227 expectedInstant = new DateTime(row[0]).getMillis(); 228 } 229 230 String expectedKey = row[1]; 231 int expectedStandardOffset = -(int) OFFSET_FORMATTER.parseMillis(row[2]); 232 int expectedOffset = -(int) OFFSET_FORMATTER.parseMillis(row[3]); 233 234 assertEquals(expectedInstant, instant); 235 assertEquals(expectedKey, tz.getNameKey(instant)); 236 assertEquals(expectedStandardOffset, tz.getStandardOffset(instant)); 237 assertEquals(expectedOffset, tz.getOffset(instant)); 238 239 // Sample a few instants between transitions. 240 if (i < data.length - 1) { 241 long nextInstant = new DateTime(data[i + 1][0]).getMillis(); 242 long span = (nextInstant - instant) / 10; 243 for (int j=1; j<10; j++) { 244 long between = instant + j * span; 245 assertEquals(expectedKey, tz.getNameKey(between)); 246 assertEquals(expectedStandardOffset, tz.getStandardOffset(between)); 247 assertEquals(expectedOffset, tz.getOffset(between)); 248 } 249 } 250 } 251 } 252 253 public void testReverseTransitions() { 254 DateTimeZone tz = buildAmericaLosAngeles(); 255 testReverseTransitions(tz, AMERICA_LOS_ANGELES_DATA); 256 } 257 258 static void testReverseTransitions(DateTimeZone tz, String[][] data) { 259 long instant = new DateTime(data[data.length - 1][0]).getMillis(); 260 for (int i=data.length; --i>=1; ) { 261 String[] row = data[i]; 262 String[] prevRow = data[i - 1]; 263 instant = tz.previousTransition(instant); 264 265 long expectedInstant = new DateTime(row[0]).getMillis() - 1; 266 String expectedKey = prevRow[1]; 267 int expectedStandardOffset = -(int) OFFSET_FORMATTER.parseMillis(prevRow[2]); 268 int expectedOffset = -(int) OFFSET_FORMATTER.parseMillis(prevRow[3]); 269 270 assertEquals(expectedInstant, instant); 271 assertEquals(expectedKey, tz.getNameKey(instant)); 272 assertEquals(expectedStandardOffset, tz.getStandardOffset(instant)); 273 assertEquals(expectedOffset, tz.getOffset(instant)); 274 } 275 } 276 277 public void testSerialization() throws IOException { 278 DateTimeZone tz = testSerialization 279 (buildAmericaLosAngelesBuilder(), "America/Los_Angeles"); 280 281 assertEquals(false, tz.isFixed()); 282 testForwardTransitions(tz, AMERICA_LOS_ANGELES_DATA); 283 testReverseTransitions(tz, AMERICA_LOS_ANGELES_DATA); 284 } 285 286 static DateTimeZone testSerialization(DateTimeZoneBuilder builder, String id) 287 throws IOException 288 { 289 ByteArrayOutputStream out = new ByteArrayOutputStream(); 290 builder.writeTo("America/Los_Angeles", out); 291 ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); 292 DateTimeZone tz = DateTimeZoneBuilder.readFrom(in, id); 293 assertEquals(id, tz.getID()); 294 return tz; 295 } 296 297 public void testFixed() throws IOException { 298 DateTimeZoneBuilder builder = new DateTimeZoneBuilder() 299 .setStandardOffset(3600000) 300 .setFixedSavings("LMT", 0); 301 DateTimeZone tz = builder.toDateTimeZone("Test", true); 302 303 for (int i=0; i<2; i++) { 304 assertEquals("Test", tz.getID()); 305 assertEquals(true, tz.isFixed()); 306 assertEquals(3600000, tz.getOffset(0)); 307 assertEquals(3600000, tz.getStandardOffset(0)); 308 assertEquals(0, tz.nextTransition(0)); 309 assertEquals(0, tz.previousTransition(0)); 310 311 tz = testSerialization(builder, "Test"); 312 } 313 } 314 }