/**
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 2015, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
package ch.qos.logback.classic.pattern;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import ch.qos.logback.core.CoreConstants;
import org.junit.BeforeClass;
import org.junit.Test;
import ch.qos.logback.core.pattern.FormattingConverter;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.LoggingEvent;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
/**
* Tests the {@link DateConverter} class
*/
public class DateConverterTest {
private static final String DATETIME_PATTERN = "MMM-dd HH:mm:ss.SSS";
private static final String ENGLISH_TIME_UTC = "Sep-03 17:20:55.123";
private static final String FRENCH_TIME_UTC = "sept.-03 17:20:55.123";
private static final String CHINESE_TIME_UTC = "九月-03 17:20:55.123";
private static LoggerContext _context;
private static Logger _logger;
private static Date _date;
private static long _timestamp;
private static String _isoDateString;
@BeforeClass
public static void beforeClass() throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(DATETIME_PATTERN, Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
_date = sdf.parse(ENGLISH_TIME_UTC);
_context = new LoggerContext();
_logger = _context.getLogger(DateConverterTest.class);
_timestamp = _date.getTime();
_isoDateString = formatDateWithPattern(_date, CoreConstants.ISO8601_PATTERN, TimeZone.getDefault().getID());
}
@Test
public void convertsDateAsIso8601WhenNull() {
assertEquals(_isoDateString, convert(_timestamp, new String[]{null}));
}
@Test
public void convertsDateAsIso8601WhenSpecifiedByIsoName() {
assertEquals(_isoDateString, convert(_timestamp, CoreConstants.ISO8601_STR));
}
@Test
public void convertsDateAsIso8601WhenInvalidPatternSpecified() {
assertEquals(_isoDateString, convert(_timestamp, "foo"));
}
@Test
public void convertsDateWithEnglishLocaleByDefault() {
Locale origLocale = Locale.getDefault();
Locale.setDefault(Locale.FRANCE);
assertEquals(ENGLISH_TIME_UTC, convert(_timestamp, DATETIME_PATTERN, "UTC"));
Locale.setDefault(origLocale);
}
@Test
public void convertsDateWithSpecifiedLocaleLang() {
assertEquals(FRENCH_TIME_UTC, convert(_timestamp, DATETIME_PATTERN, "UTC", "fr"));
}
@Test
public void convertsDateWithSpecifiedLocaleLangAndCountry() {
assertEquals(CHINESE_TIME_UTC, convert(_timestamp, DATETIME_PATTERN, "UTC", "zh,CN"));
}
@Test
public void convertsDateWithCurrentTimeZoneByDefault() {
assertEquals(formatDate(TimeZone.getDefault().getID()), convert(_timestamp, DATETIME_PATTERN));
}
@Test
public void convertsDateWithUtcWhenTimeZoneBlank() {
assertEquals(formatDate("UTC"), convert(_timestamp, DATETIME_PATTERN, ""));
}
@Test
public void convertsDateWithUtcWhenTimeZoneUnknown() {
assertEquals(formatDate("UTC"), convert(_timestamp, DATETIME_PATTERN, "FakeTimeZone"));
}
@Test
public void convertsDateInSpecifiedTimeZoneAsGmtOffset() {
assertEquals(formatDate("GMT-8"), convert(_timestamp, DATETIME_PATTERN, "GMT-8"));
}
@Test
public void convertsDateInSpecifiedTimeZoneAsRawOffset() {
assertEquals(formatDate("-0800"), convert(_timestamp, DATETIME_PATTERN, "-0800"));
}
@Test
public void convertsDateInSpecifiedTimeZoneAsTzid() {
assertEquals(formatDate("CST"), convert(_timestamp, DATETIME_PATTERN, "CST"));
}
/**
* Gets a string representation of the test date formatted with the prespecified test pattern
* @param timeZone timezone ID
* @return the formatted date/time string
*/
private static String formatDate(String timeZone) {
return formatDateWithPattern(_date, DATETIME_PATTERN, timeZone);
}
/**
* Gets a string representaton of a date formatted with the specified date/time pattern
* @param date date to format
* @param pattern desired date/time pattern
* @param timeZone timezone ID
* @return the formatted date/time string
*/
private static String formatDateWithPattern(Date date, String pattern, String timeZone) {
SimpleDateFormat sdf = new SimpleDateFormat(pattern, Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone(timeZone));
if (!timeZone.equalsIgnoreCase("UTC")) {
// TimeZone.getTimeZone() returns UTC for unknown time zones, so make sure
// that we only get UTC when it's explicitly requested.
assertThat("unexpected UTC (time zone not found for: \"" + timeZone + "\")",
sdf.getTimeZone(), is(not(TimeZone.getTimeZone("UTC"))));
}
return sdf.format(date);
}
/**
* Generates a LoggingEvent
* @param timestamp desired _timestamp (in ms) of event
* @return the newly created LoggingEvent
*/
private LoggingEvent makeLoggingEvent(long timestamp) {
LoggingEvent event = new LoggingEvent(FormattingConverter.class.getName(),
_logger,
Level.INFO,
"Some message",
null,
null);
event.setTimeStamp(timestamp);
return event;
}
/**
* Gets a DateConverter, configured with options and using the default context
* @param options the conversion pattern's options
* @return the newly created DateConverter
*/
private DateConverter getDateConverter(String... options) {
DateConverter converter = new DateConverter();
converter.setContext(_context);
converter.setOptionList(Arrays.asList(options));
return converter;
}
/**
* Gets the output of a DateConverter, configured with the given settings
* @param timestamp _timestamp to display
* @param options the conversion pattern's options
* @return the DateConverter's output
*/
private String convert(long timestamp, String... options) {
DateConverter converter = getDateConverter(options);
converter.start();
return converter.convert(makeLoggingEvent(timestamp));
}
}