/*
 * 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.
 */

#include <log4cxx/helpers/cacheddateformat.h>
#include "../logunit.h"
#include <log4cxx/helpers/absolutetimedateformat.h>
#include <log4cxx/helpers/iso8601dateformat.h>
#include <log4cxx/helpers/relativetimedateformat.h>
#include <log4cxx/helpers/pool.h>
#include <locale>
#include "../insertwide.h"
#include <apr.h>
#include <apr_time.h>
#include "localechanger.h"

using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::pattern;

#define LOCALE_US "C"
#if defined(_WIN32)
#define LOCALE_JP "Japanese_japan"
#else
#define LOCALE_JP "ja_JP"
#endif


//Define INT64_C for compilers that don't have it
#if (!defined(INT64_C))
#define INT64_C(value)  value ##LL
#endif

#define LOG4CXX_TEST 1
#include <log4cxx/private/log4cxx_private.h>


/**
 * Unit test {@link CachedDateFormat}.
 */
LOGUNIT_CLASS(CachedDateFormatTestCase)
   {
     LOGUNIT_TEST_SUITE( CachedDateFormatTestCase );
     LOGUNIT_TEST(test1);
     LOGUNIT_TEST(test2);
     LOGUNIT_TEST(test3);
     LOGUNIT_TEST(test4);
#if LOG4CXX_HAS_STD_LOCALE
     LOGUNIT_TEST(test5);
#endif
     LOGUNIT_TEST(test6);
     LOGUNIT_TEST(test8);
//   Gump doesn't like this test
//     LOGUNIT_TEST(test9);
     LOGUNIT_TEST(test10);
     LOGUNIT_TEST(test11);
     LOGUNIT_TEST(test12);
     LOGUNIT_TEST(test13);
     LOGUNIT_TEST(test14);
     LOGUNIT_TEST(test15);
     LOGUNIT_TEST(test16);
     LOGUNIT_TEST(test17);
     LOGUNIT_TEST(test18);
     LOGUNIT_TEST(test19);
     LOGUNIT_TEST(test20);
     LOGUNIT_TEST(test21);
     LOGUNIT_TEST(test22);
     LOGUNIT_TEST_SUITE_END();

#define MICROSECONDS_PER_DAY APR_INT64_C(86400000000)

   public:

  /**
   * Test multiple calls in close intervals.
   */
  void test1() {
    //   subsequent calls within one minute
    //     are optimized to reuse previous formatted value
    //     make a couple of nearly spaced calls
    DateFormatPtr baseFormatter(new AbsoluteTimeDateFormat());
    CachedDateFormat gmtFormat(baseFormatter, 1000000);
    gmtFormat.setTimeZone(TimeZone::getGMT());

    apr_time_t jul1 = MICROSECONDS_PER_DAY * 12601L;
    Pool p;

    LogString actual;

    gmtFormat.format(actual, jul1, p);
    LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:00,000"), actual);
    actual.erase(actual.begin(), actual.end());

    gmtFormat.format(actual, jul1 + 8000, p);
    LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:00,008"), actual);
    actual.erase(actual.begin(), actual.end());

    gmtFormat.format(actual, jul1 + 17000, p);
    LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:00,017"), actual);
    actual.erase(actual.begin(), actual.end());

    gmtFormat.format(actual, jul1 + 237000, p);
    LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:00,237"), actual);
    actual.erase(actual.begin(), actual.end());

    gmtFormat.format(actual, jul1 + 1415000, p);
    LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:01,415"), actual);
    actual.erase(actual.begin(), actual.end());

  }

  /**
   *  Check for interaction between caches.
   */

  void test2() {
      apr_time_t jul2 = MICROSECONDS_PER_DAY * 12602;
      DateFormatPtr baseFormatter(new AbsoluteTimeDateFormat());
      CachedDateFormat gmtFormat(baseFormatter, 1000000);
      gmtFormat.setTimeZone(TimeZone::getGMT());

     DateFormatPtr chicagoBase(new AbsoluteTimeDateFormat());
     CachedDateFormat chicagoFormat(chicagoBase, 1000000);
     chicagoFormat.setTimeZone(TimeZone::getTimeZone(LOG4CXX_STR("GMT-5")));

     Pool p;
     LogString actual;
     gmtFormat.format(actual, jul2, p);
     LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:00,000"), actual);

     actual.erase(actual.begin(), actual.end());
     chicagoFormat.format(actual, jul2, p);
     LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("19:00:00,000"), actual);

     actual.erase(actual.begin(), actual.end());
     gmtFormat.format(actual, jul2, p);
     LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:00,000"), actual);
  }

  /**
   * Test multiple calls in close intervals prior to 1 Jan 1970.
   */
  void test3() {
    //   subsequent calls within one minute
    //     are optimized to reuse previous formatted value
    //     make a couple of nearly spaced calls
    DateFormatPtr baseFormatter(new AbsoluteTimeDateFormat());
    CachedDateFormat gmtFormat(baseFormatter, 1000000);
    gmtFormat.setTimeZone(TimeZone::getGMT());

    apr_time_t ticks = MICROSECONDS_PER_DAY * -7;

    Pool p;

    LogString actual;


    gmtFormat.format(actual, ticks, p);
    LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:00,000"), actual);
    actual.erase(actual.begin(), actual.end());

   //
   //   APR's explode_time method does not properly calculate tm_usec
   //     prior to 1 Jan 1970 on Unix
   gmtFormat.format(actual, ticks + 8000, p);
   LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:00,008"), actual);
   actual.erase(actual.begin(), actual.end());

   gmtFormat.format(actual, ticks + 17000, p);
   LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:00,017"), actual);
   actual.erase(actual.begin(), actual.end());

    gmtFormat.format(actual, ticks + 237000, p);
    LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:00,237"), actual);
    actual.erase(actual.begin(), actual.end());

    gmtFormat.format(actual, ticks + 1423000, p);
    LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:01,423"), actual);
  }

  void assertFormattedEquals(
      const DateFormatPtr& baseFormat,
      const CachedDateFormat& cachedFormat,
      apr_time_t date,
      Pool& p) {
        LogString expected;
        LogString actual;

        baseFormat->format(expected, date, p);
        cachedFormat.format(actual, date, p);


        LOGUNIT_ASSERT_EQUAL(expected, actual);
  }

  void test4() {
    //   subsequent calls within one minute
    //     are optimized to reuse previous formatted value
    //     make a couple of nearly spaced calls
#if LOG4CXX_HAS_STD_LOCALE
    std::locale loco(LOCALE_US);
    std::locale* localeEN = &loco;
#else
    std::locale* localeEN = NULL;
#endif
    DateFormatPtr baseFormat(
         new SimpleDateFormat(LOG4CXX_STR("EEE, MMM dd, HH:mm:ss.SSS Z"), localeEN));
    CachedDateFormat cachedFormat(baseFormat, 1000000);
    //
    //   use a date in 2000 to attempt to confuse the millisecond locator
    apr_time_t ticks = MICROSECONDS_PER_DAY * 11141;

    Pool p;

    assertFormattedEquals(baseFormat, cachedFormat, ticks, p);
    assertFormattedEquals(baseFormat, cachedFormat, ticks + 8000, p);
    assertFormattedEquals(baseFormat, cachedFormat, ticks + 17000, p);
    assertFormattedEquals(baseFormat, cachedFormat, ticks + 237000, p);
    assertFormattedEquals(baseFormat, cachedFormat, ticks + 1415000, p);
  }


