Exemple #1
0
void
gnc_date_cell_set_value_secs (DateCell *cell, time64 secs)
{
    PopBox *box = cell->cell.gui_private;
    char buff[DATE_BUF];

    gnc_localtime_r (&secs, &(box->date));

    qof_print_date_dmy_buff (buff, MAX_DATE_LENGTH,
                             box->date.tm_mday,
                             box->date.tm_mon + 1,
                             box->date.tm_year + 1900);

    gnc_basic_cell_set_value_internal (&cell->cell, buff);

    if (!box->date_picker)
        return;

    block_picker_signals (cell);
    gnc_date_picker_set_date (box->date_picker,
                              box->date.tm_mday,
                              box->date.tm_mon,
                              box->date.tm_year + 1900);
    unblock_picker_signals (cell);
}
Exemple #2
0
size_t
gnc_print_date_time_buff (char * buff, size_t len, time64 t)
/* at the same time than gnc_parse_time_date is based on a call on GncDateTime and all calls on TZenv = g_strdup(g_getenv("TZ")) are destroyed, replace definition of gnc_print_date_time_buff by
 *  if (!buff) return 0;

    GncDateTime gncdt(t);
    std::string str = gncdt.format_time("%Z %H:%M:%S " + qof_date_format_get_string(dateFormat));
    strncpy(buff, str.c_str(), len);
    if (str.length() >= len)
buff[len - 1] = '\0'; */
{
/* replace this call by GncDateTime gncdt(t) when all TZenv code will disappear*/
    struct tm theTime;
    size_t timelength;
    time64 bt;
    
    bt = t;
    if (!gnc_localtime_r(&bt, &theTime)) /* theTime is *local* time */
        return 0;
    
    timelength = g_snprintf (buff, len, "%c%02d%02d %02d:%02d:%02d ", theTime.tm_gmtoff < 0 ? '-' : '+', abs(theTime.tm_gmtoff) / 60 / 60, (abs(theTime.tm_gmtoff) / 60) % 60, theTime.tm_hour, theTime.tm_min, theTime.tm_sec);// the left part of the string is the one hidden whenever the column is too small.

    timelength += qof_print_date_buff (buff+timelength, len-timelength, t);// TODO mettre timelength au lieu de 9 !
    return strlen(buff);
}
Exemple #3
0
static void
gnc_tm_get_day_end (struct tm *tm, time64 time_val)
{
    /* Get the equivalent time structure */
    if (!gnc_localtime_r(&time_val, tm))
        return;
    gnc_tm_set_day_end(tm);
}
Exemple #4
0
time64
time64CanonicalDayTime (time64 t)
{
    struct tm tm;
    gnc_localtime_r(&t, &tm);
    gnc_tm_set_day_middle(&tm);
    return gnc_mktime (&tm);
}
Exemple #5
0
void
gnc_gdate_set_time64 (GDate* gd, time64 time)
{
    struct tm tm;
    gnc_localtime_r(&time, &tm);
    g_date_set_dmy (gd, tm.tm_mday,
                    static_cast<GDateMonth>(tm.tm_mon + 1),
                    tm.tm_year + 1900);
}
Exemple #6
0
struct tm*
gnc_localtime (const time64 *secs)
{
     struct tm *time = g_slice_alloc0 (sizeof (struct tm));
     if (gnc_localtime_r (secs, time) == NULL)
     {
	  gnc_tm_free (time);
	  return NULL;
     }
     return time;
}
Exemple #7
0
void
gnc_timespec2dmy (Timespec t, int *day, int *month, int *year)
{
    struct tm result;
    time64 t_secs = t.tv_sec + (t.tv_nsec / NANOS_PER_SECOND);
    gnc_localtime_r(&t_secs, &result);

    if (day) *day = result.tm_mday;
    if (month) *month = result.tm_mon + 1;
    if (year) *year = result.tm_year + 1900;
}
Exemple #8
0
struct tm*
gnc_localtime (const time64 *secs)
{
    auto time = static_cast<struct tm*>(calloc(1, sizeof(struct tm)));
    if (gnc_localtime_r (secs, time) == NULL)
    {
	gnc_tm_free (time);
	return NULL;
    }
    return time;
}
Exemple #9
0
/* Converts any time on a day to midday that day.

 * given a timepair contains any time on a certain day (local time)
 * converts it to be midday that day.
 */
