package com.cedarsoftware.util;
import org.junit.Test;
import java.text.DateFormatSymbols;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.TimeZone;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* @author John DeRegnaucourt (john@cedarsoftware.com)
* <br>
* Copyright (c) Cedar Software LLC
* <br><br>
* 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
* <br><br>
* http://www.apache.org/licenses/LICENSE-2.0
* <br><br>
* 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.
*/
public class TestSimpleDateFormat
{
@Test
public void testSimpleDateFormat1() throws Exception
{
SafeSimpleDateFormat x = new SafeSimpleDateFormat("yyyy-MM-dd");
String s = x.format(getDate(2013, 9, 7, 16, 15, 31));
assertEquals("2013-09-07", s);
Date then = x.parse(s);
Calendar cal = Calendar.getInstance();
cal.clear();
cal.setTime(then);
assertEquals(2013, cal.get(Calendar.YEAR));
assertEquals(8, cal.get(Calendar.MONTH)); // Sept
assertEquals(7, cal.get(Calendar.DAY_OF_MONTH));
assertEquals(0, cal.get(Calendar.HOUR_OF_DAY));
assertEquals(0, cal.get(Calendar.MINUTE));
assertEquals(0, cal.get(Calendar.SECOND));
}
@Test(expected=ParseException.class)
public void testSetLenient() throws Exception
{
//February 942, 1996
SafeSimpleDateFormat x = new SafeSimpleDateFormat("MMM dd, yyyy");
Date then = x.parse("March 33, 2013");
Calendar cal = Calendar.getInstance();
cal.clear();
cal.setTime(then);
assertEquals(2013, cal.get(Calendar.YEAR));
assertEquals(3, cal.get(Calendar.MONTH)); // Sept
assertEquals(2, cal.get(Calendar.DAY_OF_MONTH));
assertEquals(0, cal.get(Calendar.HOUR_OF_DAY));
assertEquals(0, cal.get(Calendar.MINUTE));
assertEquals(0, cal.get(Calendar.SECOND));
x.setLenient(false);
then = x.parse("March 33, 2013");
}
@Test(expected=ParseException.class)
public void testSetCalendar() throws Exception
{
SafeSimpleDateFormat x = new SafeSimpleDateFormat("yyyy-MM-dd hh:mm:ss");
x.setCalendar(Calendar.getInstance());
String s = x.format(getDate(2013, 9, 7, 16, 15, 31));
assertEquals("2013-09-07 04:15:31", s);
Date then = x.parse(s);
Calendar cal = Calendar.getInstance();
cal.clear();
cal.setTime(then);
assertEquals(2013, cal.get(Calendar.YEAR));
assertEquals(8, cal.get(Calendar.MONTH)); // Sept
assertEquals(7, cal.get(Calendar.DAY_OF_MONTH));
assertEquals(4, cal.get(Calendar.HOUR_OF_DAY));
assertEquals(15, cal.get(Calendar.MINUTE));
assertEquals(31, cal.get(Calendar.SECOND));
SafeSimpleDateFormat x2 = new SafeSimpleDateFormat("MMM dd, yyyy");
then = x2.parse("March 33, 2013");
cal = Calendar.getInstance();
cal.clear();
cal.setTime(then);
assertEquals(2013, cal.get(Calendar.YEAR));
assertEquals(8, cal.get(Calendar.MONTH)); // Sept
assertEquals(7, cal.get(Calendar.DAY_OF_MONTH));
assertEquals(7, cal.get(Calendar.HOUR_OF_DAY));
assertEquals(15, cal.get(Calendar.MINUTE));
assertEquals(31, cal.get(Calendar.SECOND));
cal.clear();
cal.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
cal.setLenient(false);
x.setCalendar(cal);
x2.setCalendar(cal);
then = x2.parse(s);
cal = Calendar.getInstance();
cal.clear();
cal.setTime(then);
assertEquals(2013, cal.get(Calendar.YEAR));
assertEquals(3, cal.get(Calendar.MONTH)); // Sept
assertEquals(2, cal.get(Calendar.DAY_OF_MONTH));
assertEquals(0, cal.get(Calendar.HOUR_OF_DAY));
assertEquals(0, cal.get(Calendar.MINUTE));
assertEquals(0, cal.get(Calendar.SECOND));
then = x.parse("March 33, 2013");
}
@Test
public void testSetDateSymbols() throws Exception {
SafeSimpleDateFormat x = new SafeSimpleDateFormat("yyyy-MM-dd hh:mm:ss");
x.setCalendar(Calendar.getInstance());
String s = x.format(getDate(2013, 9, 7, 16, 15, 31));
assertEquals("2013-09-07 04:15:31", s);
Date then = x.parse(s);
Calendar cal = Calendar.getInstance();
cal.clear();
cal.setTime(then);
assertEquals(2013, cal.get(Calendar.YEAR));
assertEquals(8, cal.get(Calendar.MONTH)); // Sept
assertEquals(7, cal.get(Calendar.DAY_OF_MONTH));
assertEquals(4, cal.get(Calendar.HOUR_OF_DAY));
assertEquals(15, cal.get(Calendar.MINUTE));
assertEquals(31, cal.get(Calendar.SECOND));
x = new SafeSimpleDateFormat("yyyy-MM-dd hh:mm:ss");
x.setNumberFormat(new NumberFormat() {
@Override
public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
return toAppendTo;
}
@Override
public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
return toAppendTo;
}
@Override
public Number parse(String source, ParsePosition parsePosition) {
return new Integer(0);
}
});
s = x.format(getDate(2013, 9, 7, 16, 15, 31));
assertEquals("2013-09-07 04:15:31", s);
//NumberFormat.getPercentInstance();
}
@Test
public void testTimeZone() throws Exception
{
SafeSimpleDateFormat x = new SafeSimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String s = x.format(getDate(2013, 9, 7, 16, 15, 31));
assertEquals("2013-09-07 04:15:31", s);
Date then = x.parse(s);
Calendar cal = Calendar.getInstance();
cal.clear();
cal.setTime(then);
assertEquals(2013, cal.get(Calendar.YEAR));
assertEquals(8, cal.get(Calendar.MONTH)); // Sept
assertEquals(7, cal.get(Calendar.DAY_OF_MONTH));
assertEquals(4, cal.get(Calendar.HOUR_OF_DAY));
assertEquals(15, cal.get(Calendar.MINUTE));
assertEquals(31, cal.get(Calendar.SECOND));
TimeZone localTz = TimeZone.getDefault();
TimeZone tzLA = TimeZone.getTimeZone("America/Los_Angeles");
long txDiff = localTz.getRawOffset() + localTz.getDSTSavings()
- tzLA.getRawOffset() - tzLA.getDSTSavings();
x.setTimeZone(tzLA);
Calendar expectedDate = Calendar.getInstance();
expectedDate.setTimeInMillis(then.getTime() + txDiff);
then = x.parse(s);
cal = Calendar.getInstance();
cal.clear();
cal.setTime(then);
assertEquals(expectedDate.get(Calendar.YEAR), cal.get(Calendar.YEAR));
assertEquals(expectedDate.get(Calendar.MONTH), cal.get(Calendar.MONTH)); // Sept
assertEquals(expectedDate.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.DAY_OF_MONTH));
assertEquals(expectedDate.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.HOUR_OF_DAY));
assertEquals(expectedDate.get(Calendar.MINUTE), cal.get(Calendar.MINUTE));
assertEquals(expectedDate.get(Calendar.SECOND), cal.get(Calendar.SECOND));
}
@Test
public void testConcurrencyWillFail() throws Exception
{
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final Random random = new Random();
Thread[] threads = new Thread[16];
final long[]iter = new long[16];
final Date date1 = getDate(1965, 12, 17, 17, 40, 05);
final Date date2 = getDate(1996, 12, 24, 16, 18, 43);
final Date date3 = getDate(1998, 9, 30, 0, 25, 17);
final int[] r = new int[1];
final int[] s = new int[1];
final int[] t = new int[1];
final String[] passed = new String[1];
passed[0] = null;
for (int i=0; i < 16; i++)
{
final int index = i;
threads[i] = new Thread(new Runnable()
{
public void run()
{
try
{
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < 2000)
{
for (int j=0; j < 100; j++)
{
int op = random.nextInt(100);
if (op < 5)
{ // 5% calls to format date1
String a = format.format(date1);
Date x = format.parse(a);
r[0]++;
}
else if (op < 20)
{ // 15% puts
String b = format.format(date2);
Date y = format.parse(b);
s[0]++;
}
else
{ // 80% gets
String c = format.format(date3);
Date z = format.parse(c);
t[0]++;
}
}
iter[index]++;
}
}
catch (Exception e)
{
passed[0] = e.getMessage();
}
}
});
threads[i].setName("SafeSimpleDateFormat_T" + i);
threads[i].setDaemon(true);
threads[i].start();
}
for (int i=0; i < 16; i++)
{
try
{
threads[i].join();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
assertFalse(passed[0], passed[0] == null);
// System.out.println("r = " + r[0]);
// System.out.println("s = " + s[0]);
// System.out.println("t = " + t[0]);
}
@Test
public void testConcurrencyWontFail() throws Exception
{
final SafeSimpleDateFormat format = new SafeSimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final Random random = new Random();
Thread[] threads = new Thread[16];
final long[]iter = new long[16];
final Date date1 = getDate(1965, 12, 17, 17, 40, 05);
final Date date2 = getDate(1996, 12, 24, 16, 18, 43);
final Date date3 = getDate(1998, 9, 30, 0, 25, 17);
final int[] r = new int[1];
final int[] s = new int[1];
final int[] t = new int[1];
final String[] passed = new String[1];
passed[0] = null;
for (int i=0; i < 16; i++)
{
final int index = i;
threads[i] = new Thread(new Runnable()
{
public void run()
{
try
{
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < 2000)
{
for (int j=0; j < 100; j++)
{
int op = random.nextInt(100);
if (op < 5)
{ // 5% calls to format date1
String a = format.format(date1);
Date x = format.parse(a);
r[0]++;
}
else if (op < 20)
{ // 15% puts
String b = format.format(date2);
Date y = format.parse(b);
s[0]++;
}
else
{ // 80% gets
String c = format.format(date3);
Date z = format.parse(c);
t[0]++;
}
}
iter[index]++;
}
}
catch (Exception e)
{
passed[0] = e.getMessage();
}
}
});
threads[i].setName("SafeSimpleDateFormat_T" + i);
threads[i].setDaemon(true);
threads[i].start();
}
for (int i=0; i < 16; i++)
{
try
{
threads[i].join();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
assertTrue(passed[0], passed[0] == null);
// System.out.println("r = " + r[0]);
// System.out.println("s = " + s[0]);
// System.out.println("t = " + t[0]);
}
@Test
public void testParseObject() {
SafeSimpleDateFormat x = new SafeSimpleDateFormat("yyyy-MM-dd");
String s = x.format(getDate(2013, 9, 7, 16, 15, 31));
String d = "date: " + s;
assertEquals("2013-09-07", s);
Object then = (Date)x.parseObject(d, new ParsePosition(5));
Calendar cal = Calendar.getInstance();
cal.clear();
cal.setTime((Date)then);
assertTrue(cal.get(Calendar.YEAR) == 2013);
assertTrue(cal.get(Calendar.MONTH) == 8); // Sept
assertTrue(cal.get(Calendar.DAY_OF_MONTH) == 7);
}
@Test
public void test2DigitYear() throws Exception {
SafeSimpleDateFormat x = new SafeSimpleDateFormat("yy-MM-dd");
String s = x.format(getDate(13, 9, 7, 16, 15, 31));
assertEquals("13-09-07", s);
Object then = (Date)x.parse(s);
Calendar cal = Calendar.getInstance();
cal.clear();
cal.setTime((Date)then);
assertEquals(2013, cal.get(Calendar.YEAR));
assertEquals(8, cal.get(Calendar.MONTH)); // Sept
assertEquals(7, cal.get(Calendar.DAY_OF_MONTH));
cal.add(Calendar.YEAR, 87);
x.set2DigitYearStart(cal.getTime());
Object fut = (Date)x.parse(s);
cal.clear();
cal.setTime((Date)fut);
assertEquals(2113, cal.get(Calendar.YEAR));
assertEquals(8, cal.get(Calendar.MONTH)); // Sept
assertEquals(7, cal.get(Calendar.DAY_OF_MONTH));
}
@Test
public void testSetSymbols() throws Exception {
SafeSimpleDateFormat x = new SafeSimpleDateFormat("yy.MM.dd hh:mm aaa");
String s = x.format(getDate(13, 9, 7, 16, 15, 31));
assertEquals("13.09.07 04:15 PM", s);
SimpleDateFormat format = new SimpleDateFormat("yy-MM-dd");
DateFormatSymbols symbols = format.getDateFormatSymbols();
String[] ampm = new String[] { "foo", "bar"};
symbols.setAmPmStrings(ampm);
x.setDateFormatSymbols(symbols);
s = x.format(getDate(13, 9, 7, 16, 15, 31));
assertEquals("13.09.07 04:15 bar", s);
}
private Date getDate(int year, int month, int day, int hour, int min, int sec)
{
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(year, month - 1, day, hour, min, sec);
return cal.getTime();
}
}