home *** CD-ROM | disk | FTP | other *** search
- // Zinc Interface Library - DATE.CPP
- // COPYRIGHT (C) 1990, 1991. All Rights Reserved.
- // Zinc Software Incorporated. Pleasant Grove, Utah USA
-
- #include "ui_gen.hpp"
- #include <dos.h>
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- static int _daysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
- static int TokenMatch(char *table, const char *token, int length)
- {
- if (toupper(*table) != toupper(*token))
- return 0; // No match.
- while (length)
- {
- while (*table && toupper(*table) != toupper(*token))
- table++;
- if (toupper(*table) == toupper(*token))
- {
- table++;
- token++;
- }
- else
- return 0; // No match.
- length--;
- }
- return 1; // Partial match.
- }
-
- int UI_DATE::DayOfWeek()
- {
- if (dYear <= 0 || dMonth == 0 || dDay == 0)
- return (0);
- int day = dDay;
- int month = dMonth;
- int year = dYear - 1700 - (month < 3);
- long julianDate = 365L * (year + (month < 3)) + year / 4 - year / 100 +
- (year + 100) / 400 + (305 * (month - 1) - (month > 2) * 20 +
- (month > 7) * 5 + 5) / 10 + day + 4;
- return ((int)(julianDate % 7) + 1);
- }
-
- int UI_DATE::DaysInMonth()
- {
- if (dMonth == 2 && LeapYear())
- return (29);
- return(_daysInMonth[dMonth - 1]);
- }
-
- int UI_DATE::DaysInYear()
- {
- return(LeapYear() ? 366 : 365);
- }
-
- void UI_DATE::Export()
- {
- struct date info;
- info.da_year = dYear;
- info.da_mon = dMonth;
- info.da_day = dDay;
- setdate(&info);
- }
-
- void UI_DATE::Export(int *packedDate)
- {
- *packedDate = ((dYear - 1980) << 9) | (dMonth << 5) | dDay;
- }
-
- void UI_DATE::Export(int *year, int *month, int *day, int *dayOfWeek)
- {
- if (year) *year = dYear;
- if (month) *month = dMonth;
- if (day) *day = dDay;
- if (dayOfWeek) *dayOfWeek = DayOfWeek();
- }
-
- void UI_DATE::Export(char *string, int maxLength, USHORT dtFlags)
- {
- int dayOfWeek = DayOfWeek();
- /* Get the initial separators */
- ui_getcountryinfo();
- char dateFormat = _countryInfo.co_date;
- if (FlagSet(dtFlags, DTF_US_FORMAT))
- dateFormat = 0;
- else if (FlagSet(dtFlags, DTF_EUROPEAN_FORMAT | DTF_MILITARY_FORMAT))
- dateFormat = 1;
- else if (FlagSet(dtFlags, DTF_JAPANESE_FORMAT))
- dateFormat = 2;
- char separator = _countryInfo.co_dtsep[0];
- if (FlagSet(dtFlags, DTF_DASH))
- separator = '-';
- else if (FlagSet(dtFlags, DTF_SLASH))
- separator = '/';
- char yearSize = 1;
- char alphaMonth = FlagSet(dtFlags, DTF_ALPHA_MONTH) ? 2 : 0;
- char showDayOfWeek = FlagSet(dtFlags, DTF_DAY_OF_WEEK) ? 2 : 0;
- char autoShorten = TRUE;
- USHORT zeroFill = FlagSet(dtFlags, DTF_ZERO_FILL);
- if (FlagSet(dtFlags, DTF_SHORT_YEAR))
- {
- autoShorten = FALSE;
- yearSize = 0;
- }
- if (FlagSet(dtFlags, DTF_SHORT_MONTH))
- {
- autoShorten = FALSE;
- alphaMonth = 1;
- }
- if (FlagSet(dtFlags, DTF_SHORT_DAY))
- {
- autoShorten = FALSE;
- showDayOfWeek = 1;
- }
- for (;;)
- {
- char tempDate[64];
- char *ptr = tempDate;
- if (showDayOfWeek && dayOfWeek)
- {
- char *shortDay = dayTable[dayOfWeek - 1].shortName;
- if (showDayOfWeek == 1 && shortDay)
- strcpy(tempDate, shortDay);
- else
- strcpy(tempDate, dayTable[dayOfWeek - 1].longName);
- strcat(tempDate, " ");
- ptr = strchr(tempDate, '\0');
- }
- char s_year[10];
- sprintf(s_year, dYear ? "%d" : "", yearSize ? dYear : dYear % 100);
- char s_month[15];
- if (FlagSet(dtFlags, DTF_MILITARY_FORMAT) && dMonth)
- {
- memcpy(s_month, monthTable[dMonth - 1].longName, 3);
- s_month[3] = '\0';
- }
- else if (alphaMonth && dMonth)
- {
- char *shortMonth = monthTable[dMonth - 1].shortName;
- if (alphaMonth == 1 && shortMonth)
- strcpy(s_month, shortMonth);
- else
- strcpy(s_month, monthTable[dMonth - 1].longName);
- }
- else
- sprintf(s_month, dMonth ? (zeroFill ? "%02d" : "%d") : "", dMonth);
- char s_day[10];
- sprintf(s_day, dDay ? (zeroFill ? "%02d" : "%d") : "", dDay);
- char realSeparator = (FlagSet(dtFlags, DTF_MILITARY_FORMAT) || alphaMonth) ?
- ' ' : separator;
- if (dateFormat == 1) // European
- sprintf(ptr, "%s%c%s%c%s",
- s_day, realSeparator, s_month, realSeparator, s_year);
- else if (dateFormat == 2) // Japan
- sprintf(ptr, "%s%c%s%c%s",
- s_year, realSeparator, s_month, realSeparator, s_day);
- else // U.S.
- {
- if (dMonth && dDay && dYear && alphaMonth)
- sprintf(ptr, "%s %s, %s", s_month, s_day, s_year);
- else
- sprintf(ptr, "%s%c%s%c%s",
- s_month, realSeparator, s_day, realSeparator, s_year);
- }
- // Strip leading separators.
- while (*ptr == realSeparator)
- memmove(ptr, ptr + 1, strlen(ptr));
- // Strip trailing separators and double separators.
- while (*ptr)
- {
- if (*ptr == realSeparator &&
- (*(ptr + 1) == realSeparator || *(ptr + 1) == '\0'))
- memmove(ptr, ptr + 1, strlen(ptr));
- else
- ptr++;
- }
- if (FlagSet(dtFlags, DTF_UPPER_CASE))
- strupr(tempDate);
- if (strlen(tempDate) <= maxLength)
- {
- strcpy(string, tempDate);
- break;
- }
- if (autoShorten)
- {
- if (showDayOfWeek == 2)
- showDayOfWeek--;
- else if (alphaMonth == 2)
- alphaMonth--;
- else if (yearSize)
- yearSize--;
- else if (showDayOfWeek)
- showDayOfWeek--;
- else if (alphaMonth)
- alphaMonth--;
- else
- autoShorten = FALSE;
- }
- else
- {
- strcpy(string, tempDate);
- break;
- }
- }
- }
-
- DTI_RESULT UI_DATE::Import()
- {
- struct date info;
- getdate(&info);
- return(Import(info.da_year, info.da_mon, info.da_day));
- }
-
- DTI_RESULT UI_DATE::Import(int date)
- {
- return(Import(1980 + ((date & 0xFE00) >> 9), (date & 0x01E0) >> 5, date & 0x001F));
- }
-
- DTI_RESULT UI_DATE::Import(int year, int month, int day)
- {
- int tYear = dYear;
- dYear = year;
- int tMonth = dMonth;
- dMonth = month;
- int tDay = dDay;
- dDay = day;
- if (year <= 0 || month < 0 || month > 12 || day < 0)
- {
- dYear = tYear;
- dMonth = tMonth;
- dDay = tDay;
- return (DTI_INVALID);
- }
- else if (day <= _daysInMonth[month-1] ||
- (month == 2 && day == 29 && LeapYear()))
- return (DTI_OK);
- dYear = tYear;
- dMonth = tMonth;
- dDay = tDay;
- return (DTI_INVALID);
- }
-
- DTI_RESULT UI_DATE::Import(const char *string, USHORT dtFlags)
- {
- int tYear = 0;
- int tMonth = 0;
- int tDay = 0;
-
- ui_getcountryinfo();
-
- // NOTE: For the purposes of the date string conversion algorithm, we
- // are only concerned with the respective order of the month and day
- // fields. Therefore, the only significance to the dateFormat values is
- // whether the value equals 1 or not. We save a line of code by calling
- // the JAPANESE_FORMAT a 0 even though it is really a 2.
- char dateFormat = _countryInfo.co_date;
- if (FlagSet(dtFlags, DTF_US_FORMAT | DTF_JAPANESE_FORMAT))
- dateFormat = 0;
- else if (FlagSet(dtFlags, DTF_EUROPEAN_FORMAT | DTF_MILITARY_FORMAT))
- dateFormat = 1;
- int alphaMonth = FALSE;
- int isBlank = TRUE;
- while (*string)
- {
- if (isalpha(*string))
- {
- int monthValue = TableLookup(monthTable, 12, string);
- if (!tMonth && monthValue < 0 ||
- (alphaMonth && monthValue > 0 && monthValue != tMonth))
- return DTI_AMBIGUOUS; // Ambiguous.
- if (!tMonth && monthValue > 0)
- tMonth = monthValue;
- else if (tMonth && !tDay && !alphaMonth && monthValue > 0)
- {
- // The "month" we thought we had must have been the day.
- tDay = tMonth;
- tMonth = monthValue;
- }
- else if (TableLookup(dayTable, 7, string) == 0)
- return DTI_INVALID_NAME; // Invalid month or week day name.
- if (monthValue > 0)
- alphaMonth = TRUE;
- while (isalpha(*string))
- string++;
- isBlank = FALSE;
- }
- else if (isdigit(*string))
- {
- int value = atoi(string);
- if (value <= 0)
- return DTI_INVALID; // Bad number.
- if (value > 31) // Must be the year.
- {
- if (tYear)
- return DTI_INVALID;
- else
- tYear = value < 100 ? 1900 + value : value;
- }
- else if (value > 12 || tMonth ||
- FlagSet(dtFlags, DTF_FORCE_ALPHA_MONTH))
- { // Must be the day.
- if (tDay)
- return DTI_INVALID;
- else
- tDay = value;
- }
- else if (tDay) // Must be the month.
- {
- if (tMonth || FlagSet(dtFlags, DTF_FORCE_ALPHA_MONTH))
- return DTI_INVALID;
- else
- tMonth = value;
- }
- else // Could be month or day.
- {
- if (dateFormat == 1)
- tDay = value;
- else
- tMonth = value;
- }
- while (isdigit(*string))
- string++;
- isBlank = FALSE;
- }
- else
- string++; // Ignore spaces and punctuation.
- }
- if (tMonth && !alphaMonth && !tDay)
- {
- tDay = tMonth; // Single digit is a day.
- tMonth = 0;
- }
- UI_DATE today;
- if (isBlank)
- {
- if (FlagSet(dtFlags, DTF_SYSTEM))
- {
- tYear = today.dYear;
- tMonth = today.dMonth;
- tDay = today.dDay;
- }
- else
- {
- Import(0, 0, 0); // Zero all fields.
- return DTI_VALUE_MISSING;
- }
- }
- return Import(tYear, tMonth, tDay);
- }
-
- int UI_DATE::LeapYear()
- {
- // Return TRUE if a leap year, else FALSE.
- return((dYear % 400 == 0) || ((dYear % 4 == 0) && (dYear % 100 != 0)));
- }
-
- int UI_DATE::TableLookup(NAME_PAIR *table, int tableLength,
- const char *token)
- {
- const char *ptr = token;
- int length = 0;
- int match = 0;
-
- while (isalpha(*ptr))
- {
- ptr++;
- length++;
- }
- for (int i = 0; i < tableLength; i++)
- {
- int result = TokenMatch(table[i].longName, token, length);
- if (result == 2)
- return i + 1; // Full match.
- else if (result)
- {
- if (match)
- return -1; // Ambiguous.
- else
- match = i + 1;
- }
- }
- return match;
- }
-
-