Timespec
timespecCanonicalDayTime(Timespec t)
{
    struct tm tm;
    Timespec retval;
    time64 t_secs = t.tv_sec + (t.tv_nsec / NANOS_PER_SECOND);
    gnc_localtime_r(&t_secs, &tm);
    gnc_tm_set_day_middle(&tm);
    retval.tv_sec = gnc_mktime(&tm);
    retval.tv_nsec = 0;
    return retval;
}
Exemple #10
0
/* Convert day, month and year values to a date string

  Convert a date as day / month / year integers into a localized string
  representation

param   buff - pointer to previously allocated character array; its size
         must be at lease MAX_DATE_LENTH bytes.
param   day - value to be set with the day of the month as 1 ... 31
param   month - value to be set with the month of the year as 1 ... 12
param   year - value to be set with the year (4-digit)

return length of string created in buff.

Globals: global dateFormat value
*/
size_t
qof_print_date_dmy_buff (char * buff, size_t len, int day, int month, int year)
{
    int flen;
    if (!buff) return 0;

    /* Note that when printing year, we use %-4d in format string;
     * this causes a one, two or three-digit year to be left-adjusted
     * when printed (i.e. padded with blanks on the right).  This is
     * important while the user is editing the year, since erasing a
     * digit can temporarily cause a three-digit year, and having the
     * blank on the left is a real pain for the user.  So pad on the
     * right.
     */
    switch (dateFormat)
    {
    case QOF_DATE_FORMAT_UK:
        flen = g_snprintf (buff, len, "%02d/%02d/%-4d", day, month, year);
        break;
    case QOF_DATE_FORMAT_CE:
        flen = g_snprintf (buff, len, "%02d.%02d.%-4d", day, month, year);
        break;
    case QOF_DATE_FORMAT_LOCALE:
    {
        struct tm tm_str;
        time64 t;

        tm_str.tm_mday = day;
        tm_str.tm_mon = month - 1;    /* tm_mon = 0 through 11 */
        tm_str.tm_year = year - 1900; /* this is what the standard
	 says, it's not a Y2K thing */

        gnc_tm_set_day_start (&tm_str);
        t = gnc_mktime (&tm_str);
        gnc_localtime_r (&t, &tm_str);
        flen = qof_strftime (buff, len, GNC_D_FMT, &tm_str);
        if (flen != 0)
            break;
    }
    /* FALL THROUGH */
    case QOF_DATE_FORMAT_ISO:
    case QOF_DATE_FORMAT_UTC:
        flen = g_snprintf (buff, len, "%04d-%02d-%02d", year, month, day);
        break;
    case QOF_DATE_FORMAT_US:
    default:
        flen = g_snprintf (buff, len, "%02d/%02d/%-4d", month, day, year);
        break;
    }

    return flen;
}
Exemple #11
0
size_t
qof_print_date_buff (char * buff, size_t len, time64 t)
{
    struct tm theTime;
    time64 bt = t;
    size_t actual;
    if (!buff) return 0 ;
    if (!gnc_localtime_r(&bt, &theTime))
	return 0;

    actual = qof_print_date_dmy_buff (buff, len,
                                    theTime.tm_mday,
                                    theTime.tm_mon + 1,
                                    theTime.tm_year + 1900);
    return actual;
}
Exemple #12
0
static void
fill_time_combo (GtkWidget *widget, GNCDateEdit *gde)
{
    GtkTreeModel *model;
    GtkTreeIter  hour_iter, min_iter;
    struct tm *tm_returned;
    struct tm mtm;
    time64 current_time;
    int i, j;

    if (gde->lower_hour > gde->upper_hour)
        return;

    model = gtk_combo_box_get_model (GTK_COMBO_BOX(gde->time_combo));

    gnc_time (&current_time);
    tm_returned = gnc_localtime_r (&current_time, &mtm);
    g_return_if_fail(tm_returned != NULL);

    for (i = gde->lower_hour; i <= gde->upper_hour; i++)
    {
        char buffer [40];
        mtm.tm_hour = i;
        mtm.tm_min  = 0;

        if (gde->flags & GNC_DATE_EDIT_24_HR)
            qof_strftime (buffer, sizeof (buffer), "%H:00", &mtm);
        else
            qof_strftime (buffer, sizeof (buffer), "%I:00 %p ", &mtm);

        gtk_tree_store_append (GTK_TREE_STORE(model), &hour_iter, NULL);
        gtk_tree_store_set (GTK_TREE_STORE(model), &hour_iter, 0, buffer, -1);

        for (j = 0; j < 60; j += 15)
        {
            mtm.tm_min = j;

            if (gde->flags & GNC_DATE_EDIT_24_HR)
                qof_strftime (buffer, sizeof (buffer), "%H:%M", &mtm);
            else
                qof_strftime (buffer, sizeof (buffer), "%I:%M %p", &mtm);

            gtk_tree_store_append(GTK_TREE_STORE(model), &min_iter, &hour_iter );
            gtk_tree_store_set (GTK_TREE_STORE(model), &min_iter, 0, buffer, -1);
        }
    }
}
Exemple #13
0
int
main(void)
{
    int y, m, d;
    time64 bin_time;
    struct tm br_time;

    gnc_time (&bin_time);
    gnc_localtime_r (&bin_time, &br_time);

    gregorian_to_jalali(&y, &m, &d,
                        1900 + br_time.tm_year,
                        1 + br_time.tm_mon,
                        br_time.tm_mday);

    printf("Current Jalali date: %d %s %d\n", d, j_month_name[m-1], y);

    return 0;
}
Exemple #14
0
/* Return the field separator for the current date format
return date character
*/
char dateSeparator (void)
{
    static char locale_separator = '\0';

    switch (dateFormat)
    {
    case QOF_DATE_FORMAT_CE:
        return '.';
    case QOF_DATE_FORMAT_ISO:
    case QOF_DATE_FORMAT_UTC:
        return '-';
    case QOF_DATE_FORMAT_US:
    case QOF_DATE_FORMAT_UK:
    default:
        return '/';
    case QOF_DATE_FORMAT_LOCALE:
        if (locale_separator != '\0')
            return locale_separator;
        else
        {
            /* Make a guess */
            gchar string[256];
            struct tm tm;
            time64 secs;
            gchar *s;

            secs = gnc_time (NULL);
            gnc_localtime_r(&secs, &tm);
            auto normalized_fmt =
                normalize_format(qof_date_format_get_string(dateFormat));
            qof_strftime(string, sizeof(string), normalized_fmt.c_str(), &tm);

            for (s = string; *s != '\0'; s++)
                if (!isdigit(*s))
                    return (locale_separator = *s);
        }
        break;
    }
    return '\0';
}
Exemple #15
0
static void
gnc_date_cell_init (DateCell *cell)
{
    PopBox *box;
    time64 secs;
    char buff[DATE_BUF];

    gnc_basic_cell_init (&(cell->cell));

    cell->cell.is_popup = TRUE;

    cell->cell.destroy = gnc_date_cell_destroy;

    cell->cell.gui_realize = gnc_date_cell_realize;
    cell->cell.gui_destroy = gnc_date_cell_gui_destroy;
    cell->cell.modify_verify = gnc_date_cell_modify_verify;
    cell->cell.direct_update = gnc_date_cell_direct_update;
    cell->cell.set_value = gnc_date_cell_set_value_internal;

    box = g_new0 (PopBox, 1);

    box->sheet = NULL;
    box->item_edit = NULL;
    box->date_picker = NULL;

    box->signals_connected = FALSE;
    box->calendar_popped = FALSE;
    box->in_date_select = FALSE;

    cell->cell.gui_private = box;

    /* default value is today's date */
    gnc_time (&secs);
    gnc_localtime_r (&secs, &(box->date));
    gnc_date_cell_print_date (cell, buff);

    gnc_basic_cell_set_value_internal (&cell->cell, buff);
}
static char * get_date_help (VirtualLocation virt_loc, gpointer user_data)
{
    GncEntryLedger *ledger = user_data;
    BasicCell *cell;
    char string[1024];
    struct tm tm;
    Timespec ts;
    time64 tt;

    cell = gnc_table_get_cell (ledger->table, virt_loc);
    if (!cell)
        return NULL;

    if (!cell->value || *cell->value == '\0')
        return NULL;

    gnc_date_cell_get_date ((DateCell *) cell, &ts);
    tt = ts.tv_sec;
    gnc_localtime_r (&tt, &tm);
    qof_strftime (string, sizeof(string), "%A %d %B %Y", &tm);

    return g_strdup (string);
}
Exemple #17
0
/* Based on the post date and a proximo type, compute the month and
 * year this is due.  The actual day is filled in below.
 *
 * A proximo billing term has multiple parameters:
 * * due day: day of the month the invoice/bill will be due
 * * cutoff: day of the month used to decide if the due date will be
 *           in the next month or in the month thereafter. This can be
 *           a negative number in which case the cutoff date is relative
 *           to the end of the month and counting backwards.
 *           Eg: cutoff = -3 would mean 25 in February or 28 in June
 *
 * How does it work:
 * Assume cutoff = 19 and due day = 20
 *
 * * Example 1 post date = 14-06-2010 (European date format)
 *   14 is less than the cutoff of 19, so the due date will be in the next
 *   month. Since the due day is set to 20, the due date will be
 *   20-07-2010
 *
 * * Example 2 post date = 22-06-2010 (European date format)
 *   22 is more than the cutoff of 19, so the due date will be in the month
 *   after next month. Since the due day is set to 20, the due date will be
 *   20-02-2010
 *
 */