#if LOG4CXX_HAS_STD_LOCALE
  void test5() {
    //   subsequent calls within one minute
    //     are optimized to reuse previous formatted value
    //     make a couple of nearly spaced calls
    LocaleChanger localeChange(LOCALE_JP);
    if (localeChange.isEffective()) {
        DateFormatPtr baseFormat(new SimpleDateFormat(
                   LOG4CXX_STR("EEE, MMM dd, HH:mm:ss.SSS Z")));
        CachedDateFormat cachedFormat(baseFormat, 1000000);
        //
        //   use a date in 2000 to attempt to confuse the millisecond locator
        apr_time_t ticks = MICROSECONDS_PER_DAY * 11141;

        Pool p;

        assertFormattedEquals(baseFormat, cachedFormat, ticks, p);
        assertFormattedEquals(baseFormat, cachedFormat, ticks + 8000, p);
        assertFormattedEquals(baseFormat, cachedFormat, ticks + 17000, p);
        assertFormattedEquals(baseFormat, cachedFormat, ticks + 237000, p);
        assertFormattedEquals(baseFormat, cachedFormat, ticks + 1415000, p);
    }
  }
#endif

  /**
   * Checks that numberFormat works as expected.
   */
  void test6() {
    LogString numb;
    Pool p;
    AbsoluteTimeDateFormat formatter;
    formatter.numberFormat(numb, 87, p);
    LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("87"), numb);
  }


  /**
   * Set time zone on cached and check that it is effective.
   */
  void test8() {
    DateFormatPtr baseFormat(new SimpleDateFormat(LOG4CXX_STR("yyyy-MM-dd HH:mm:ss,SSS")));
    baseFormat->setTimeZone(TimeZone::getGMT());
    CachedDateFormat cachedFormat(baseFormat, 1000000);
    apr_time_t jul4 = MICROSECONDS_PER_DAY * 12603;

    Pool p;

    LogString actual;
    cachedFormat.format(actual, jul4, p);
    LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("2004-07-04 00:00:00,000"), actual);

    cachedFormat.setTimeZone(TimeZone::getTimeZone(LOG4CXX_STR("GMT-6")));
    actual.erase(actual.begin(), actual.end());
    cachedFormat.format(actual, jul4, p);

    LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("2004-07-03 18:00:00,000"), actual);
  }


