package com.thoughtworks.xstream.converters.basic;

import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.testutil.TimeZoneChanger;

import junit.framework.TestCase;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

public class DateConverterTest extends TestCase {

    private DateConverter converter = new DateConverter();

    protected void setUp() throws Exception {
        super.setUp();

        // Ensure that this test always run as if it were in the EST timezone.
        // This prevents failures when running the tests in different zones.
        // Note: 'EST' has no relevance - it was just a randomly chosen zone.
        TimeZoneChanger.change("EST");
    }

    protected void tearDown() throws Exception {
        TimeZoneChanger.reset();
        super.tearDown();
    }


    public void testRetainsDetailDownToMillisecondLevel() {
        // setup
        Date in = new Date();

        // execute
        String text = converter.toString(in);
        Date out = (Date) converter.fromString(text);

        // verify
        assertEquals(in, out);
        assertEquals(in.toString(), out.toString());
        assertEquals(in.getTime(), out.getTime());
    }

    public void testUnmarshallsOldXStreamDatesThatLackMillisecond() {
        Date expected = (Date) converter.fromString("2004-02-22 15:16:04.0 EST");

        assertEquals(expected, converter.fromString("2004-02-22 15:16:04.0 EST"));
        assertEquals(expected, converter.fromString("2004-02-22 15:16:04.0 PM"));
        assertEquals(expected, converter.fromString("2004-02-22 15:16:04PM"));
        assertEquals(expected, converter.fromString("2004-02-22 15:16:04 EST"));
        assertEquals(expected, converter.fromString("2004-02-22 15:16:04EST"));
    }

    public void testRetainsTimeZone() {
        Calendar cal = Calendar.getInstance();
        cal.clear();
        cal.set(2007, Calendar.MAY, 17, 19, 20, 32);
        Date dateEST = cal.getTime();
        String strEST = converter.toString(dateEST);
        assertEquals("2007-05-17 19:20:32.0 EST", strEST);
        TimeZone.setDefault(TimeZone.getTimeZone("GMT+1"));
        Date dateGMT = (Date)converter.fromString(strEST);
        assertEquals(dateEST, dateGMT);
        assertEquals("2007-05-18 01:20:32.0 GMT+01:00", converter.toString(dateGMT));
    }
    
    public void testIsThreadSafe() throws InterruptedException {
        final List results = Collections.synchronizedList(new ArrayList());
        final DateConverter converter = new DateConverter();
        final Object monitor = new Object();
        final int numberOfCallsPerThread = 20;
        final int numberOfThreads = 20;

        // spawn some concurrent threads, that hammer the converter
        Runnable runnable = new Runnable() {
            public void run() {
                for (int i = 0; i < numberOfCallsPerThread; i++) {
                    try {
                        converter.fromString("2004-02-22 15:16:04.0 EST");
                        results.add("PASS");
                    } catch (ConversionException e) {
                        results.add("FAIL");
                    } finally {
                        synchronized (monitor) {
                            monitor.notifyAll();
                        }
                    }
                }
            }
        };
        for (int i = 0; i < numberOfThreads; i++) {
            new Thread(runnable).start();
        }

        // wait for all results
        while (results.size() < numberOfThreads * numberOfCallsPerThread) {
            synchronized (monitor) {
                monitor.wait(100);
            }
        }

        assertTrue("Nothing suceeded", results.contains("PASS"));
        assertFalse("At least one attempt failed", results.contains("FAIL"));
    }
}

@@ -109,16 +109,58 @@
 eption;%0A
+import com.thoughtworks.xstream.core.JVM;%0A
 import c
@@ -209,16 +209,16 @@
 hanger;%0A
-
 %0Aimport 
@@ -371,24 +371,49 @@
 .util.List;%0A
+import java.util.Locale;%0A
 import java.
@@ -428,16 +428,17 @@
 eZone;%0A%0A
+%0A
 public c
@@ -1005,17 +1005,16 @@
 %0A    %7D%0A%0A
-%0A
     publ
@@ -1195,33 +1195,32 @@
 ate out = (Date)
- 
 converter.fromSt
@@ -1492,17 +1492,16 @@
 = (Date)
- 
 converte
@@ -2204,24 +2204,557 @@
 g(dateEST);%0A
+        TimeZone timeZone = TimeZone.getDefault();%0A        if (!JVM.is14() && timeZone.inDaylightTime(dateEST)) %7B%0A            // JDK 1.3 does not support TimeZone without daylight saving!%0A            assertEquals(%222007-05-17 19:20:32.0 EDT%22, strEST);%0A            TimeZone.setDefault(TimeZone.getTimeZone(%22GMT+1%22));%0A            Date dateGMT = (Date)converter.fromString(strEST);%0A            assertEquals(dateEST, dateGMT);%0A            assertEquals(%222007-05-18 00:20:32.0 GMT+01:00%22, converter.toString(dateGMT));%0A        %7D else %7B%0A    
         asse
@@ -2800,32 +2800,36 @@
 trEST);%0A        
+ 
+   
 TimeZone.setDefa
@@ -2864,32 +2864,36 @@
 T+1%22));%0A        
+    
 Date dateGMT = (
@@ -2927,32 +2927,36 @@
 trEST);%0A        
+ 
+   
 assertEquals(dat
@@ -2963,32 +2963,36 @@
 eEST, dateGMT);%0A
+    
         assertEq
@@ -3061,26 +3061,32 @@
 eGMT));%0A
+        %7D%0A
     %7D%0A
-    
 %0A    pub

Fix for JDK 1.3