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.File;
020    import java.io.FileOutputStream;
021    import java.io.IOException;
022    import java.io.InputStream;
023    import java.util.StringTokenizer;
024    
025    import junit.framework.TestCase;
026    import junit.framework.TestSuite;
027    
028    import org.joda.time.DateTime;
029    import org.joda.time.DateTimeZone;
030    import org.joda.time.tz.ZoneInfoCompiler.DateTimeOfYear;
031    
032    /**
033     * Test cases for ZoneInfoCompiler.
034     *
035     * @author Brian S O'Neill
036     */
037    public class TestCompiler extends TestCase {
038        public static void main(String[] args) {
039            junit.textui.TestRunner.run(suite());
040        }
041    
042        public static TestSuite suite() {
043            return new TestSuite(TestCompiler.class);
044        }
045    
046        static final String AMERICA_LOS_ANGELES_FILE =
047            "# Rules for building just America/Los_Angeles time zone.\n" + 
048            "\n" + 
049            "Rule    US  1918    1919    -   Mar lastSun 2:00    1:00    D\n" + 
050            "Rule    US  1918    1919    -   Oct lastSun 2:00    0   S\n" + 
051            "Rule    US  1942    only    -   Feb 9   2:00    1:00    W # War\n" + 
052            "Rule    US  1945    only    -   Aug 14  23:00u  1:00    P # Peace\n" + 
053            "Rule    US  1945    only    -   Sep 30  2:00    0   S\n" + 
054            "Rule    US  1967    max -   Oct lastSun 2:00    0   S\n" + 
055            "Rule    US  1967    1973    -   Apr lastSun 2:00    1:00    D\n" + 
056            "Rule    US  1974    only    -   Jan 6   2:00    1:00    D\n" + 
057            "Rule    US  1975    only    -   Feb 23  2:00    1:00    D\n" + 
058            "Rule    US  1976    1986    -   Apr lastSun 2:00    1:00    D\n" + 
059            "Rule    US  1987    max -   Apr Sun>=1  2:00    1:00    D\n" + 
060            "\n" + 
061            "Rule    CA  1948    only    -   Mar 14  2:00    1:00    D\n" + 
062            "Rule    CA  1949    only    -   Jan  1  2:00    0   S\n" + 
063            "Rule    CA  1950    1966    -   Apr lastSun 2:00    1:00    D\n" + 
064            "Rule    CA  1950    1961    -   Sep lastSun 2:00    0   S\n" + 
065            "Rule    CA  1962    1966    -   Oct lastSun 2:00    0   S\n" + 
066            "\n" + 
067            "Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 12:00\n" + 
068            "            -8:00   US  P%sT    1946\n" + 
069            "            -8:00   CA  P%sT    1967\n" + 
070            "            -8:00   US  P%sT";
071    
072        private DateTimeZone originalDateTimeZone = null;
073    
074        public TestCompiler(String name) {
075            super(name);
076        }
077    
078        protected void setUp() throws Exception {
079            originalDateTimeZone = DateTimeZone.getDefault();
080            DateTimeZone.setDefault(DateTimeZone.UTC);
081        }
082    
083        protected void tearDown() throws Exception {
084            DateTimeZone.setDefault(originalDateTimeZone);
085        }
086    
087        public void testCompile() throws Exception {
088            Provider provider = compileAndLoad(AMERICA_LOS_ANGELES_FILE);
089            DateTimeZone tz = provider.getZone("America/Los_Angeles");
090    
091            assertEquals("America/Los_Angeles", tz.getID());
092            assertEquals(false, tz.isFixed());
093            TestBuilder.testForwardTransitions(tz, TestBuilder.AMERICA_LOS_ANGELES_DATA);
094            TestBuilder.testReverseTransitions(tz, TestBuilder.AMERICA_LOS_ANGELES_DATA);
095        }
096    
097        private Provider compileAndLoad(String data) throws Exception {
098            File tempDir = createDataFile(data);
099            File destDir = makeTempDir();
100    
101            ZoneInfoCompiler.main(new String[] {
102                "-src", tempDir.getAbsolutePath(),
103                "-dst", destDir.getAbsolutePath(),
104                "tzdata"
105            });
106    
107            // Mark all files to be deleted on exit.
108            deleteOnExit(destDir);
109    
110            return new ZoneInfoProvider(destDir);
111        }
112    
113        private File createDataFile(String data) throws IOException {
114            File tempDir = makeTempDir();
115    
116            File tempFile = new File(tempDir, "tzdata");
117            tempFile.deleteOnExit();
118    
119            InputStream in = new ByteArrayInputStream(data.getBytes("UTF-8"));
120    
121            FileOutputStream out = new FileOutputStream(tempFile);
122            byte[] buf = new byte[1000];
123            int amt;
124            while ((amt = in.read(buf)) > 0) {
125                out.write(buf, 0, amt);
126            }
127            out.close();
128            in.close();
129    
130            return tempDir;
131        }
132    
133        private File makeTempDir() {
134            File tempDir = new File(System.getProperty("java.io.tmpdir"));
135            tempDir = new File(tempDir, "joda-test-" + (new java.util.Random().nextInt() & 0xffffff));
136            tempDir.mkdirs();
137            tempDir.deleteOnExit();
138            return tempDir;
139        }
140    
141        private void deleteOnExit(File tempFile) {
142            tempFile.deleteOnExit();
143            if (tempFile.isDirectory()) {
144                File[] files = tempFile.listFiles();
145                for (int i=0; i<files.length; i++) {
146                    deleteOnExit(files[i]);
147                }
148            }
149        }
150    
151        //-----------------------------------------------------------------------
152        public void test_2400_fromDay() {
153            StringTokenizer st = new StringTokenizer("Apr Sun>=1  24:00");
154            DateTimeOfYear test = new DateTimeOfYear(st);
155            assertEquals(4, test.iMonthOfYear);  // Apr
156            assertEquals(2, test.iDayOfMonth);   // 2nd
157            assertEquals(1, test.iDayOfWeek);    // Mon
158            assertEquals(0, test.iMillisOfDay);  // 00:00
159            assertEquals(true, test.iAdvanceDayOfWeek);
160        }
161    
162        public void test_2400_last() {
163            StringTokenizer st = new StringTokenizer("Mar lastSun 24:00");
164            DateTimeOfYear test = new DateTimeOfYear(st);
165            assertEquals(4, test.iMonthOfYear);  // Apr
166            assertEquals(1, test.iDayOfMonth);   // 1st
167            assertEquals(1, test.iDayOfWeek);    // Mon
168            assertEquals(0, test.iMillisOfDay);  // 00:00
169            assertEquals(false, test.iAdvanceDayOfWeek);
170        }
171    
172        public void test_Amman_2003() {
173            DateTimeZone zone = DateTimeZone.forID("Asia/Amman");
174            DateTime dt = new DateTime(2003, 3, 1, 0, 0, zone);
175            long next = zone.nextTransition(dt.getMillis());
176            assertEquals(next, new DateTime(2003, 3, 28, 0, 0, DateTimeZone.forOffsetHours(2)).getMillis());
177        }
178    
179        public void test_Amman_2004() {
180            DateTimeZone zone = DateTimeZone.forID("Asia/Amman");
181            DateTime dt = new DateTime(2004, 3, 1, 0, 0, zone);
182            long next = zone.nextTransition(dt.getMillis());
183            assertEquals(next, new DateTime(2004, 3, 26, 0, 0, DateTimeZone.forOffsetHours(2)).getMillis());
184        }
185    
186        public void test_Amman_2005() {
187            DateTimeZone zone = DateTimeZone.forID("Asia/Amman");
188            DateTime dt = new DateTime(2005, 3, 1, 0, 0, zone);
189            long next = zone.nextTransition(dt.getMillis());
190            assertEquals(next, new DateTime(2005, 4, 1, 0, 0, DateTimeZone.forOffsetHours(2)).getMillis());
191        }
192    
193        public void test_Amman_2006() {
194            DateTimeZone zone = DateTimeZone.forID("Asia/Amman");
195            DateTime dt = new DateTime(2006, 3, 1, 0, 0, zone);
196            long next = zone.nextTransition(dt.getMillis());
197            assertEquals(next, new DateTime(2006, 3, 31, 0, 0, DateTimeZone.forOffsetHours(2)).getMillis());
198        }
199    
200    }