Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

213 lines
5.3 KiB

  1. #include "windows.h"
  2. #include <port1632.h>
  3. #include "date.h"
  4. extern CHAR chSepDate;
  5. extern CHAR chSepTime;
  6. extern CHAR sz1159[];
  7. extern CHAR sz2359[];
  8. extern INT iDate;
  9. extern INT iYearOffset;
  10. extern BOOL f24Time;
  11. extern BOOL fLZero;
  12. extern HANDLE hinstTimeDate;
  13. CHAR * APIENTRY Int2Ascii();
  14. CHAR * FAR APIENTRY Ascii2Int();
  15. CHAR * APIENTRY SkipDateSep();
  16. CHAR * APIENTRY GetMonthString();
  17. CHAR * APIENTRY GetWeekString();
  18. INT FAR APIENTRY ParseTimeString(pdt, pch)
  19. DOSTIME *pdt;
  20. register CHAR *pch;
  21. {
  22. INT h, m;
  23. CHAR *pchT;
  24. CHAR ch;
  25. BOOL fPM;
  26. if ((pch = Ascii2Int(pch, &h)) == NULL)
  27. return(PD_ERRFORMAT);
  28. if (*pch++ != chSepTime)
  29. return(PD_ERRFORMAT);
  30. if ((pch = Ascii2Int(pch, &m)) == NULL)
  31. return(PD_ERRFORMAT);
  32. /* Now look for match against AM or PM string */
  33. fPM = FALSE;
  34. if (*pch != 0) {
  35. /* Upper case the string in PLACE */
  36. AnsiUpper((LPSTR)pch);
  37. ch = *pch;
  38. if (ch == sz1159[0]) {
  39. pchT = sz1159;
  40. } else if (ch == sz2359[0]) {
  41. fPM = TRUE;
  42. pchT = sz2359;
  43. } else {
  44. return(PD_ERRFORMAT);
  45. }
  46. /* The following is just a case-insensitive, kanji-sensitive
  47. string equality check */
  48. while (*pchT != 0) {
  49. if (*pch == 0 || *pch++ != *pchT++)
  50. return(PD_ERRFORMAT);
  51. }
  52. }
  53. if (!f24Time) {
  54. if (h > 12)
  55. return PD_ERRSUBRANGE;
  56. if (!fPM) {
  57. /* Convert 12:xx am to 0:xx */
  58. if (h == 12)
  59. h = 0;
  60. } else {
  61. if (h == 0)
  62. return(PD_ERRSUBRANGE);
  63. /* convert 0..11 to 12..23 */
  64. if (h < 12)
  65. h += 12;
  66. }
  67. }
  68. if (h >= 24 || m >= 60)
  69. return(PD_ERRSUBRANGE);
  70. pdt->hour = (BYTE)h;
  71. pdt->minutes = (BYTE)m;
  72. pdt->seconds = 0;
  73. pdt->hundredths = 0;
  74. return(0);
  75. }
  76. BOOL FAR APIENTRY ParseDateString(pdd, pch)
  77. DOSDATE *pdd;
  78. register CHAR *pch;
  79. {
  80. INT m, d, y;
  81. register INT t;
  82. INT cDays;
  83. if ((pch = Ascii2Int(pch, &m)) == NULL)
  84. return(PD_ERRFORMAT);
  85. if ((pch = SkipDateSep(pch, chSepDate)) == NULL)
  86. return(PD_ERRFORMAT);
  87. if ((pch = Ascii2Int(pch, &d)) == NULL)
  88. return(PD_ERRFORMAT);
  89. if ((pch = SkipDateSep(pch, chSepDate)) == NULL)
  90. return(PD_ERRFORMAT);
  91. if ((pch = Ascii2Int(pch, &y)) == NULL)
  92. return(PD_ERRFORMAT);
  93. if (*pch != 0)
  94. return(PD_ERRFORMAT);
  95. switch (iDate) {
  96. case 1: /* mdy->dmy */
  97. t = m; m = d; d = t;
  98. break;
  99. case 2: /* mdy->ymd */
  100. t = y; y = m; m = d; d = t;
  101. break;
  102. }
  103. /* if y < 100, assume he's specifying the last two digits of 19xx */
  104. y += iYearOffset;
  105. if (y < 100)
  106. y += 1900;
  107. pdd->month = (BYTE)m;
  108. pdd->year = (WORD)y;
  109. pdd->day = (BYTE)d;
  110. return(ValidateDosDate(pdd)); /* validate the date */
  111. }
  112. CHAR * APIENTRY SkipDateSep(pch, ch)
  113. CHAR *pch;
  114. CHAR ch;
  115. {
  116. if (*pch == ch || *pch == '-' || *pch == '/')
  117. return(++pch);
  118. return(NULL);
  119. }
  120. CHAR * FAR APIENTRY Ascii2Int(pch, pw)
  121. register CHAR *pch;
  122. DWORD *pw; //- Changed from WORD to DWORD for 32 bit ints. 7/11/91 t-davema
  123. {
  124. register INT ch;
  125. DWORD n;
  126. CHAR *pchStart;
  127. /* skip leading spaces */
  128. while (*pch == ' ')
  129. pch++;
  130. pchStart = pch;
  131. n = 0;
  132. /* OLD: while (n < 3000 && !IsTwoByteCharPrefix(ch = *pch) && *pch >= '0' && ch <= '9') { */
  133. while (n < 3000 && /*!IsTwoByteCharPrefix(ch = *pch) &&*/ (ch = *pch) >= '0' && ch <= '9') {
  134. n = n * 10 + ch - '0';
  135. pch++;
  136. }
  137. if (pch == pchStart) /* return NULL if nothing parsed */
  138. return (NULL);
  139. /* skip trailing spaces */
  140. while (*pch == ' ')
  141. pch++;
  142. *pw = n;
  143. return(pch);
  144. }
  145. INT FAR APIENTRY ValidateDosDate(pdd)
  146. PDOSDATE pdd;
  147. {
  148. register WORD d;
  149. register WORD y;
  150. static INT cDaysAccum[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
  151. static BYTE rgbDaysMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  152. /* Make sure this is a valid date:
  153. - The year must be in the range 1980 through 2099 inclusive.
  154. - The month must be in the range 1 through 12 inclusive.
  155. - The day must be in the range 1 through the number of days
  156. of the specified month (which may need adjustment for leap year).
  157. */
  158. /* months are from 1..12 */
  159. if (pdd->month == 0 || pdd->month > 12)
  160. return(PD_ERRSUBRANGE);
  161. y = pdd->year - 1980;
  162. if (y > 119)
  163. return(PD_ERRRANGE);
  164. d = rgbDaysMonth[pdd->month - 1];
  165. if ((y & (4-1)) == 0 && pdd->month == 2)
  166. d++;
  167. if ((WORD)(pdd->day) > (WORD)d || (pdd->day == 0))
  168. return(PD_ERRSUBRANGE);
  169. /* We have a legal date. Now calculate day of week and store in pdd->dayofweek */
  170. /* calc no. days in previous years plus total up to beginning of month */
  171. d = y * 365 + cDaysAccum[pdd->month - 1];
  172. /* Add in the days for the preceding leap years. */
  173. if (y != 0)
  174. d += 1 + (y - 1) / 4;
  175. /* if this is a leap year and we're past feb, add in extra day. */
  176. if ((y & (4-1)) == 0 && pdd->month > 2)
  177. d++;
  178. /* add 2 since jan 1 1980 was a tuesday */
  179. pdd->dayofweek = ((d + pdd->day - 1 + 2) % 7);
  180. return(0);
  181. }