/**
   * Fairfieldの公式の確認。
   *
   * @param pattern
   * @param timeZone
   * @param failsOnAssert
   * @throws ParseException
   */
  private void assertFairfieldDays(String pattern, TimeZone timeZone, boolean failsOnAssert)
      throws ParseException {
    SimpleDateFormat sdf = new SimpleDateFormat(pattern);
    sdf.setTimeZone(timeZone);
    SafeDateFormat safe = SafeDateFormat.getInstance(pattern, timeZone);

    boolean passed = true;
    StringBuilder failedDates = new StringBuilder();
    String minYear = null;
    String maxYear = null;
    long ms = 0;
    for (int i = -100000; i < 100000; i++) {
      ms = 86400000L * i;
      String date = sdf.format(new Date(ms));
      long msDate = sdf.parse(date).getTime();
      if (failsOnAssert) {
        assertEquals(msDate, safe.parse(date));
        assertEquals(date, safe.format(msDate));
      }
      if (msDate != safe.parse(date)) {
        passed = false;
        int diff = (int) (msDate - safe.parse(date)) / 1000;
        failedDates.append('p').append(date).append('-').append(diff).append(',');
      }
      if (!date.equals(safe.format(msDate))) {
        passed = false;
        failedDates.append('f').append(date).append(',');
      }

      maxYear = date.substring(0, 4);
      if (minYear == null) {
        minYear = maxYear;
      }
    }

    if (passed) {
      System.out.printf(
          "passed %s from %s year till %s year\n", timeZone.getID(), minYear, maxYear);
    } else {
      failedDates.setLength(failedDates.length() - 1);
      System.out.printf("FAILED! %s %s\n", timeZone.getID(), failedDates.toString());
    }
  }
  @Test
  public void test() throws ParseException {
    // Fairfieldの公式ベースの確認
    for (String timeZoneId : TimeZone.getAvailableIDs()) {
      if (timeZoneId.contains("/")) {
        assertFairfieldDays("yyyyMMdd", TimeZone.getTimeZone(timeZoneId), false);
      }
    }

    // TimeZone確認
    for (String timeZoneId : new String[] {"UTC", "GMT+9", "JST", "America/New_York"}) {
      String pattern = "yyyy/MM/dd-HH:mm:ss.SSS";
      TimeZone timeZone = TimeZone.getTimeZone(timeZoneId);
      SimpleDateFormat sdf = new SimpleDateFormat(pattern);
      sdf.setTimeZone(timeZone);
      SafeDateFormat safe = SafeDateFormat.getInstance(pattern, timeZone);

      String date = sdf.format(new Date());
      long msDate = sdf.parse(date).getTime();
      assertEquals(timeZoneId, msDate, safe.parse(date));
      assertEquals(timeZoneId, date, safe.format(msDate));
    }
  }
 private static String getDateStr() {
   return safeDateFormat.format(System.currentTimeMillis());
 }
 @Benchmark
 public void formatOfSafeDateFormat() {
   safeDateFormat.format(System.currentTimeMillis());
 }