// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * Copyright (C) 2006-2011, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */

package com.ibm.icu.tests;

import java.text.FieldPosition;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Date;
import java.util.Locale;

import com.ibm.icu.text.DateFormatSymbols;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;

public class SimpleDateFormatTest extends ICUTestCase {
    private static final String mdy = "MMM dd yyyy";
    private static final String md2 = "MMM dd yy";
    private static final String hmz = "'The time is' HH:mm:ss zzz";
    private static final String hmzmdy = hmz + " 'on' " + mdy;
    private static final String hmzmdyStr = "The time is 15:05:20 CST on Jan 10 2006";
        
    private static final TimeZone tzc = TimeZone.getTimeZone("CST");
    private static final TimeZone tzp = TimeZone.getTimeZone("PST");
    private static final Calendar cal = Calendar.getInstance(tzc);
    private static final Date date;
    static {
        cal.clear();
        cal.set(2006, 0, 10, 15, 5, 20); // arrgh, doesn't clear millis
        date = cal.getTime();
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.format(Calendar, StringBuffer, FieldPosition)'
     */
    public void testFormatCalendarStringBufferFieldPosition() {
        StringBuffer buf = new StringBuffer();
        FieldPosition fp = new FieldPosition(0);
        SimpleDateFormat sdf = new SimpleDateFormat(hmzmdy);
        sdf.format(cal, buf, fp);
        assertEquals(hmzmdyStr, buf.toString());
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.parse(String, Calendar, ParsePosition)'
     */
    public void testParseStringCalendarParsePosition() {
        Calendar cal = Calendar.getInstance(tzp);
        cal.clear();
        ParsePosition pp = new ParsePosition(0);
        SimpleDateFormat sdf = new SimpleDateFormat(hmzmdy);
        sdf.parse(hmzmdyStr, cal, pp);
        assertEquals(date, cal.getTime());
        // note: java doesn't return the parsed time zone
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.clone()'
     */
    public void testClone() {

    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat()'
     */
    public void testSimpleDateFormat() {
        SimpleDateFormat sdf = new SimpleDateFormat();
        java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat();
        assertEquals(jsdf.format(date), sdf.format(date));
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String)'
     */
    public void testSimpleDateFormatString() {
        SimpleDateFormat sdf = new SimpleDateFormat(mdy);
        java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy);
        assertEquals(jsdf.format(date), sdf.format(date));
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String, Locale)'
     */
    public void testSimpleDateFormatStringLocale() {
        Locale l = Locale.JAPAN;
        SimpleDateFormat sdf = new SimpleDateFormat(mdy, l);
        java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy, l);
        assertEquals(jsdf.format(date), sdf.format(date));
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String, ULocale)'
     */
    public void testSimpleDateFormatStringULocale() {
        ULocale l = ULocale.JAPAN;
        SimpleDateFormat sdf = new SimpleDateFormat(mdy, l);
        java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy, l.toLocale());
        assertEquals(jsdf.format(date), sdf.format(date));
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String, DateFormatSymbols)'
     */
    public void testSimpleDateFormatStringDateFormatSymbols() {
        Locale l = Locale.US;
        DateFormatSymbols dfs = new DateFormatSymbols(l);
        java.text.DateFormatSymbols jdfs = new java.text.DateFormatSymbols(l);
        SimpleDateFormat sdf = new SimpleDateFormat(mdy, dfs);
        java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy, jdfs);
        assertEquals(jsdf.format(date), sdf.format(date));
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.set2DigitYearStart(Date)'
     */
    public void testSet2DigitYearStart() {
        SimpleDateFormat sdf = new SimpleDateFormat(md2);
        sdf.set2DigitYearStart(date);
        try {
            Date d = sdf.parse("Jan 15 04");
            assertNotEqual(-1, d.toString().indexOf("2104"));
        }
        catch (ParseException pe) {
            fail(pe.getMessage());
        }
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.get2DigitYearStart()'
     */
    public void testGet2DigitYearStart() {
        SimpleDateFormat sdf = new SimpleDateFormat(md2);
        sdf.set2DigitYearStart(date);
        assertEquals(date, sdf.get2DigitYearStart());
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.toPattern()'
     */
    public void testToPattern() {
        SimpleDateFormat sdf = new SimpleDateFormat(mdy);
        assertEquals(mdy, sdf.toPattern());
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.toLocalizedPattern()'
     */
    public void testToLocalizedPattern() {
        Locale l = Locale.getDefault();
        Locale.setDefault(Locale.US);
        SimpleDateFormat sdf = new SimpleDateFormat(mdy);
        assertEquals(mdy, sdf.toLocalizedPattern());
        Locale.setDefault(l);
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.applyPattern(String)'
     */
    public void testApplyPattern() {
        SimpleDateFormat sdf = new SimpleDateFormat();
        sdf.setTimeZone(tzc);
        sdf.applyPattern(hmzmdy);
        assertEquals(hmzmdyStr, sdf.format(date));
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.applyLocalizedPattern(String)'
     */
    public void testApplyLocalizedPattern() {
        SimpleDateFormat sdf = new SimpleDateFormat();
        sdf.setTimeZone(tzc);
        sdf.applyLocalizedPattern(hmzmdy);
        assertEquals(hmzmdyStr, sdf.format(date));
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.getDateFormatSymbols()'
     */
    public void testGetDateFormatSymbols() {
        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
        SimpleDateFormat sdf = new SimpleDateFormat(mdy, dfs);
        assertEquals(dfs, sdf.getDateFormatSymbols());
    }

    /*
     * Test method for 'com.ibm.icu.text.SimpleDateFormat.setDateFormatSymbols(DateFormatSymbols)'
     */
    public void testSetDateFormatSymbols() {
        DateFormatSymbols dfs = new DateFormatSymbols(Locale.JAPAN);
        SimpleDateFormat sdf = new SimpleDateFormat(hmzmdy);
        sdf.setDateFormatSymbols(dfs);
        // assumes Japanese symbols do not have gregorian month names
        assertEquals(-1, sdf.format(date).indexOf("Jan"));
    }
}