/**
 * Test of caching when less than three millisecond digits are specified.
 */
void test9() {
  std::locale localeUS(LOCALE_US);

  DateFormatPtr baseFormat = new SimpleDateFormat(
      LOG4CXX_STR("yyyy-MMMM-dd HH:mm:ss,SS Z"), &localeUS);
  DateFormatPtr cachedFormat = new CachedDateFormat(baseFormat, 1000000);
  TimeZonePtr cet = TimeZone::getTimeZone(LOG4CXX_STR("GMT+1"));
  cachedFormat->setTimeZone(cet);


   apr_time_exp_t c;
   memset(&c, 0, sizeof(c));
   c.tm_year = 104;
   c.tm_mon = 11;
   c.tm_mday = 12;
   c.tm_hour = 19;
   c.tm_sec = 37;
   c.tm_usec = 23000;

   apr_time_t dec12;
   apr_status_t stat = apr_time_exp_gmt_get(&dec12, &c);
   const apr_status_t statOK = 0;
   LOGUNIT_ASSERT_EQUAL(statOK, stat);

   Pool p;

   LogString s;
   cachedFormat->format(s, dec12, p);

   LOGUNIT_ASSERT_EQUAL(
       (LogString) LOG4CXX_STR("2004-December-12 20:00:37,23 +0100"), s);

    memset(&c, 0, sizeof(c));
    c.tm_year = 104;
    c.tm_mon = 11;
    c.tm_mday = 31;
    c.tm_hour = 23;
    c.tm_sec = 13;
    c.tm_usec = 905000;

    apr_time_t jan1;
    stat = apr_time_exp_gmt_get(&jan1, &c);
    LOGUNIT_ASSERT_EQUAL(statOK, stat);

    s.erase(s.begin(), s.end());
    cachedFormat->format(s, jan1, p);

    LOGUNIT_ASSERT_EQUAL(
       (LogString) LOG4CXX_STR("2005-January-01 00:00:13,905 +0100"), s);
}


/**
 * Test when millisecond position moves but length remains constant.
 */