static void
compute_monthyear (const GncBillTerm *term, time64 post_date,
                   int *month, int *year)
{
    int iday, imonth, iyear;
    struct tm tm;
    int cutoff = term->cutoff;

    g_return_if_fail (term->type == GNC_TERM_TYPE_PROXIMO);
    gnc_localtime_r (&post_date, &tm);
    iday = tm.tm_mday;
    imonth = tm.tm_mon + 1;
    iyear = tm.tm_year + 1900;

    if (cutoff <= 0)
        cutoff += gnc_date_get_last_mday (imonth - 1, iyear);

    if (iday <= cutoff)
    {
        /* We apply this to next month */
        imonth++;
    }
    else
    {
        /* We apply to the following month */
        imonth += 2;
    }

    if (imonth > 12)
    {
        iyear++;
        imonth -= 12;
    }

    if (month) *month = imonth;
    if (year) *year = iyear;
}
Exemple #18
0
void
gnc_date_format_refresh (GNCDateFormat *gdf)
{
    GNCDateFormatPriv *priv;
    int sel_option;
    gboolean enable_year, enable_month, enable_custom, check_modifiers;
    static gchar *format, *c;
    gchar date_string[MAX_DATE_LEN];
    time64 secs_now;
    struct tm today;

    g_return_if_fail(gdf);
    g_return_if_fail(GNC_IS_DATE_FORMAT(gdf));

    priv = GNC_DATE_FORMAT_GET_PRIVATE(gdf);
    sel_option =
        gtk_combo_box_get_active(GTK_COMBO_BOX(priv->format_combobox));

    switch (sel_option)
    {
    case QOF_DATE_FORMAT_CUSTOM:
        format = g_strdup(gtk_entry_get_text(GTK_ENTRY(priv->custom_entry)));
        enable_year = enable_month = check_modifiers = FALSE;
        enable_custom = TRUE;
        break;

    case QOF_DATE_FORMAT_LOCALE:
    case QOF_DATE_FORMAT_UTC:
        format = g_strdup(qof_date_format_get_string(sel_option));
        enable_year = enable_month = check_modifiers = enable_custom = FALSE;
        break;

    case QOF_DATE_FORMAT_ISO:
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->months_number), TRUE);
        enable_year = check_modifiers = TRUE;
        enable_month = enable_custom = FALSE;
        break;

    default:
        enable_year = enable_month = check_modifiers = TRUE;
        enable_custom = FALSE;
        break;
    }

    /* Tweak widget sensitivities, as appropriate. */
    gnc_date_format_enable_year(gdf, enable_year);
    gnc_date_format_enable_month(gdf, enable_month);
    gnc_date_format_enable_format(gdf, enable_custom);

    /* Update the format string based upon the user's preferences */
    if (check_modifiers)
    {
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->months_number)))
        {
            format = g_strdup(qof_date_format_get_string(sel_option));
        }
        else
        {
            format = g_strdup(qof_date_text_format_get_string(sel_option));
            if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->months_name)))
            {
                c = strchr(format, 'b');
                if (c)
                    *c = 'B';
            }
        }
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->years_button)))
        {
            c = strchr(format, 'y');
            if (c)
                *c = 'Y';
        }
    }

    /*
     * Give feedback on the format string so users can see how it works
     * without having to read the strftime man page. Prevent recursive
     * signals.
     */
    g_signal_handlers_block_matched(priv->custom_entry, G_SIGNAL_MATCH_DATA,
                                    0, 0, NULL, NULL, gdf);
    gtk_entry_set_text(GTK_ENTRY(priv->custom_entry), format);
    g_signal_handlers_unblock_matched(priv->custom_entry, G_SIGNAL_MATCH_DATA,
                                      0, 0, NULL, NULL, gdf);

    /* Visual feedback on what the date will look like. */
    secs_now = gnc_time (NULL);
    gnc_localtime_r (&secs_now, &today);
    qof_strftime(date_string, MAX_DATE_LEN, format, &today);
    gtk_label_set_text(GTK_LABEL(priv->sample_label), date_string);
    g_free(format);
}
Exemple #19
0
/** Parses a string into a date, given a format. The format must
 * include the year. This function should only be called by
 * parse_date.
 * @param date_str The string containing a date being parsed
 * @param format An index specifying a format in date_format_user
 * @return The parsed value of date_str on success or -1 on failure
 */
