Index: src/backend/file/sixtp-dom-parsers.c
===================================================================
--- src/backend/file/sixtp-dom-parsers.c	(revision 17471)
+++ src/backend/file/sixtp-dom-parsers.c	(working copy)
@@ -611,6 +611,90 @@
   return ret;
 }
 
+Timespec
+dom_tree_to_date_as_timespec(xmlNodePtr node)
+{
+  /* Turn something like this
+     
+     <date-posted>
+       <s>Mon, 05 Jun 2000 23:16:19 -0500</s>
+       <ns>658864000</ns>
+     </date-posted>
+     
+     into a Timespec.  If this returns FALSE, the effects on *ts are
+     undefined.  The XML is valid if it has at least one of <s> or <ns>
+     and no more than one of each.  Order is irrelevant. */
+
+  Timespec ret;
+  gboolean seen_s = FALSE;
+  gboolean seen_ns = FALSE;
+  xmlNodePtr n;
+
+  
+  ret.tv_sec = 0;
+  ret.tv_nsec = 0;
+  for(n = node->xmlChildrenNode; n; n = n->next) {
+    switch(n->type) {
+    case XML_COMMENT_NODE:
+    case XML_TEXT_NODE:
+      break;
+    case XML_ELEMENT_NODE:
+      if(safe_strcmp("ts:date", (char*)n->name) == 0) {
+        if(seen_s)
+        {
+            return timespec_failure(ret);
+        }
+        else
+        {
+          gchar *content = dom_tree_to_text(n);
+          if(!content)
+          {
+              return timespec_failure(ret);
+          }
+          
+          if(!string_to_date_as_timespec(content, &ret)) {
+              g_free(content);
+              return timespec_failure(ret);
+          }
+          g_free(content);
+          seen_s = TRUE;
+        }
+      }
+      else if(safe_strcmp("ts:ns", (char*)n->name) == 0) {
+        if(seen_ns)
+        {
+            return timespec_failure(ret);
+        }
+        else
+        {
+          gchar *content = dom_tree_to_text(n);
+          if(!content)
+          {
+              return timespec_failure(ret);
+          }
+          
+          /* Content is good, but we'll ignore it. */
+          g_free(content);
+          seen_ns = TRUE;
+        }
+      }
+      break;
+    default:
+      PERR("unexpected sub-node.");
+      return timespec_failure(ret);
+      break;
+    }
+  }
+
+  if(!seen_s)
+  {
+      PERR("no ts:date node found.");
+      return timespec_failure(ret);
+  }
+  
+  return ret;
+}
+
 GDate*
 dom_tree_to_gdate(xmlNodePtr node)
 {
Index: src/backend/file/sixtp-utils.c
===================================================================
--- src/backend/file/sixtp-utils.c	(revision 17471)
+++ src/backend/file/sixtp-utils.c	(working copy)
@@ -430,9 +430,11 @@
    all goes well, returns the Timespec* as the result.
 */
 
-gboolean
-string_to_timespec_secs(const gchar *str, Timespec *ts) {
-
+static gboolean
+string_to_timespec_secs_internal(const gchar *str,
+                                 Timespec *ts,
+                                 gboolean date_only)
+{
   struct tm parsed_time;
   const gchar *strpos;
   time_t parsed_secs;
@@ -457,6 +459,7 @@
     int m2;
     int num_read;
 
+    /* Read the time zone. */
     /* must use "<" here because %n's effects aren't well defined */
     if(sscanf(strpos, " %c%1d%1d%1d%1d%n",
               &sign,
@@ -476,8 +479,69 @@
     if(sign == '-') gmtoff = - gmtoff;
 
     parsed_time.tm_isdst = -1;
+
+    if (date_only &&
+        (parsed_time.tm_hour != 0 ||
+         parsed_time.tm_min  != 0 ||
+         parsed_time.tm_sec  != 0))
+    {
+      /* The time isn't midnight, so the date has become time-shifted
+       * due to bug #137017. We'll have figure out the correct date. */
+      struct tm *utctm;
+      long int todsec = parsed_time.tm_hour * 60 * 60 +
+                        parsed_time.tm_min * 60;
+
+      if (gmtoff - todsec < -11 * 60 * 60)
+      {
+        /* To have moved east, the original time zone would have to be
+         * more than 11 hours west of UTC. Since there are no countries
+         * on such a time zone, we must have moved west. Therefore, the
+         * date is wrong and we need to add a day. */
+        parsed_secs = gnc_timegm(&parsed_time);
+        if(parsed_secs == (time_t) -1) return(FALSE);
+
+        /* Add a calendar day by adding hours. We need to definitely
+         * reach the next day, so in case of daylight savings effects
+         * we'll add more than enough time. */
+        if (parsed_time.tm_hour < 12)
+          /* Add 30 hours. */
+          parsed_secs += 30 * 60 * 60;
+        else
+          /* Add 20 hours. */
+          parsed_secs += 20 * 60 * 60;
+
+        utctm = gmtime(&parsed_secs);
+        if (!utctm) return (FALSE);
+        parsed_time = *utctm;
+      }
+    }
   }
 
+  if (date_only)
+  {
+    time_t secs = time(NULL);
+    struct tm *adjusted_time = localtime(&secs);
+
+    /* The date will be converted to midnight local time. */
+    adjusted_time->tm_year = parsed_time.tm_year;
+    adjusted_time->tm_mon  = parsed_time.tm_mon;
+    adjusted_time->tm_mday = parsed_time.tm_mday;
+    adjusted_time->tm_hour = 0;
+    adjusted_time->tm_min  = 0;
+    adjusted_time->tm_sec  = 0;
+    secs = mktime(adjusted_time);
+    if (secs == (time_t) -1) return(FALSE);
+    ts->tv_sec = secs;
+
+    if (parsed_time.tm_hour != 0 ||
+        parsed_time.tm_min  != 0 ||
+        parsed_time.tm_sec  != 0)
+    g_warning("Timestamp %s adjusted to %s",
+              str, ctime((time_t *) &ts->tv_sec));
+
+    return(TRUE);
+  }
+
   parsed_secs = gnc_timegm(&parsed_time);
 
   if(parsed_secs == (time_t) -1) return(FALSE);
@@ -490,6 +554,12 @@
 }
 
 gboolean
+string_to_timespec_secs(const gchar *str, Timespec *ts)
+{
+  return string_to_timespec_secs_internal(str, ts, FALSE);
+}
+
+gboolean
 string_to_timespec_nsecs(const gchar *str, Timespec *ts)
 {
   long int nanosecs;
@@ -513,6 +583,12 @@
 }
 
 gboolean
+string_to_date_as_timespec(const gchar *str, Timespec *ts)
+{
+  return string_to_timespec_secs_internal(str, ts, TRUE);
+}
+
+gboolean
 timespec_secs_to_given_string (const Timespec *ts, gchar *str)
 {
   struct tm parsed_time;
Index: src/backend/file/sixtp-dom-parsers.h
===================================================================
--- src/backend/file/sixtp-dom-parsers.h	(revision 17471)
+++ src/backend/file/sixtp-dom-parsers.h	(working copy)
@@ -41,6 +41,7 @@
 Recurrence* dom_tree_to_recurrence(xmlNodePtr node);
 
 Timespec dom_tree_to_timespec(xmlNodePtr node);
+Timespec dom_tree_to_date_as_timespec(xmlNodePtr node);
 gboolean dom_tree_valid_timespec(Timespec *ts, const gchar *name);
 GDate* dom_tree_to_gdate(xmlNodePtr node);
 gnc_numeric* dom_tree_to_gnc_numeric(xmlNodePtr node);
Index: src/backend/file/sixtp-utils.h
===================================================================
--- src/backend/file/sixtp-utils.h	(revision 17471)
+++ src/backend/file/sixtp-utils.h	(working copy)
@@ -85,6 +85,7 @@
 
 gboolean string_to_timespec_secs(const gchar *str, Timespec *ts);
 gboolean string_to_timespec_nsecs(const gchar *str, Timespec *ts);
+gboolean string_to_date_as_timespec(const gchar *str, Timespec *ts);
 
 /* str must have length of at least TIMESPEC_SEC_FORMAT_MAX */
 gboolean timespec_secs_to_given_string (const Timespec *ts, gchar *str);
Index: src/backend/file/gnc-transaction-xml-v2.c
===================================================================
--- src/backend/file/gnc-transaction-xml-v2.c	(revision 17471)
+++ src/backend/file/gnc-transaction-xml-v2.c	(working copy)
@@ -430,8 +430,8 @@
 }
 
 static inline gboolean
-set_tran_date(xmlNodePtr node, Transaction *trn,
-              void (*func)(Transaction *trn, const Timespec *tm))
+set_tran_timespec(xmlNodePtr node, Transaction *trn,
+                  void (*func)(Transaction *trn, const Timespec *tm))
 {
     Timespec tm;
 
@@ -444,6 +444,21 @@
     return TRUE;
 }
 
+static inline gboolean
+set_tran_date_as_timespec(xmlNodePtr node, Transaction *trn,
+                          void (*func)(Transaction *trn, const Timespec *tm))
+{
+    Timespec tm;
+
+    tm = dom_tree_to_date_as_timespec(node);
+
+    if (!dom_tree_valid_timespec(&tm, node->name)) return FALSE;
+    
+    func(trn, &tm);
+
+    return TRUE;
+}
+
 static gboolean
 trn_id_handler(xmlNodePtr node, gpointer trans_pdata)
 {
@@ -488,7 +503,7 @@
     struct trans_pdata *pdata = trans_pdata;
     Transaction *trn = pdata->trans;
 
-    return set_tran_date(node, trn, xaccTransSetDatePostedTS);
+    return set_tran_date_as_timespec(node, trn, xaccTransSetDatePostedTS);
 }
 
 static gboolean
@@ -497,7 +512,7 @@
     struct trans_pdata *pdata = trans_pdata;
     Transaction *trn = pdata->trans;
 
-    return set_tran_date(node, trn, xaccTransSetDateEnteredTS);
+    return set_tran_timespec(node, trn, xaccTransSetDateEnteredTS);
 }
 
 static gboolean