void test10() {
#if LOG4CXX_HAS_STD_LOCALE
  std::locale loco("C");
  std::locale* localeUS = &loco;
#else
  std::locale* localeUS = NULL;
#endif
  DateFormatPtr baseFormat = new SimpleDateFormat(
      LOG4CXX_STR("MMMM SSS EEEEEE"), localeUS);
  DateFormatPtr cachedFormat = new CachedDateFormat(baseFormat, 1000000);
  TimeZonePtr cet = TimeZone::getTimeZone(LOG4CXX_STR("GMT+1"));
  cachedFormat->setTimeZone(cet);

  apr_time_exp_t c;
  memset(&c, 0, sizeof(c));
  c.tm_year = 104;
  c.tm_mon = 9;
  c.tm_mday = 5;
  c.tm_hour = 21;
  c.tm_sec = 37;
  c.tm_usec = 23000;

  apr_time_t oct5;
  apr_status_t stat = apr_time_exp_gmt_get(&oct5, &c);
  const apr_status_t statOK = 0;
  LOGUNIT_ASSERT_EQUAL(statOK, stat);

  Pool p;

  LogString s;
  cachedFormat->format(s, oct5, p);

  LOGUNIT_ASSERT_EQUAL(
    (LogString) LOG4CXX_STR("October 023 Tuesday"), s);

  memset(&c, 0, sizeof(c));
  c.tm_year = 104;
  c.tm_mon = 10;
  c.tm_mday = 1;
  c.tm_usec = 23000;

  apr_time_t nov1;
  stat = apr_time_exp_gmt_get(&nov1, &c);
  LOGUNIT_ASSERT_EQUAL(statOK, stat);

  s.erase(s.begin(), s.end());
  cachedFormat->format(s, nov1, p);

  LOGUNIT_ASSERT_EQUAL(
     (LogString) LOG4CXX_STR("November 023 Monday"), s);

   nov1 += 961000;
   s.erase(s.begin(), s.end());
   cachedFormat->format(s, nov1, p);

   LOGUNIT_ASSERT_EQUAL(
      (LogString) LOG4CXX_STR("November 984 Monday"), s);
}

/**
 * Test that tests if caching is skipped if only "SS"
 *     is specified.
 */
void test11() {
   //
   //   Earlier versions could be tricked by "SS0" patterns.
   //
   LogString badPattern(LOG4CXX_STR("ss,SS0"));
   DateFormatPtr simpleFormat = new SimpleDateFormat(badPattern);
   DateFormatPtr gmtFormat = new CachedDateFormat(simpleFormat, 1000000);
   gmtFormat->setTimeZone(TimeZone::getGMT());

   //
   // The first request has to 100 ms after an ordinal second
   //    to push the literal zero out of the pattern check
   apr_time_t ticks = MICROSECONDS_PER_DAY * 11142L;
   apr_time_t jul2 = ticks + 120000;

   Pool p;

   LogString s;
   gmtFormat->format(s, jul2, p);

   LOGUNIT_ASSERT_EQUAL(
      (LogString) LOG4CXX_STR("00,1200"), s);

   jul2 = ticks + 87000;

   s.erase(s.begin(), s.end());
   gmtFormat->format(s, jul2, p);

   LOGUNIT_ASSERT_EQUAL(
      (LogString) LOG4CXX_STR("00,870"), s);
}

/**
 * Check pattern location for ISO8601
 */
