/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2014 by Pentaho : http://www.pentaho.com * ******************************************************************************* * * 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 org.pentaho.di.core.row.value.timestamp; import static org.junit.Assert.assertEquals; import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.HashSet; import java.util.Locale; import java.util.ResourceBundle; import java.util.Set; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * User: Dzmitry Stsiapanau Date: 3/17/14 Time: 4:46 PM */ public class SimpleTimestampFormatTest { private static Locale formatLocale; private Set<Locale> locales = new HashSet<Locale>( Arrays.asList( Locale.US, Locale.GERMANY, Locale.JAPANESE, Locale.CHINESE ) ); private ResourceBundle tdb; private static String stringNinePrecision = "2014-03-15 15:30:45.123456789"; private static String stringFourPrecision = "2014-03-15 15:30:45.1234"; private static String stringThreePrecision = "2014-03-15 15:30:45.123"; private static String stringWithoutPrecision = "2014-03-15 15:30:45"; private static String stringWithoutPrecisionWithDot = "2014-11-15 15:30:45.000"; private static Timestamp timestampNinePrecision = Timestamp.valueOf( stringNinePrecision ); private static Timestamp timestampFourPrecision = Timestamp.valueOf( stringFourPrecision ); private static Timestamp timestampThreePrecision = Timestamp.valueOf( stringThreePrecision ); private static Timestamp timestampWithoutPrecision = Timestamp.valueOf( stringWithoutPrecision ); private static Timestamp timestampWithoutPrecisionWithDot = Timestamp.valueOf( stringWithoutPrecisionWithDot ); private static Date dateThreePrecision = new Date( timestampThreePrecision.getTime() ); private static Date dateWithoutPrecision = new Date( timestampWithoutPrecision.getTime() ); @Before public void setUp() throws Exception { formatLocale = Locale.getDefault( Locale.Category.FORMAT ); } @After public void tearDown() throws Exception { Locale.setDefault( Locale.Category.FORMAT, formatLocale ); } @Test public void testFormat() throws Exception { for ( Locale locale : locales ) { Locale.setDefault( Locale.Category.FORMAT, locale ); tdb = ResourceBundle.getBundle( "org/pentaho/di/core/row/value/timestamp/messages/testdates", locale ); checkFormat( "KETTLE.LONG" ); checkFormat( "LOCALE.DATE", new SimpleTimestampFormat( new SimpleDateFormat().toPattern() ) ); //checkFormat( "LOCALE.TIMESTAMP", new SimpleTimestampFormat( new SimpleDateFormat().toPattern() ) ); checkFormat( "KETTLE" ); checkFormat( "DB.DEFAULT" ); checkFormat( "LOCALE.DEFAULT" ); } } private void checkFormat( String patternName ) { SimpleTimestampFormat stf = new SimpleTimestampFormat( tdb.getString( "PATTERN." + patternName ) ); checkFormat( patternName, stf ); } private void checkFormat( String patternName, SimpleTimestampFormat stf ) { String localeForErrorMSG = Locale.getDefault( Locale.Category.FORMAT ).toLanguageTag(); assertEquals( localeForErrorMSG + "=locale localized pattern= " + stf.toLocalizedPattern(), tdb.getString( "TIMESTAMP.NINE." + patternName ), ( stf.format( timestampNinePrecision ) ) ); assertEquals( localeForErrorMSG + "=locale localized pattern= " + stf.toLocalizedPattern(), tdb.getString( "TIMESTAMP.THREE." + patternName ), ( stf.format( timestampThreePrecision ) ) ); assertEquals( localeForErrorMSG + "=locale localized pattern= " + stf.toLocalizedPattern(), tdb.getString( "TIMESTAMP.ZERO." + patternName ), ( stf.format( timestampWithoutPrecision ) ) ); assertEquals( localeForErrorMSG + "=locale localized pattern= " + stf.toLocalizedPattern(), tdb.getString( "TIMESTAMP.DOT." + patternName ), ( stf.format( timestampWithoutPrecisionWithDot ) ) ); assertEquals( localeForErrorMSG + "=locale localized pattern= " + stf.toLocalizedPattern(), tdb.getString( "DATE.THREE." + patternName ), ( stf.format( dateThreePrecision ) ) ); assertEquals( localeForErrorMSG + "=locale localized pattern= " + stf.toLocalizedPattern(), tdb.getString( "DATE.ZERO." + patternName ), ( stf.format( dateWithoutPrecision ) ) ); } @Test public void testParse() throws Exception { for ( Locale locale : locales ) { Locale.setDefault( Locale.Category.FORMAT, locale ); tdb = ResourceBundle.getBundle( "org/pentaho/di/core/row/value/timestamp/messages/testdates", locale ); checkParseKettle(); checkParseKettleLong(); checkParseDbDefault(); checkParseLocaleDefault(); // Uncomment in case of locale timestamp format is defined for the most locales as in SimpleDateFormat() //checkParseLocalTimestamp(); } } private void checkParseKettle() throws ParseException { String patternName = "KETTLE"; SimpleTimestampFormat stf = new SimpleTimestampFormat( tdb.getString( "PATTERN." + patternName ) ); String localeForErrorMSG = Locale.getDefault( Locale.Category.FORMAT ).toLanguageTag(); parseUnit( "TIMESTAMP.NINE." + patternName, stf, localeForErrorMSG, timestampThreePrecision ); //ThreePrecision only for Kettle parseUnit( "TIMESTAMP.THREE." + patternName, stf, localeForErrorMSG, timestampThreePrecision ); parseUnit( "TIMESTAMP.ZERO." + patternName, stf, localeForErrorMSG, timestampWithoutPrecision ); parseUnit( "TIMESTAMP.DOT." + patternName, stf, localeForErrorMSG, timestampWithoutPrecisionWithDot ); parseUnit( "DATE.THREE." + patternName, stf, localeForErrorMSG, dateThreePrecision ); parseUnit( "DATE.ZERO." + patternName, stf, localeForErrorMSG, dateWithoutPrecision ); } private void checkParseKettleLong() throws ParseException { String patternName = "KETTLE.LONG"; SimpleTimestampFormat stf = new SimpleTimestampFormat( tdb.getString( "PATTERN." + patternName ) ); String localeForErrorMSG = Locale.getDefault( Locale.Category.FORMAT ).toLanguageTag(); parseUnit( "TIMESTAMP.NINE." + patternName, stf, localeForErrorMSG, timestampFourPrecision ); //FourPrecision only for Kettle long parseUnit( "TIMESTAMP.THREE." + patternName, stf, localeForErrorMSG, timestampThreePrecision ); parseUnit( "TIMESTAMP.ZERO." + patternName, stf, localeForErrorMSG, timestampWithoutPrecision ); parseUnit( "TIMESTAMP.DOT." + patternName, stf, localeForErrorMSG, timestampWithoutPrecisionWithDot ); parseUnit( "DATE.THREE." + patternName, stf, localeForErrorMSG, dateThreePrecision ); parseUnit( "DATE.ZERO." + patternName, stf, localeForErrorMSG, dateWithoutPrecision ); } private void checkParseDbDefault() throws ParseException { String patternName = "DB.DEFAULT"; SimpleTimestampFormat stf = new SimpleTimestampFormat( tdb.getString( "PATTERN." + patternName ) ); String localeForErrorMSG = Locale.getDefault( Locale.Category.FORMAT ).toLanguageTag(); parseUnit( "TIMESTAMP.NINE." + patternName, stf, localeForErrorMSG, timestampNinePrecision ); parseUnit( "TIMESTAMP.THREE." + patternName, stf, localeForErrorMSG, timestampThreePrecision ); parseUnit( "TIMESTAMP.ZERO." + patternName, stf, localeForErrorMSG, timestampWithoutPrecision ); parseUnit( "TIMESTAMP.DOT." + patternName, stf, localeForErrorMSG, timestampWithoutPrecisionWithDot ); parseUnit( "DATE.THREE." + patternName, stf, localeForErrorMSG, dateThreePrecision ); parseUnit( "DATE.ZERO." + patternName, stf, localeForErrorMSG, dateWithoutPrecision ); } private void checkParseLocaleDefault() throws ParseException { String patternName = "LOCALE.DEFAULT"; SimpleTimestampFormat stf = new SimpleTimestampFormat( tdb.getString( "PATTERN." + patternName ) ); String localeForErrorMSG = Locale.getDefault( Locale.Category.FORMAT ).toLanguageTag(); parseUnit( "TIMESTAMP.NINE." + patternName, stf, localeForErrorMSG, timestampNinePrecision ); parseUnit( "TIMESTAMP.THREE." + patternName, stf, localeForErrorMSG, timestampThreePrecision ); parseUnit( "TIMESTAMP.ZERO." + patternName, stf, localeForErrorMSG, timestampWithoutPrecision ); parseUnit( "TIMESTAMP.DOT." + patternName, stf, localeForErrorMSG, timestampWithoutPrecisionWithDot ); parseUnit( "DATE.THREE." + patternName, stf, localeForErrorMSG, dateThreePrecision ); parseUnit( "DATE.ZERO." + patternName, stf, localeForErrorMSG, dateWithoutPrecision ); } protected void checkParseLocalTimestamp() throws ParseException { String patternName = "LOCALE.TIMESTAMP"; SimpleTimestampFormat stf = new SimpleTimestampFormat( tdb.getString( "PATTERN." + patternName ) ); String localeForErrorMSG = Locale.getDefault( Locale.Category.FORMAT ).toLanguageTag(); parseUnit( "TIMESTAMP.NINE." + patternName, stf, localeForErrorMSG, timestampThreePrecision ); parseUnit( "TIMESTAMP.THREE." + patternName, stf, localeForErrorMSG, timestampThreePrecision ); parseUnit( "TIMESTAMP.ZERO." + patternName, stf, localeForErrorMSG, timestampWithoutPrecision ); parseUnit( "TIMESTAMP.DOT." + patternName, stf, localeForErrorMSG, timestampWithoutPrecisionWithDot ); parseUnit( "DATE.THREE." + patternName, stf, localeForErrorMSG, dateThreePrecision ); parseUnit( "DATE.ZERO." + patternName, stf, localeForErrorMSG, dateWithoutPrecision ); } private void parseUnit( String patternName, SimpleTimestampFormat stf, String localeForErrorMSG, Date date ) throws ParseException { if ( date instanceof Timestamp ) { assertEquals( localeForErrorMSG + "=locale localized pattern= " + stf.toLocalizedPattern(), date, ( stf.parse( tdb.getString( patternName ) ) ) ); } else { assertEquals( localeForErrorMSG + "=locale localized pattern= " + stf.toLocalizedPattern(), date, ( stf.parse( tdb.getString( patternName ) ) ) ); } } @Test public void testToPattern() throws Exception { for ( Locale locale : locales ) { Locale.setDefault( Locale.Category.FORMAT, locale ); tdb = ResourceBundle.getBundle( "org/pentaho/di/core/row/value/timestamp/messages/testdates", locale ); String patternExample = tdb.getString( "PATTERN.KETTLE" ); SimpleTimestampFormat stf = new SimpleTimestampFormat( new SimpleDateFormat().toPattern() ); assertEquals( locale.toLanguageTag(), tdb.getString( "PATTERN.LOCALE.DATE" ), stf.toPattern() ); stf = new SimpleTimestampFormat( patternExample, Locale.GERMANY ); assertEquals( locale.toLanguageTag(), patternExample, stf.toPattern() ); stf = new SimpleTimestampFormat( patternExample, Locale.US ); assertEquals( locale.toLanguageTag(), patternExample, stf.toPattern() ); } } @Test public void testToLocalizedPattern() throws Exception { for ( Locale locale : locales ) { Locale.setDefault( Locale.Category.FORMAT, locale ); tdb = ResourceBundle.getBundle( "org/pentaho/di/core/row/value/timestamp/messages/testdates", locale ); SimpleTimestampFormat stf = new SimpleTimestampFormat( new SimpleDateFormat().toPattern() ); assertEquals( locale.toLanguageTag(), tdb.getString( "PATTERN.LOCALE.COMPILED" ), stf.toLocalizedPattern() ); String patternExample = tdb.getString( "PATTERN.KETTLE" ); stf = new SimpleTimestampFormat( patternExample ); assertEquals( locale.toLanguageTag(), tdb.getString( "PATTERN.LOCALE.COMPILED_DATE" ), stf.toLocalizedPattern() ); } } @Test public void testApplyPattern() throws Exception { for ( Locale locale : locales ) { Locale.setDefault( Locale.Category.FORMAT, locale ); tdb = ResourceBundle.getBundle( "org/pentaho/di/core/row/value/timestamp/messages/testdates", locale ); String patternExample = tdb.getString( "PATTERN.KETTLE" ); SimpleTimestampFormat stf = new SimpleTimestampFormat( new SimpleDateFormat().toPattern() ); assertEquals( locale.toLanguageTag(), tdb.getString( "PATTERN.LOCALE.DATE" ), stf.toPattern() ); stf.applyPattern( patternExample ); checkFormat( "KETTLE", stf ); } } @Test public void testApplyLocalizedPattern() throws Exception { Locale.setDefault( Locale.Category.FORMAT, Locale.US ); SimpleTimestampFormat stf = new SimpleTimestampFormat( new SimpleDateFormat().toPattern() ); for ( Locale locale : locales ) { Locale.setDefault( Locale.Category.FORMAT, locale ); tdb = ResourceBundle.getBundle( "org/pentaho/di/core/row/value/timestamp/messages/testdates", locale ); stf.applyLocalizedPattern( tdb.getString( "PATTERN.LOCALE.DEFAULT" ) ); assertEquals( locale.toLanguageTag(), tdb.getString( "PATTERN.LOCALE.DEFAULT" ), stf.toLocalizedPattern() ); checkFormat( "LOCALE.DEFAULT", stf ); } } }