static Timespec gnc_dmy2timespec_internal (int day, int month, int year, gboolean start_of_day) { Timespec result; struct tm date; long long secs = 0; long long era = 0; date.tm_year = year - 1900; date.tm_mon = month - 1; date.tm_mday = day; if (start_of_day) gnc_tm_set_day_start(&date); else gnc_tm_set_day_end(&date); /* compute number of seconds */ secs = gnc_mktime (&date); result.tv_sec = secs; result.tv_nsec = 0; return result; }
void gnc_date_cell_set_value (DateCell *cell, int day, int mon, int year) { PopBox *box = cell->cell.gui_private; struct tm dada; char buff[DATE_BUF]; dada.tm_mday = day; dada.tm_mon = mon - 1; dada.tm_year = year - 1900; gnc_tm_set_day_start(&dada); gnc_mktime (&dada); box->date.tm_mday = dada.tm_mday; box->date.tm_mon = dada.tm_mon; box->date.tm_year = dada.tm_year; qof_print_date_dmy_buff (buff, MAX_DATE_LENGTH, dada.tm_mday, dada.tm_mon + 1, dada.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, day, mon - 1, year); unblock_picker_signals (cell); }
static void gnc_tm_get_day_start (struct tm *tm, time64 time_val) { /* Get the equivalent time structure */ if (!gnc_localtime_r(&time_val, tm)) return; gnc_tm_set_day_start(tm); }
/* 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; }
static void gnc_parse_date (struct tm *parsed, const char * datestr) { int day, month, year; gboolean use_autoreadonly = qof_book_uses_autoreadonly(gnc_get_current_book()); if (!parsed) return; if (!datestr) return; if (!qof_scan_date (datestr, &day, &month, &year)) { // Couldn't parse date, use today struct tm tm_today; memset (&tm_today, 0, sizeof (struct tm)); gnc_tm_get_today_start (&tm_today); day = tm_today.tm_mday; month = tm_today.tm_mon + 1; year = tm_today.tm_year + 1900; } // If we have an auto-read-only threshold, do not accept a date that is // older than the threshold. if (use_autoreadonly) { GDate *d = g_date_new_dmy(day, month, year); if (check_readonly_threshold (datestr, d)) { day = g_date_get_day (d); month = g_date_get_month (d); year = g_date_get_year (d); } g_date_free (d); } parsed->tm_mday = day; parsed->tm_mon = month - 1; parsed->tm_year = year - 1900; gnc_tm_set_day_start(parsed); /* Using gnc_mktime purely for its side effect of filling in the * rest of parsed and to check that it's valid. */ if (gnc_mktime (parsed) == -1) gnc_tm_get_today_start (parsed); gnc_mktime (parsed); }
static void gnc_date_edit_popup (GNCDateEdit *gde) { GtkWidget *toplevel; struct tm mtm; gboolean date_was_valid; GdkDevice *device, *keyboard, *pointer; g_return_if_fail (GNC_IS_DATE_EDIT (gde)); ENTER("gde %p", gde); device = gtk_get_current_event_device (); /* This code is pretty much just copied from gtk_date_edit_get_date */ date_was_valid = qof_scan_date (gtk_entry_get_text (GTK_ENTRY (gde->date_entry)), &mtm.tm_mday, &mtm.tm_mon, &mtm.tm_year); if (!date_was_valid) { /* No valid date. Hacky workaround: Instead of crashing we randomly choose today's date. */ gnc_tm_get_today_start(&mtm); } mtm.tm_mon--; /* Hope the user does not actually mean years early in the A.D. days... * This date widget will obviously not work for a history program :-) */ if (mtm.tm_year >= 1900) mtm.tm_year -= 1900; gnc_tm_set_day_start(&mtm); /* Set the calendar. */ gtk_calendar_select_day (GTK_CALENDAR (gde->calendar), 1); gtk_calendar_select_month (GTK_CALENDAR (gde->calendar), mtm.tm_mon, 1900 + mtm.tm_year); gtk_calendar_select_day (GTK_CALENDAR (gde->calendar), mtm.tm_mday); /* Make sure we'll get notified of clicks outside the popup * window so we can properly pop down if that happens. */ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (gde)); if (GTK_IS_WINDOW (toplevel)) { gtk_window_group_add_window ( gtk_window_get_group (GTK_WINDOW (toplevel)), GTK_WINDOW (gde->cal_popup)); gtk_window_set_transient_for (GTK_WINDOW (gde->cal_popup), GTK_WINDOW (toplevel)); } position_popup (gde); gtk_widget_show (gde->cal_popup); gtk_widget_grab_focus (gde->cal_popup); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gde->date_button), TRUE); if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) { keyboard = device; pointer = gdk_device_get_associated_device (device); } else { pointer = device; keyboard = gdk_device_get_associated_device (device); } if (!gtk_widget_has_focus (gde->calendar)) gtk_widget_grab_focus (gde->calendar); if (!popup_grab_on_window (gtk_widget_get_window ((GTK_WIDGET(gde->cal_popup))), keyboard, pointer, GDK_CURRENT_TIME)) { gtk_widget_hide (gde->cal_popup); LEAVE("Failed to grab window"); return; } gtk_grab_add (gde->cal_popup); LEAVE(" "); }
static struct tm gnc_date_edit_get_date_internal (GNCDateEdit *gde) { struct tm tm = {0}; char *str; gchar *flags = NULL; gboolean date_was_valid; /* Assert, because we're just hosed if it's NULL */ g_assert(gde != NULL); g_assert(GNC_IS_DATE_EDIT(gde)); date_was_valid = qof_scan_date (gtk_entry_get_text (GTK_ENTRY (gde->date_entry)), &tm.tm_mday, &tm.tm_mon, &tm.tm_year); if (!date_was_valid) { /* Hm... no valid date. What should we do not? As a hacky workaround we revert to today's date. Alternatively we can return some value that signals that we don't get a valid date, but all callers of this function will have to check this. Alas, I'm too lazy to do this here. */ gnc_tm_get_today_start(&tm); } tm.tm_mon--; tm.tm_year -= 1900; if (gde->flags & GNC_DATE_EDIT_SHOW_TIME) { char *tokp = NULL; gchar *temp; str = g_strdup (gtk_entry_get_text (GTK_ENTRY (gde->time_entry))); temp = gnc_strtok_r (str, ": ", &tokp); if (temp) { tm.tm_hour = atoi (temp); temp = gnc_strtok_r (NULL, ": ", &tokp); if (temp) { if (isdigit (*temp)) { tm.tm_min = atoi (temp); flags = gnc_strtok_r (NULL, ": ", &tokp); if (flags && isdigit (*flags)) { tm.tm_sec = atoi (flags); flags = gnc_strtok_r (NULL, ": ", &tokp); } } else flags = temp; } } if (flags && (strcasecmp (flags, "PM") == 0)) { if (tm.tm_hour < 12) tm.tm_hour += 12; } g_free (str); } else { gnc_tm_set_day_start(&tm); } tm.tm_isdst = -1; return tm; }