void test12() {
   DateFormatPtr df    = new SimpleDateFormat(LOG4CXX_STR("yyyy-MM-dd HH:mm:ss,SSS"));
   apr_time_t    ticks = 11142L * MICROSECONDS_PER_DAY;
   Pool p;
   LogString formatted;

   df->format(formatted, ticks, p);
   int msStart = CachedDateFormat::findMillisecondStart(ticks, formatted, df, p);
   LOGUNIT_ASSERT_EQUAL(20, msStart);

   // Test for for milliseconds overlapping with the magic ones as per LOGCXX-420.
   apr_time_exp_t c;
   memset(&c, 0, sizeof(c));
   c.tm_year = 110;
   c.tm_mon  = 7;
   c.tm_mday = 12;
   c.tm_hour = 9;
   c.tm_min  = 4;
   c.tm_sec  = 50;
   c.tm_usec = 406000;

   LOGUNIT_ASSERT_EQUAL(0, apr_time_exp_gmt_get(&ticks, &c));

   formatted.clear();
   df->format(formatted, ticks, p);
   msStart = CachedDateFormat::findMillisecondStart(ticks, formatted, df, p);
   LOGUNIT_ASSERT_EQUAL(20, msStart);

   c.tm_usec = 609000;
   LOGUNIT_ASSERT_EQUAL(0, apr_time_exp_gmt_get(&ticks, &c));

   formatted.clear();
   df->format(formatted, ticks, p);
   msStart = CachedDateFormat::findMillisecondStart(ticks, formatted, df, p);
   LOGUNIT_ASSERT_EQUAL(20, msStart);
}

/**
 * Check pattern location for DATE
 */
void test13() {
   DateFormatPtr df = new SimpleDateFormat(LOG4CXX_STR("yyyy-MM-dd"));
   apr_time_t ticks = 11142L * MICROSECONDS_PER_DAY;

   Pool p;

   LogString formatted;
   df->format(formatted, ticks, p);

   int millisecondStart = CachedDateFormat::findMillisecondStart(ticks,
       formatted, df, p);
   LOGUNIT_ASSERT_EQUAL((int) CachedDateFormat::NO_MILLISECONDS, millisecondStart);
}

/**
 * Check pattern location for ABSOLUTE
 */
void test14() {
   DateFormatPtr df = new SimpleDateFormat(LOG4CXX_STR("HH:mm:ss,SSS"));
   apr_time_t ticks = 11142L * MICROSECONDS_PER_DAY;

   Pool p;
   LogString formatted;
   df->format(formatted, ticks, p);

   int millisecondStart = CachedDateFormat::findMillisecondStart(ticks,
      formatted, df, p);
   LOGUNIT_ASSERT_EQUAL(9, millisecondStart);
}

/**
 * Check pattern location for single S
 */
void test15() {
   DateFormatPtr df = new SimpleDateFormat(LOG4CXX_STR("HH:mm:ss,S"));
   apr_time_t ticks = 11142L * MICROSECONDS_PER_DAY;

   Pool p;
   LogString formatted;
   df->format(formatted, ticks, p);

   int millisecondStart = CachedDateFormat::findMillisecondStart(ticks,
      formatted, df, p);
   LOGUNIT_ASSERT_EQUAL((int) CachedDateFormat::UNRECOGNIZED_MILLISECONDS, millisecondStart);
}

/**
 * Check pattern location for single SS
 */
void test16() {
   DateFormatPtr df = new SimpleDateFormat(LOG4CXX_STR("HH:mm:ss,SS"));
   apr_time_t ticks = 11142L * MICROSECONDS_PER_DAY;

   Pool p;
   LogString formatted;
   df->format(formatted, ticks, p);

   int millisecondStart =
      CachedDateFormat::findMillisecondStart(ticks, formatted, df, p);
   LOGUNIT_ASSERT_EQUAL((int) CachedDateFormat::UNRECOGNIZED_MILLISECONDS, millisecondStart);
}

/**
 * Check caching when multiple SSS appear in pattern
 */