static time64 parse_date_with_year (const char* date_str, int format)
{
    time64 rawtime; /* The integer time */
    struct tm retvalue, test_retvalue; /* The time in a broken-down structure */

    int i, j, mem_length, orig_year = -1, orig_month = -1, orig_day = -1;

    /* Buffer for containing individual parts (e.g. year, month, day) of a date */
    char date_segment[5];

    /* The compiled regular expression */
    regex_t preg = {0};

    /* An array containing indices specifying the matched substrings in date_str */
    regmatch_t pmatch[4] = { {0}, {0}, {0}, {0} };

    /* The regular expression for parsing dates */
    const char* regex = "^ *([0-9]+) *[-/.'] *([0-9]+) *[-/.'] *([0-9]+).*$|^ *([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]).*$";

    /* We get our matches using the regular expression. */
    regcomp (&preg, regex, REG_EXTENDED);
    regexec (&preg, date_str, 4, pmatch, 0);
    regfree (&preg);

    /* If there wasn't a match, there was an error. */
    if (pmatch[0].rm_eo == 0)
        return -1;

    /* If this is a string without separators ... */
    if (pmatch[1].rm_so == -1)
    {
        /* ... we will fill in the indices based on the user's selection. */
        int k = 0; /* k traverses date_str by keeping track of where separators "should" be. */
        j = 1; /* j traverses pmatch. */
        for (i = 0; date_format_user[format][i]; i++)
        {
            char segment_type = date_format_user[format][i];
            /* Only do something if this is a meaningful character */
            if (segment_type == 'y' || segment_type == 'm' || segment_type == 'd')
            {
                pmatch[j].rm_so = k;
                switch (segment_type)
                {
                case 'm':
                case 'd':
                    k += 2;
                    break;

                case 'y':
                    k += 4;
                    break;
                }

                pmatch[j].rm_eo = k;
                j++;
            }
        }
    }

    /* Put some sane values in retvalue by using the current time for
     * the non-year-month-day parts of the date. */
    gnc_time (&rawtime);
    gnc_localtime_r (&rawtime, &retvalue);

    /* j traverses pmatch (index 0 contains the entire string, so we
     * start at index 1 for the first meaningful match). */
    j = 1;
    /* Go through the date format and interpret the matches in order of
     * the sections in the date format. */
    for (i = 0; date_format_user[format][i]; i++)
    {
        char segment_type = date_format_user[format][i];
        /* Only do something if this is a meaningful character */
        if (segment_type == 'y' || segment_type == 'm' || segment_type == 'd')
        {
            /* Copy the matching substring into date_segment so that we can
             * convert it into an integer. */
            mem_length = pmatch[j].rm_eo - pmatch[j].rm_so;
            memcpy (date_segment, date_str + pmatch[j].rm_so, mem_length);
            date_segment[mem_length] = '\0';

            /* Set the appropriate member of retvalue. Save the original
             * values so that we can check if the change when we use gnc_mktime
             * below. */
            switch (segment_type)
            {
            case 'y':
                retvalue.tm_year = atoi (date_segment);

                /* Handle two-digit years. */
                if (retvalue.tm_year < 100)
                {
                    /* We allow two-digit years in the range 1969 - 2068. */
                    if (retvalue.tm_year < 69)
                        retvalue.tm_year += 100;
                }
                else
                    retvalue.tm_year -= 1900;
                orig_year = retvalue.tm_year;
                break;

            case 'm':
                orig_month = retvalue.tm_mon = atoi (date_segment) - 1;
                break;

            case 'd':
                orig_day = retvalue.tm_mday = atoi (date_segment);
                break;
            }
            j++;
        }
    }
    /* Convert back to an integer. If gnc_mktime leaves retvalue unchanged,
     * everything is okay; otherwise, an error has occurred. */
    /* We have to use a "test" date value to account for changes in
     * daylight savings time, which can cause a date change with gnc_mktime
     * near midnight, causing the code to incorrectly think a date is
     * incorrect. */
    test_retvalue = retvalue;
    gnc_mktime (&test_retvalue);
    retvalue.tm_isdst = test_retvalue.tm_isdst;
    rawtime = gnc_mktime (&retvalue);
    if (retvalue.tm_mday == orig_day &&
            retvalue.tm_mon == orig_month &&
            retvalue.tm_year == orig_year)
    {
        return rawtime;
    }
    else
    {
        return -1;
    }
}
Exemple #20
0
/*   gnc_parse_time_date parsing tm (+0000) (from %+05d %d:%d:%d then the date) in datestr

 I hope that github will show differences between my new function gnc_parse_time_date and function qof_scan_date_internal found below, existing in HEAD (as of 25/1/2016) of the branch master of gnucash. Thanks to spaces added to qof_scan_date_internal.

**********************************************************
KNOWN BUG: gnucash crashes if a date string starts by ":" and longer thant ":".
**********************************************************
*/
void
gnc_parse_time_date (struct tm *parsed, const char * buff)
/* gnc_parse_time_date should call GncDateTime gncdt(std::string) when gnc_print_date_time_buff will be using GncDateTime and TZenv will disappear from everywhere*/
{
    char *dupe, *tmp, *TZhourtxt, *TZtxt, *hourtxt, *minutetxt, *secondtxt; /* tmp may be the unparsed part of the string. , */
    int iday, imonth, iyear;
    time64 secs;
    int tz; /* signed timezone in seconds */
    hourtxt = NULL;/* will stay NULL if TZ is not in buff */
    if (!parsed) return;
    parsed->tm_year=-1; /* means failure. */

    if (!buff) return;
    dupe = g_strdup (buff);

    tmp = dupe;
    TZhourtxt = strtok (tmp, ":");
    minutetxt = strtok (NULL, ":");
    secs = time(NULL); /* gnc_time(NULL) or time(NULL) ?? */
    gnc_localtime_r(&secs, parsed);
    tz = parsed->tm_gmtoff;
    if (TZhourtxt || minutetxt) {
        if (dupe[0] != ':' && minutetxt) {/* "hh:mm date" and "hh:mm:ss date" are parsed. "hh date" is not recognized. "hh:mm" and "hh:mm:ss" imply today. Default value for the timezone is TZenv */
            secondtxt = strtok (NULL, " ");
            tmp = strtok (NULL, "\a");/* hack: \a is the audible bell, hope this one is never used in a date format ; tmp = minutetxt + strlen (strtok (minutetxt, " "))+1 might be better */
            TZtxt = strtok (TZhourtxt, " ");
            hourtxt = strtok (NULL, " ");
            if (hourtxt) {
                tz = atoi(TZtxt);
                parsed->tm_hour = atoi(hourtxt) ;
                tz = 60 * ( (tz % 100) + 60 * (tz / 100) ) ;
                if (atoi(TZtxt) < 0) tz = - tz;
            } else {
                if (TZtxt) {
                    parsed->tm_hour = atoi(TZtxt) ;
                } else {
                    parsed->tm_hour = 0 ; /* the case "::" falls here ? */
                }
            }
            if (tmp) {
                /* +0200 02:01:03 2016-06-03
                * <+0200 02> TZhourtxt
                *          <01> minutetxt
                *             <03> secondtxt
                *                <2016-06-03> tmp
                * <+0200> TZtxt
                *       <02> hourtxt  */
                parsed->tm_min = atoi(minutetxt) ;
                parsed->tm_sec = atoi(secondtxt) ;
            } else {
                /* +0200 02:01 2016-06-03
                * <+0200 02> TZhourtxt
                *          <01 2016-06-03> minutetxt */
                parsed->tm_min = atoi ( strtok (minutetxt, " ") );
                parsed->tm_sec = 0 ;
                tmp = secondtxt ;
                /* +0200 02:01 2016-06-03
                * <+0200 02> TZhourtxt
                *             <2016-06-03> minutetxt
                *             <2016-06-03> tmp */
            }
            parsed->tm_sec = (parsed->tm_sec) - tz + (parsed->tm_gmtoff) ;
        }
    } else {
       parsed->tm_hour = k_reference_time_TZ_hour;
       /* parsed->tm_gmtoff = 0; does not work */
       parsed->tm_min = k_reference_time_TZ_min;
       parsed->tm_sec = k_reference_time_TZ_sec_of_min + parsed->tm_gmtoff;
       tmp = TZhourtxt;
    }
    if (tmp && qof_scan_date (tmp, &iday, &imonth, &iyear))
    {
        parsed->tm_mday = iday;
        parsed->tm_mon  = imonth - 1;
        parsed->tm_year = iyear - 1900;
    } /* else { Couldn't parse date, use today ; } */
    
    g_free (dupe);

}