| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 org.apache.log4j.pattern; |
| |
| import junit.framework.Test; |
| import junit.framework.TestCase; |
| import junit.framework.TestSuite; |
| |
| import org.apache.log4j.pattern.CachedDateFormat; |
| |
| import java.text.DateFormat; |
| import java.util.TimeZone; |
| import java.util.Date; |
| import java.text.SimpleDateFormat; |
| import java.util.Locale; |
| import java.util.Calendar; |
| |
| /** |
| Unit test {@link AbsoluteTimeDateFormat}. |
| @author Curt Arnold |
| */ |
| public final class CachedDateFormatTest |
| extends TestCase { |
| |
| /** |
| * Test constructor |
| * @param name String test name |
| */ |
| public CachedDateFormatTest(String name) { |
| super(name); |
| } |
| |
| private static DateFormat createAbsoluteTimeDateFormat(TimeZone timeZone) { |
| DateFormat df = new SimpleDateFormat("HH:mm:ss,SSS"); |
| df.setTimeZone(timeZone); |
| return df; |
| } |
| |
| |
| /** |
| * Timezone representing GMT. |
| */ |
| private static final TimeZone GMT = TimeZone.getTimeZone("GMT"); |
| |
| /** |
| * Timezone for Chicago, Ill. USA. |
| */ |
| private static final TimeZone CHICAGO = TimeZone.getTimeZone( |
| "America/Chicago"); |
| |
| /** |
| * Test multiple calls in close intervals. |
| */ |
| public void test1() { |
| // subsequent calls within one minute |
| // are optimized to reuse previous formatted value |
| // make a couple of nearly spaced calls |
| DateFormat gmtFormat = new CachedDateFormat(createAbsoluteTimeDateFormat(GMT), 1000); |
| long ticks = 12601L * 86400000L; |
| Date jul1 = new Date(ticks); |
| assertEquals("00:00:00,000", gmtFormat.format(jul1)); |
| Date plus8ms = new Date(ticks + 8); |
| assertEquals("00:00:00,008", gmtFormat.format(plus8ms)); |
| Date plus17ms = new Date(ticks + 17); |
| assertEquals("00:00:00,017", gmtFormat.format(plus17ms)); |
| Date plus237ms = new Date(ticks + 237); |
| assertEquals("00:00:00,237", gmtFormat.format(plus237ms)); |
| Date plus1415ms = new Date(ticks + 1415); |
| assertEquals("00:00:01,415", gmtFormat.format(plus1415ms)); |
| } |
| |
| /** |
| * Check for interaction between caches. |
| */ |
| public void test2() { |
| Date jul2 = new Date(12602L * 86400000L); |
| DateFormat gmtFormat = new CachedDateFormat(createAbsoluteTimeDateFormat(GMT), 1000); |
| DateFormat chicagoFormat = new CachedDateFormat(createAbsoluteTimeDateFormat(CHICAGO), 1000); |
| assertEquals("00:00:00,000", gmtFormat.format(jul2)); |
| assertEquals("19:00:00,000", chicagoFormat.format(jul2)); |
| assertEquals("00:00:00,000", gmtFormat.format(jul2)); |
| } |
| |
| /** |
| * Test multiple calls in close intervals prior to 1 Jan 1970. |
| */ |
| public void test3() { |
| // subsequent calls within one minute |
| // are optimized to reuse previous formatted value |
| // make a couple of nearly spaced calls |
| DateFormat gmtFormat = new CachedDateFormat( |
| createAbsoluteTimeDateFormat(GMT), 1000); |
| // |
| // if the first call was exactly on an integral |
| // second, it would not test the round toward zero compensation |
| long ticks = -7L * 86400000L; |
| Date jul1 = new Date(ticks + 8); |
| assertEquals("00:00:00,008", gmtFormat.format(jul1)); |
| Date plus8ms = new Date(ticks + 16); |
| assertEquals("00:00:00,016", gmtFormat.format(plus8ms)); |
| Date plus17ms = new Date(ticks + 23); |
| assertEquals("00:00:00,023", gmtFormat.format(plus17ms)); |
| Date plus237ms = new Date(ticks + 245); |
| assertEquals("00:00:00,245", gmtFormat.format(plus237ms)); |
| Date plus1415ms = new Date(ticks + 1423); |
| assertEquals("00:00:01,423", gmtFormat.format(plus1415ms)); |
| } |
| |
| public void test4() { |
| // subsequent calls within one minute are optimized to reuse previous |
| // formatted value. make a couple of nearly spaced calls |
| // (Note: 'Z' is JDK 1.4, using 'z' instead.) |
| SimpleDateFormat baseFormat = |
| new SimpleDateFormat("EEE, MMM dd, HH:mm:ss.SSS z", Locale.ENGLISH); |
| DateFormat cachedFormat = new CachedDateFormat(baseFormat, 1000); |
| // |
| // use a date in 2000 to attempt to confuse the millisecond locator |
| long ticks = 11141L * 86400000L; |
| Date jul1 = new Date(ticks); |
| assertEquals(baseFormat.format(jul1), cachedFormat.format(jul1)); |
| Date plus8ms = new Date(ticks + 8); |
| baseFormat.format(plus8ms); |
| cachedFormat.format(plus8ms); |
| assertEquals(baseFormat.format(plus8ms), cachedFormat.format(plus8ms)); |
| Date plus17ms = new Date(ticks + 17); |
| assertEquals(baseFormat.format(plus17ms), cachedFormat.format(plus17ms)); |
| Date plus237ms = new Date(ticks + 237); |
| assertEquals(baseFormat.format(plus237ms), cachedFormat.format(plus237ms)); |
| Date plus1415ms = new Date(ticks + 1415); |
| assertEquals(baseFormat.format(plus1415ms), cachedFormat.format(plus1415ms)); |
| } |
| |
| public void test5() { |
| // subsequent calls within one minute |
| // are optimized to reuse previous formatted value |
| // make a couple of nearly spaced calls |
| // (Note: 'Z' is JDK 1.4, using 'z' instead.) |
| Locale thai = new Locale("th", "TH"); |
| SimpleDateFormat baseFormat = |
| new SimpleDateFormat("EEE, MMM dd, HH:mm:ss.SSS z", thai); |
| DateFormat cachedFormat = new CachedDateFormat(baseFormat, 1000); |
| // |
| // use a date in the year 2000 CE to attempt to confuse the millisecond locator |
| long ticks = 11141L * 86400000L; |
| |
| String sx; |
| Date jul1 = new Date(ticks); |
| sx = cachedFormat.format(jul1); |
| |
| assertEquals(baseFormat.format(jul1), sx); |
| |
| sx = cachedFormat.format(jul1); |
| |
| assertEquals(baseFormat.format(jul1), sx); |
| |
| |
| Date plus8ms = new Date(ticks + 8); |
| sx = cachedFormat.format(plus8ms); |
| |
| assertEquals(baseFormat.format(plus8ms), sx); |
| |
| Date plus17ms = new Date(ticks + 17); |
| assertEquals(baseFormat.format(plus17ms), cachedFormat.format(plus17ms)); |
| |
| Date plus237ms = new Date(ticks + 237); |
| assertEquals(baseFormat.format(plus237ms), cachedFormat.format(plus237ms)); |
| |
| Date plus1415ms = new Date(ticks + 1415); |
| assertEquals(baseFormat.format(plus1415ms), cachedFormat.format(plus1415ms)); |
| } |
| |
| /** |
| * Checks that getNumberFormat does not return null. |
| */ |
| public void test6() { |
| assertNotNull(new CachedDateFormat(new SimpleDateFormat(), 1000).getNumberFormat()); |
| } |
| |
| /** |
| * Set time zone on cached and check that it is effective. |
| */ |
| public void test8() { |
| DateFormat baseFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS"); |
| baseFormat.setTimeZone(GMT); |
| DateFormat cachedFormat = new CachedDateFormat(baseFormat, 1000); |
| Date jul4 = new Date(12603L * 86400000L); |
| assertEquals("2004-07-04 00:00:00,000", cachedFormat.format(jul4)); |
| cachedFormat.setTimeZone(TimeZone.getTimeZone("GMT-6")); |
| assertEquals("2004-07-03 18:00:00,000", cachedFormat.format(jul4)); |
| } |
| |
| |
| /** |
| * Test of caching when less than three millisecond digits are specified. |
| */ |
| public void test9() { |
| // (Note: 'Z' is JDK 1.4, using 'z' instead.) |
| DateFormat baseFormat = new SimpleDateFormat("yyyy-MMMM-dd HH:mm:ss,SS z", Locale.US); |
| DateFormat cachedFormat = new CachedDateFormat(baseFormat, 1000); |
| TimeZone cet = TimeZone.getTimeZone("GMT+1"); |
| cachedFormat.setTimeZone(cet); |
| |
| Calendar c = Calendar.getInstance(); |
| c.set(2004, Calendar.DECEMBER, 12, 20, 0); |
| c.set(Calendar.SECOND, 37); |
| c.set(Calendar.MILLISECOND, 23); |
| c.setTimeZone(cet); |
| |
| String expected = baseFormat.format(c.getTime()); |
| String s = cachedFormat.format(c.getTime()); |
| assertEquals(expected, s); |
| |
| c.set(2005, Calendar.JANUARY, 1, 0, 0); |
| c.set(Calendar.SECOND, 13); |
| c.set(Calendar.MILLISECOND, 905); |
| |
| expected = baseFormat.format(c.getTime()); |
| s = cachedFormat.format(c.getTime()); |
| assertEquals(expected, s); |
| } |
| |
| |
| /** |
| * Test when millisecond position moves but length remains constant. |
| */ |
| public void test10() { |
| DateFormat baseFormat = new SimpleDateFormat("MMMM SSS EEEEEE", Locale.US); |
| DateFormat cachedFormat = new CachedDateFormat(baseFormat, 1000); |
| TimeZone cet = TimeZone.getTimeZone("GMT+1"); |
| cachedFormat.setTimeZone(cet); |
| |
| Calendar c = Calendar.getInstance(); |
| c.set(2004, Calendar.OCTOBER, 5, 20, 0); |
| c.set(Calendar.SECOND, 37); |
| c.set(Calendar.MILLISECOND, 23); |
| c.setTimeZone(cet); |
| |
| String expected = baseFormat.format(c.getTime()); |
| String s = cachedFormat.format(c.getTime()); |
| assertEquals(expected, s); |
| |
| c.set(2004, Calendar.NOVEMBER, 1, 0, 0); |
| c.set(Calendar.MILLISECOND, 23); |
| expected = baseFormat.format(c.getTime()); |
| s = cachedFormat.format(c.getTime()); |
| assertEquals(expected, s); |
| |
| |
| c.set(Calendar.MILLISECOND, 984); |
| expected = baseFormat.format(c.getTime()); |
| s = cachedFormat.format(c.getTime()); |
| assertEquals(expected, s); |
| } |
| |
| /** |
| * Test that tests if caching is skipped if only "SS" |
| * is specified. |
| */ |
| public void test11() { |
| // |
| // Earlier versions could be tricked by "SS0" patterns. |
| // |
| String badPattern = "ss,SS0"; |
| SimpleDateFormat simpleFormat = new SimpleDateFormat(badPattern); |
| SimpleDateFormat baseFormat = new SimpleDateFormat(badPattern); |
| DateFormat gmtFormat = new CachedDateFormat(simpleFormat, 1000); |
| gmtFormat.setTimeZone(GMT); |
| baseFormat.setTimeZone(GMT); |
| |
| // |
| // The first request has to 100 ms after an ordinal second |
| // to push the literal zero out of the pattern check |
| long ticks = 11142L * 86400000L; |
| Date jul2 = new Date(ticks + 120); |
| String expected = baseFormat.format(jul2); |
| assertEquals(expected, gmtFormat.format(jul2)); |
| jul2.setTime(ticks + 87); |
| |
| |
| // |
| // Cache gives 00,087 |
| expected = baseFormat.format(jul2); |
| assertEquals(expected, gmtFormat.format(jul2)); |
| |
| } |
| |
| /** |
| * Check pattern location for ISO8601 |
| */ |
| public void test12() { |
| SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS"); |
| long ticks = 11142L * 86400000L; |
| String formatted = df.format(new Date(ticks)); |
| int millisecondStart = CachedDateFormat.findMillisecondStart(ticks, formatted, df); |
| assertEquals(20, millisecondStart); |
| } |
| |
| /** |
| * Check pattern location for DATE |
| */ |
| public void test13() { |
| SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); |
| long ticks = 11142L * 86400000L; |
| String formatted = df.format(new Date(ticks)); |
| int millisecondStart = CachedDateFormat.findMillisecondStart(ticks, formatted, df); |
| assertEquals(CachedDateFormat.NO_MILLISECONDS, millisecondStart); |
| } |
| |
| /** |
| * Check pattern location for ABSOLUTE |
| */ |
| public void test14() { |
| SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss,SSS"); |
| long ticks = 11142L * 86400000L; |
| String formatted = df.format(new Date(ticks)); |
| int millisecondStart = CachedDateFormat.findMillisecondStart(ticks, formatted, df); |
| assertEquals(9, millisecondStart); |
| } |
| |
| /** |
| * Check pattern location for single S |
| */ |
| public void test15() { |
| SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss,S"); |
| long ticks = 11142L * 86400000L; |
| String formatted = df.format(new Date(ticks)); |
| int millisecondStart = CachedDateFormat.findMillisecondStart(ticks, formatted, df); |
| assertEquals(CachedDateFormat.UNRECOGNIZED_MILLISECONDS, millisecondStart); |
| } |
| |
| /** |
| * Check pattern location for single SS |
| */ |
| public void test16() { |
| SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss,SS"); |
| long ticks = 11142L * 86400000L; |
| String formatted = df.format(new Date(ticks)); |
| int millisecondStart = CachedDateFormat.findMillisecondStart(ticks, formatted, df); |
| assertEquals(CachedDateFormat.UNRECOGNIZED_MILLISECONDS, millisecondStart); |
| } |
| |
| |
| /** |
| * Check caching when multiple SSS appear in pattern |
| */ |
| public void test17() { |
| Date jul2 = new Date(12602L * 86400000L); |
| String badPattern = "HH:mm:ss,SSS HH:mm:ss,SSS"; |
| SimpleDateFormat simpleFormat = new SimpleDateFormat(badPattern); |
| simpleFormat.setTimeZone(GMT); |
| DateFormat cachedFormat = new CachedDateFormat(simpleFormat, 1000); |
| String s = cachedFormat.format(jul2); |
| assertEquals("00:00:00,000 00:00:00,000", s); |
| jul2.setTime(jul2.getTime() + 120); |
| assertEquals("00:00:00,120 00:00:00,120", simpleFormat.format(jul2)); |
| s = cachedFormat.format(jul2); |
| // |
| // TODO: why is this returning ,120 ... , 120 |
| // |
| //assertEquals("00:00:00,120 00:00:00,000", s) ; |
| |
| int maxValid = CachedDateFormat.getMaximumCacheValidity(badPattern); |
| assertEquals(1, maxValid); |
| } |
| |
| |
| public static Test xsuite() { |
| TestSuite suite = new TestSuite(); |
| suite.addTest(new CachedDateFormatTest("test5")); |
| //suite.addTest(new CachedDateFormatTest("testS2")); |
| return suite; |
| } |
| |
| } |