Locale-awareness for date parsing and formatting:

 - always format in en_US for best interchange
 - always parse in en_US, system locale and ISO-8601
diff --git a/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java b/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java
index 22a154f..4b3fa42 100644
--- a/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java
+++ b/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java
@@ -44,6 +44,7 @@
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.StringTokenizer;
+import java.util.TimeZone;
 import java.util.TreeSet;
 import java.util.UUID;
 
@@ -287,29 +288,40 @@
   }
 
   static class DefaultDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
-    private final DateFormat format;
+    private final DateFormat enUsFormat;
+    private final DateFormat localFormat;
+    private final DateFormat iso8601Format;
 
     DefaultDateTypeAdapter() {
-      this.format = DateFormat.getDateTimeInstance();
+      this(DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US),
+          DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT));
     }
 
-    DefaultDateTypeAdapter(final String datePattern) {
-      this.format = new SimpleDateFormat(datePattern);
+    DefaultDateTypeAdapter(String datePattern) {
+      this(new SimpleDateFormat(datePattern, Locale.US), new SimpleDateFormat(datePattern));
     }
 
-    DefaultDateTypeAdapter(final int style) {
-      this.format = DateFormat.getDateInstance(style);
+    DefaultDateTypeAdapter(int style) {
+      this(DateFormat.getDateInstance(style, Locale.US), DateFormat.getDateInstance(style));
     }
 
-    public DefaultDateTypeAdapter(final int dateStyle, final int timeStyle) {
-      this.format = DateFormat.getDateTimeInstance(dateStyle, timeStyle);
+    public DefaultDateTypeAdapter(int dateStyle, int timeStyle) {
+      this(DateFormat.getDateTimeInstance(dateStyle, timeStyle, Locale.US),
+          DateFormat.getDateTimeInstance(dateStyle, timeStyle));
+    }
+
+    public DefaultDateTypeAdapter(DateFormat enUsFormat, DateFormat localFormat) {
+      this.enUsFormat = enUsFormat;
+      this.localFormat = localFormat;
+      this.iso8601Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
+      this.iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
     }
 
     // These methods need to be synchronized since JDK DateFormat classes are not thread-safe
     // See issue 162
     public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
-      synchronized (format) {
-        String dateFormatAsString = format.format(src);
+      synchronized (localFormat) {
+        String dateFormatAsString = enUsFormat.format(src);
         return new JsonPrimitive(dateFormatAsString);
       }
     }
@@ -319,12 +331,20 @@
       if (!(json instanceof JsonPrimitive)) {
         throw new JsonParseException("The date should be a string value");
       }
-      try {
-        synchronized (format) {
-          return format.parse(json.getAsString());
+      synchronized (localFormat) {
+        try {
+          return localFormat.parse(json.getAsString());
+        } catch (ParseException ignored) {
         }
-      } catch (ParseException e) {
-        throw new JsonSyntaxException(e);
+        try {
+          return enUsFormat.parse(json.getAsString());
+        } catch (ParseException ignored) {
+        }
+        try {
+          return iso8601Format.parse(json.getAsString());
+        } catch (ParseException e) {
+          throw new JsonSyntaxException(json.getAsString(), e);
+        }
       }
     }
 
@@ -332,7 +352,7 @@
     public String toString() {
       StringBuilder sb = new StringBuilder();
       sb.append(DefaultDateTypeAdapter.class.getSimpleName());
-      sb.append('(').append(format.getClass().getSimpleName()).append(')');
+      sb.append('(').append(localFormat.getClass().getSimpleName()).append(')');
       return sb.toString();
     }
   }
@@ -454,7 +474,7 @@
         throw new JsonParseException(e);
       }
     }
-    
+
     public JsonElement serialize(InetAddress src, Type typeOfSrc,
         JsonSerializationContext context) {
       return new JsonPrimitive(src.getHostAddress());
diff --git a/gson/src/test/java/com/google/gson/DefaultDateTypeAdapterTest.java b/gson/src/test/java/com/google/gson/DefaultDateTypeAdapterTest.java
index bdc1417..e585531 100644
--- a/gson/src/test/java/com/google/gson/DefaultDateTypeAdapterTest.java
+++ b/gson/src/test/java/com/google/gson/DefaultDateTypeAdapterTest.java
@@ -17,12 +17,12 @@
 package com.google.gson;
 
 import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
-
-import junit.framework.TestCase;
-
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+import junit.framework.TestCase;
 
 /**
  * A simple unit test for the {@link DefaultDateTypeAdapter} class.
@@ -31,6 +31,100 @@
  */
 public class DefaultDateTypeAdapterTest extends TestCase {
 
+  public void testFormattingInEnUs() {
+    testFormattingAlwaysEmitsUsLocale(Locale.US);
+  }
+
+  public void testFormattingInFr() {
+    testFormattingAlwaysEmitsUsLocale(Locale.FRANCE);
+  }
+
+  private void testFormattingAlwaysEmitsUsLocale(Locale locale) {
+    TimeZone defaultTimeZone = TimeZone.getDefault();
+    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+    Locale defaultLocale = Locale.getDefault();
+    Locale.setDefault(locale);
+    try {
+      assertFormatted("Jan 1, 1970 12:00:00 AM", new DefaultDateTypeAdapter());
+      assertFormatted("1/1/70", new DefaultDateTypeAdapter(DateFormat.SHORT));
+      assertFormatted("Jan 1, 1970", new DefaultDateTypeAdapter(DateFormat.MEDIUM));
+      assertFormatted("January 1, 1970", new DefaultDateTypeAdapter(DateFormat.LONG));
+      assertFormatted("1/1/70 12:00 AM",
+          new DefaultDateTypeAdapter(DateFormat.SHORT, DateFormat.SHORT));
+      assertFormatted("Jan 1, 1970 12:00:00 AM",
+          new DefaultDateTypeAdapter(DateFormat.MEDIUM, DateFormat.MEDIUM));
+      assertFormatted("January 1, 1970 12:00:00 AM UTC",
+          new DefaultDateTypeAdapter(DateFormat.LONG, DateFormat.LONG));
+      assertFormatted("Thursday, January 1, 1970 12:00:00 AM UTC",
+          new DefaultDateTypeAdapter(DateFormat.FULL, DateFormat.FULL));
+    } finally {
+      TimeZone.setDefault(defaultTimeZone);
+      Locale.setDefault(defaultLocale);
+    }
+  }
+
+  public void testParsingDatesFormattedWithSystemLocale() {
+    TimeZone defaultTimeZone = TimeZone.getDefault();
+    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+    Locale defaultLocale = Locale.getDefault();
+    Locale.setDefault(Locale.FRANCE);
+    try {
+      assertParsed("1 janv. 1970 00:00:00", new DefaultDateTypeAdapter());
+      assertParsed("01/01/70", new DefaultDateTypeAdapter(DateFormat.SHORT));
+      assertParsed("1 janv. 1970", new DefaultDateTypeAdapter(DateFormat.MEDIUM));
+      assertParsed("1 janvier 1970", new DefaultDateTypeAdapter(DateFormat.LONG));
+      assertParsed("01/01/70 00:00",
+          new DefaultDateTypeAdapter(DateFormat.SHORT, DateFormat.SHORT));
+      assertParsed("1 janv. 1970 00:00:00",
+          new DefaultDateTypeAdapter(DateFormat.MEDIUM, DateFormat.MEDIUM));
+      assertParsed("1 janvier 1970 00:00:00 UTC",
+          new DefaultDateTypeAdapter(DateFormat.LONG, DateFormat.LONG));
+      assertParsed("jeudi 1 janvier 1970 00 h 00 UTC",
+          new DefaultDateTypeAdapter(DateFormat.FULL, DateFormat.FULL));
+    } finally {
+      TimeZone.setDefault(defaultTimeZone);
+      Locale.setDefault(defaultLocale);
+    }
+  }
+
+  public void testParsingDatesFormattedWithUsLocale() {
+    TimeZone defaultTimeZone = TimeZone.getDefault();
+    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+    Locale defaultLocale = Locale.getDefault();
+    Locale.setDefault(Locale.US);
+    try {
+      assertParsed("Jan 1, 1970 0:00:00 AM", new DefaultDateTypeAdapter());
+      assertParsed("1/1/70", new DefaultDateTypeAdapter(DateFormat.SHORT));
+      assertParsed("Jan 1, 1970", new DefaultDateTypeAdapter(DateFormat.MEDIUM));
+      assertParsed("January 1, 1970", new DefaultDateTypeAdapter(DateFormat.LONG));
+      assertParsed("1/1/70 0:00 AM",
+          new DefaultDateTypeAdapter(DateFormat.SHORT, DateFormat.SHORT));
+      assertParsed("Jan 1, 1970 0:00:00 AM",
+          new DefaultDateTypeAdapter(DateFormat.MEDIUM, DateFormat.MEDIUM));
+      assertParsed("January 1, 1970 0:00:00 AM UTC",
+          new DefaultDateTypeAdapter(DateFormat.LONG, DateFormat.LONG));
+      assertParsed("Thursday, January 1, 1970 0:00:00 AM UTC",
+          new DefaultDateTypeAdapter(DateFormat.FULL, DateFormat.FULL));
+    } finally {
+      TimeZone.setDefault(defaultTimeZone);
+      Locale.setDefault(defaultLocale);
+    }
+  }
+
+  public void testFormatUsesDefaultTimezone() {
+    TimeZone defaultTimeZone = TimeZone.getDefault();
+    TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
+    Locale defaultLocale = Locale.getDefault();
+    Locale.setDefault(Locale.US);
+    try {
+      assertFormatted("Dec 31, 1969 4:00:00 PM", new DefaultDateTypeAdapter());
+      assertParsed("Dec 31, 1969 4:00:00 PM", new DefaultDateTypeAdapter());
+    } finally {
+      TimeZone.setDefault(defaultTimeZone);
+      Locale.setDefault(defaultLocale);
+    }
+  }
+
   public void testDateSerialization() throws Exception {
     int dateStyle = DateFormat.LONG;
     DefaultDateTypeAdapter dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle);
@@ -57,4 +151,14 @@
       fail("Invalid date pattern should fail.");
     } catch (IllegalArgumentException expected) { }
   }
+
+  private void assertFormatted(String formatted, DefaultDateTypeAdapter adapter) {
+    assertEquals(formatted, adapter.serialize(new Date(0), Date.class, null).getAsString());
+  }
+
+  private void assertParsed(String date, DefaultDateTypeAdapter  adapter) {
+    assertEquals(date, new Date(0), adapter.deserialize(new JsonPrimitive(date), Date.class, null));
+    assertEquals("ISO 8601", new Date(0), adapter.deserialize(
+        new JsonPrimitive("1970-01-01T00:00:00Z"), Date.class, null));
+  }
 }