1 /* 2 * DATE.C - date internal command. 3 * 4 * 5 * History: 6 * 7 * 08 Jul 1998 (John P. Price) 8 * started. 9 * 10 * 20 Jul 1998 (John P. Price) 11 * corrected number of days for December from 30 to 31. 12 * (Thanx to Steffen Kaiser for bug report) 13 * 14 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>) 15 * added config.h include 16 * 17 * 29-Jul-1998 (Rob Lake) 18 * fixed stand-alone mode. 19 * Added Pacific C compatible dos_getdate functions 20 * 21 * 09-Jan-1999 (Eric Kohl) 22 * Added locale support 23 * 24 * 23-Jan-1999 (Eric Kohl) 25 * Unicode and redirection safe! 26 * 27 * 04-Feb-1999 (Eric Kohl) 28 * Fixed date input bug. 29 * 30 * 03-Apr-2005 (Magnus Olsen <magnus@greatlord.com>) 31 * Remove all hardcoded strings in En.rc 32 */ 33 34 #include "precomp.h" 35 36 #ifdef INCLUDE_CMD_DATE 37 38 39 static WORD awMonths[2][13] = 40 { 41 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 42 {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 43 }; 44 45 46 static VOID 47 PromptDateString(VOID) 48 { 49 switch (nDateFormat) 50 { 51 case 0: /* mmddyy */ 52 default: 53 ConOutResPrintf(STRING_DATE_HELP1, cDateSeparator, cDateSeparator); 54 break; 55 56 case 1: /* ddmmyy */ 57 ConOutResPrintf(STRING_DATE_HELP2, cDateSeparator, cDateSeparator); 58 break; 59 60 case 2: /* yymmdd */ 61 ConOutResPrintf(STRING_DATE_HELP3, cDateSeparator, cDateSeparator); 62 break; 63 } 64 } 65 66 static BOOL 67 ReadNumber (LPTSTR *s, LPWORD lpwValue) 68 { 69 if (_istdigit (**s)) 70 { 71 while (_istdigit (**s)) 72 { 73 *lpwValue = *lpwValue * 10 + **s - _T('0'); 74 (*s)++; 75 } 76 return TRUE; 77 } 78 return FALSE; 79 } 80 81 static BOOL 82 ReadSeparator (LPTSTR *s) 83 { 84 if (**s == _T('/') || **s == _T('-') || **s == cDateSeparator) 85 { 86 (*s)++; 87 return TRUE; 88 } 89 return FALSE; 90 } 91 92 static BOOL 93 ParseDate (LPTSTR s) 94 { 95 SYSTEMTIME d; 96 unsigned char leap; 97 LPTSTR p = s; 98 99 if (!*s) 100 return TRUE; 101 102 GetLocalTime (&d); 103 104 d.wYear = 0; 105 d.wDay = 0; 106 d.wMonth = 0; 107 108 switch (nDateFormat) 109 { 110 case 0: /* mmddyy */ 111 default: 112 if (!ReadNumber (&p, &d.wMonth)) 113 return FALSE; 114 if (!ReadSeparator (&p)) 115 return FALSE; 116 if (!ReadNumber (&p, &d.wDay)) 117 return FALSE; 118 if (!ReadSeparator (&p)) 119 return FALSE; 120 if (!ReadNumber (&p, &d.wYear)) 121 return FALSE; 122 break; 123 124 case 1: /* ddmmyy */ 125 if (!ReadNumber (&p, &d.wDay)) 126 return FALSE; 127 if (!ReadSeparator (&p)) 128 return FALSE; 129 if (!ReadNumber (&p, &d.wMonth)) 130 return FALSE; 131 if (!ReadSeparator (&p)) 132 return FALSE; 133 if (!ReadNumber (&p, &d.wYear)) 134 return FALSE; 135 break; 136 137 case 2: /* yymmdd */ 138 if (!ReadNumber (&p, &d.wYear)) 139 return FALSE; 140 if (!ReadSeparator (&p)) 141 return FALSE; 142 if (!ReadNumber (&p, &d.wMonth)) 143 return FALSE; 144 if (!ReadSeparator (&p)) 145 return FALSE; 146 if (!ReadNumber (&p, &d.wDay)) 147 return FALSE; 148 break; 149 } 150 151 /* if only entered two digits: */ 152 /* assume 2000's if value less than 80 */ 153 /* assume 1900's if value greater or equal 80 */ 154 if (d.wYear <= 99) 155 { 156 if (d.wYear >= 80) 157 d.wYear = 1900 + d.wYear; 158 else 159 d.wYear = 2000 + d.wYear; 160 } 161 162 leap = (!(d.wYear % 4) && (d.wYear % 100)) || !(d.wYear % 400); 163 164 if ((d.wMonth >= 1 && d.wMonth <= 12) && 165 (d.wDay >= 1 && d.wDay <= awMonths[leap][d.wMonth]) && 166 (d.wYear >= 1980 && d.wYear <= 2099)) 167 { 168 SetLocalTime (&d); 169 return TRUE; 170 } 171 172 return FALSE; 173 } 174 175 176 INT cmd_date(LPTSTR param) 177 { 178 LPTSTR* arg; 179 INT argc; 180 INT i; 181 BOOL bPrompt = TRUE; 182 INT nDateString = -1; 183 TCHAR szDate[40]; 184 185 if (!_tcsncmp(param, _T("/?"), 2)) 186 { 187 ConOutResPaging(TRUE, STRING_DATE_HELP4); 188 return 0; 189 } 190 191 nErrorLevel = 0; 192 193 /* Build the parameter array */ 194 arg = split(param, &argc, FALSE, FALSE); 195 196 /* Check for options */ 197 for (i = 0; i < argc; i++) 198 { 199 if (bEnableExtensions && (_tcsicmp(arg[i], _T("/T")) == 0)) 200 bPrompt = FALSE; 201 202 if ((*arg[i] != _T('/')) && (nDateString == -1)) 203 nDateString = i; 204 } 205 206 if (nDateString == -1) 207 { 208 ConOutResPuts(STRING_DATE_NOW); 209 ConOutPrintf(_T("%s\n"), GetDateString()); 210 } 211 212 if (!bPrompt) 213 { 214 freep(arg); 215 return 0; 216 } 217 218 while (TRUE) 219 { 220 if (nDateString == -1) 221 { 222 PromptDateString(); 223 ConInString(szDate, ARRAYSIZE(szDate)); 224 225 TRACE("\'%s\'\n", debugstr_aw(szDate)); 226 227 while (*szDate && szDate[_tcslen(szDate) - 1] < _T(' ')) 228 szDate[_tcslen(szDate) - 1] = _T('\0'); 229 230 if (ParseDate(szDate)) 231 { 232 freep(arg); 233 return 0; 234 } 235 } 236 else 237 { 238 if (ParseDate(arg[nDateString])) 239 { 240 freep(arg); 241 return 0; 242 } 243 244 /* Force input the next time around */ 245 nDateString = -1; 246 } 247 248 ConErrResPuts(STRING_DATE_ERROR); 249 nErrorLevel = 1; 250 } 251 252 freep(arg); 253 return 0; 254 } 255 #endif /* INCLUDE_CMD_DATE */ 256 257 /* EOF */ 258