+ d->year = begin_date.year;
+ d->month = begin_date.month;
+ d->day = begin_date.day;
+ }
+ }
+ return result;
+}
+
+/* PRE: d->cal != CAL_UNKNOWN
+ INPUT: d->day_str, d->month_str, d->year_str
+ OUTPUT: d->day, d->month, d->year, d->year_type
+*/
+int strings_to_numbers(struct date *d)
+{
+ int result = 0;
+ if (d->cal == CAL_UNKNOWN) {
+ gedcom_date_error(_("Cannot compute months for unknown calendar type"));
+ result = 1;
+ }
+ else {
+ if (d->day_str[0]) {
+ d->day = get_day_num(d->day_str);
+ if (d->day == -1) result = 1;
+ }
+ else
+ d->day = -1;
+
+ if (d->month_str[0]) {
+ d->month = get_month_num(d->cal, d->month_str);
+ if (d->month == -1) result = 1;
+ }
+ else
+ d->month = -1;
+
+ d->year = get_year_num(d->year_str, &d->year_type);
+ if (d->year == -1) result = 1;
+ }
+
+ return result;
+}
+
+/* PRE: d->cal != CAL_UNKNOWN
+ INPUT: d->day, d->month, d->year, d->year_type
+ OUTPUT: d->day_str, d->month_str, d->year_str
+*/
+int numbers_to_strings(struct date *d)
+{
+ int result = 0;
+ if (d->cal == CAL_UNKNOWN) {
+ gedcom_date_error(_("Cannot compute month names for unknown calendar type"));
+ result = 1;
+ }
+ else {
+ if (d->day != -1)
+ sprintf(d->day_str, "%d", d->day);
+
+ if (d->month > 0 && d->month <= max_month[d->cal])
+ strcpy(d->month_str, month_name[d->cal][d->month - 1]);
+
+ if (d->year_type == YEAR_SINGLE)
+ sprintf(d->year_str, "%d", d->year);
+ else
+ sprintf(d->year_str, "%d/%d", d->year - 1, (d->year % 100));
+ }
+ return result;
+}
+
+int gedcom_normalize_date(Date_input input, struct date_value *val)
+{
+ int result = 0;
+ if (val->type != DV_PHRASE) {
+ switch (input) {
+ case DI_FROM_STRINGS:
+ result |= strings_to_numbers(&val->date1);
+ result |= numbers_to_sdn(&val->date1);
+ if (val->type == DV_BETWEEN || val->type == DV_FROM_TO) {
+ result |= strings_to_numbers(&val->date2);
+ result |= numbers_to_sdn(&val->date2);
+ }
+ break;
+ case DI_FROM_NUMBERS:
+ result |= numbers_to_strings(&val->date1);
+ result |= numbers_to_sdn(&val->date1);
+ if (val->type == DV_BETWEEN || val->type == DV_FROM_TO) {
+ result |= numbers_to_strings(&val->date2);
+ result |= numbers_to_sdn(&val->date2);
+ }
+ break;
+ case DI_FROM_SDN:
+ result |= sdn_to_numbers(&val->date1);
+ result |= numbers_to_strings(&val->date1);
+ if (val->type == DV_BETWEEN || val->type == DV_FROM_TO) {
+ result |= sdn_to_numbers(&val->date2);
+ result |= numbers_to_strings(&val->date2);
+ }
+ break;
+ default:
+ break;