gnucash maint: Australian (GMT-10) OFX transactions imported have previous days date

John Ralls jralls at code.gnucash.org
Sun Sep 11 18:00:36 EDT 2016


Updated	 via  https://github.com/Gnucash/gnucash/commit/876f57ef (commit)
	from  https://github.com/Gnucash/gnucash/commit/52c682bd (commit)



commit 876f57ef4f00f990f46f3ab804626fbb697eedbe
Author: John Ralls <jralls at ceridwen.us>
Date:   Sun Sep 11 14:48:24 2016 -0700

    Australian (GMT-10) OFX transactions imported have previous days date
    
    The fundamental problem is https://sourceforge.net/p/libofx/bugs/39.
    Work around it by detecting it at configure time and if present check
    to see if the time in question is not daylight time. If that's the case,
    determine the daylight time offset and add it back to the timestamp.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ee7175b..d33ba76 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -291,6 +291,31 @@ ENDIF (WITH_AQBANKING)
 
 IF (WITH_OFX)
   GNC_PKG_CHECK_MODULES (LIBOFX REQUIRED libofx)
+  INCLUDE(CheckCXXSourceRuns)
+  SET(CMAKE_REQUIRED_LIBRARIES "-lofx")
+  CHECK_CXX_SOURCE_RUNS("
+#include <time.h>
+#include <stdlib.h>
+#include <string>
+extern time_t ofxdate_to_time_t(const std::string ofxdate);
+
+int main(int argc, char** argv)
+{
+    const std::string timestr = \"20160319000000\";
+    struct tm ts;
+    ts.tm_year = 116;
+    ts.tm_mon = 2;
+    ts.tm_mday = 19;
+
+    setenv(\"TZ\", \"PST 08 PDT 07 M 4.1.0, M 10.6.0\", 1);
+    time_t t = ofxdate_to_time_t(timestr);
+    if (t == mktime(&ts))
+        exit(1);
+    exit(0);
+}
+" HAVE_OFX_BUG_39)
+  SET(HAVE_OFX_BUG_39 ${HAVE_OFX_BUG_39})
+  SET(CMAKE_REQUIRED_LIBRARIES)
 ENDIF(WITH_OFX)
 # ############################################################
 
diff --git a/configure.ac b/configure.ac
index 3f798f6..b12853c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -792,6 +792,41 @@ if test x${have_ofx} = xyes ; then
   MIGRATABLE_PREFS_OFX="$srcdir/src/import-export/ofx/migratable-prefs-ofx.xml"
 fi
 
+ofx_has_bug_39=no
+if test x${have_ofx} = xyes ; then
+  AC_MSG_CHECKING([Does libofx have bug 39])
+  libs_old="$LIBS"
+  LIBS="$LIBS -lofx"
+  AC_LANG_PUSH(C++)
+  AC_RUN_IFELSE(
+    [AC_LANG_PROGRAM([
+#include <time.h>
+#include <stdlib.h>
+#include <string>
+extern time_t ofxdate_to_time_t(const std::string ofxdate);
+],[
+const std::string timestr = "20160319000000";
+struct tm ts;
+ts.tm_year = 116;
+ts.tm_mon = 2;
+ts.tm_mday = 19;
+
+setenv("TZ", "PST 08 PDT 07 M 4.1.0, M 10.6.0", 1);
+time_t t = ofxdate_to_time_t(timestr);
+if (t == mktime(&ts))
+  exit(0);
+exit(1);
+])],
+    [AC_MSG_RESULT(no)], [
+    AC_MSG_RESULT(yes)
+    ofx_has_bug_39=yes
+    ])
+  if test x$ofx_has_bug_39 = "xyes"; then
+    AC_DEFINE(HAVE_OFX_BUG_39, 1, [Libofx has a daylight-time handling bug.])
+  fi
+  AC_LANG_POP([C++])
+  LIBS="$libs_old"
+fi
 AM_CONDITIONAL([WITH_OFX], [test "x${have_ofx}" = xyes])
 AC_SUBST_FILE([MIGRATABLE_PREFS_OFX])
 ### --------------------------------------------------------------------------
diff --git a/src/config.h.cmake.in b/src/config.h.cmake.in
index cd9b250..2c85bc4 100644
--- a/src/config.h.cmake.in
+++ b/src/config.h.cmake.in
@@ -327,6 +327,10 @@
    your system. */
 #cmakedefine PTHREAD_CREATE_JOINABLE 1
 
+/* Result of LibOFX Bug 39 detection (see
+  https://sourceforge.net/p/libofx/bugs/39/ for details). */
+#cmakedefine HAVE_OFX_BUG_39 1
+
 /* Name of package containing qt3-wizard. */
 #define QT3_WIZARD_PACKAGE "aqbanking"
 
diff --git a/src/import-export/ofx/gnc-ofx-import.c b/src/import-export/ofx/gnc-ofx-import.c
index 98b5491..4f84cb2 100644
--- a/src/import-export/ofx/gnc-ofx-import.c
+++ b/src/import-export/ofx/gnc-ofx-import.c
@@ -325,7 +325,28 @@ static Account *gnc_ofx_new_account(const char* name,
     g_list_free(valid_types);
     return result;
 }
-
+/* LibOFX has a daylight time handling bug,
+ * https://sourceforge.net/p/libofx/bugs/39/, which causes it to adjust the
+ * timestamp for daylight time even when daylight time is not in
+ * effect. HAvE_OFX_BUG_39 reflects the result of checking for this bug during
+ * configuration, and fix_ofx_bug_39() corrects for it.
+ */
+static time64
+fix_ofx_bug_39 (time64 t)
+{
+#if HAVE_OFX_BUG_39
+    struct tm stm;
+    gnc_localtime_r(&t, &stm);
+    if (!stm.tm_isdst)
+    {
+        time64 new_t;
+        stm.tm_isdst = 1;
+        new_t = gnc_mktime(&stm);
+    t += t - new_t;
+    }
+#endif
+    return t;
+}
 
 int ofx_proc_transaction_cb(struct OfxTransactionData data, void * transaction_user_data)
 {
@@ -386,11 +407,13 @@ int ofx_proc_transaction_cb(struct OfxTransactionData data, void * transaction_u
     if (data.date_posted_valid && (data.date_posted != 0))
     {
         /* The hopeful case: We have a posted_date */
+        data.date_posted = fix_ofx_bug_39 (data.date_posted);
         xaccTransSetDatePostedSecsNormalized(transaction, data.date_posted);
     }
     else if (data.date_initiated_valid && (data.date_initiated != 0))
     {
         /* No posted date? Maybe we have an initiated_date */
+        data.date_initiated = fix_ofx_bug_39 (data.date_initiated);
         xaccTransSetDatePostedSecsNormalized(transaction, data.date_initiated);
     }
     else



Summary of changes:
 CMakeLists.txt                         | 25 ++++++++++++++++++++++++
 configure.ac                           | 35 ++++++++++++++++++++++++++++++++++
 src/config.h.cmake.in                  |  4 ++++
 src/import-export/ofx/gnc-ofx-import.c | 25 +++++++++++++++++++++++-
 4 files changed, 88 insertions(+), 1 deletion(-)



More information about the gnucash-changes mailing list