void test17() {
    apr_time_t jul2 = 12602L * MICROSECONDS_PER_DAY;
    LogString badPattern(LOG4CXX_STR("HH:mm:ss,SSS HH:mm:ss,SSS"));
    DateFormatPtr simpleFormat = new SimpleDateFormat(badPattern);
    simpleFormat->setTimeZone(TimeZone::getGMT());
    DateFormatPtr cachedFormat = new CachedDateFormat(simpleFormat, 1000000);

    Pool p;
    LogString s;
    cachedFormat->format(s, jul2, p);

    LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:00,000 00:00:00,000"), s);
    jul2 += 120000;

    s.erase(s.begin(), s.end());
    simpleFormat->format(s, jul2, p);
    LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:00,120 00:00:00,120"), s);

    s.erase(s.begin(), s.end());
    int msStart = CachedDateFormat::findMillisecondStart(jul2, s, simpleFormat, p);
    LOGUNIT_ASSERT_EQUAL((int) CachedDateFormat::UNRECOGNIZED_MILLISECONDS, msStart);

    cachedFormat->format(s, jul2, p);
    LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("00:00:00,120 00:00:00,120"), s) ;

    int maxValid = CachedDateFormat::getMaximumCacheValidity(badPattern);
    LOGUNIT_ASSERT_EQUAL(1000, maxValid);

    // Test overlapping millis with a magic string from CachedDateFormat for LOGCXX-420.
    s.clear();
    jul2 += 286000;
    cachedFormat->format(s, jul2, p);
    msStart = CachedDateFormat::findMillisecondStart(jul2, s, simpleFormat, p);
    LOGUNIT_ASSERT_EQUAL((int) CachedDateFormat::UNRECOGNIZED_MILLISECONDS, msStart);

    s.clear();
    jul2 += 203000;
    cachedFormat->format(s, jul2, p);
    msStart = CachedDateFormat::findMillisecondStart(jul2, s, simpleFormat, p);
    LOGUNIT_ASSERT_EQUAL((int) CachedDateFormat::UNRECOGNIZED_MILLISECONDS, msStart);
}

/**
 * Check that patterns not containing microseconds
 * are reported as being able to be cached for a full second.
 */
void test18() {

    int maxValid =
       CachedDateFormat::getMaximumCacheValidity(
          LOG4CXX_STR("yyyy-MM-dd"));
    LOGUNIT_ASSERT_EQUAL(1000000, maxValid);
}

/**
 * Check that patterns not containing 3 microseconds
 * are reported as being able to be cached for a full second.
 */
void test19() {

    int maxValid =
       CachedDateFormat::getMaximumCacheValidity(
          LOG4CXX_STR("yyyy-MM-dd SSS"));
    LOGUNIT_ASSERT_EQUAL(1000000, maxValid);
}

/**
 * Check that patterns not containing 2 S's
 * are reported as being able to be cached for only a millisecond.
 */
void test20() {

    int maxValid =
       CachedDateFormat::getMaximumCacheValidity(
          LOG4CXX_STR("yyyy-MM-dd SS"));
    LOGUNIT_ASSERT_EQUAL(1000, maxValid);
}

/**
 * Check that patterns not containing multi S groups
 * are reported as being able to be cached for only a millisecond.
 */
void test21() {

    int maxValid =
       CachedDateFormat::getMaximumCacheValidity(
          LOG4CXX_STR("yyyy-MM-dd SSS SSS"));
    LOGUNIT_ASSERT_EQUAL(1000, maxValid);
}

/**
 * Check that findMillisecondStart correctly handles timestamps
 * which use the magic millisecond value 654.
 */
void test22() {
    DateFormatPtr baseFormatter(new ISO8601DateFormat());
    CachedDateFormat isoFormat(baseFormatter, 1000000);
    isoFormat.setTimeZone(TimeZone::getGMT());

    Pool p;
    LogString formatted;

    isoFormat.format(formatted, 654000, p);
    LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("1970-01-01 00:00:00,654"), formatted);

    formatted.clear();
    isoFormat.format(formatted, 999000, p);
    LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("1970-01-01 00:00:00,999"), formatted);

    formatted.clear();
    isoFormat.format(formatted, 1654010, p);
    LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("1970-01-01 00:00:01,654"), formatted);

    formatted.clear();
    isoFormat.format(formatted, 1999010, p);
    LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("1970-01-01 00:00:01,999"), formatted);
}

};

LOGUNIT_TEST_SUITE_REGISTRATION(CachedDateFormatTestCase);
