Leaked source code of windows server 2003
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.

433 lines
10 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name :
  4. datetime.cxx
  5. Abstract:
  6. This module exports common functions for date and time fields,
  7. Expanding into strings and manipulation.
  8. Author:
  9. Murali R. Krishnan ( MuraliK ) 3-Jan-1995
  10. Project:
  11. Internet Services Common DLL
  12. Functions Exported:
  13. SystemTimeToGMT()
  14. NtLargeIntegerTimeToSystemTime()
  15. Revision History:
  16. MuraliK 23-Feb-1996 Added IslFormatDate()
  17. --*/
  18. /************************************************************
  19. * Include Headers
  20. ************************************************************/
  21. #include <stdlib.h>
  22. #include "stdinc.h"
  23. #ifndef DBG_ASSERT
  24. #define DBG_ASSERT( f ) _ASSERT( f )
  25. #endif
  26. /************************************************************
  27. * Data
  28. ************************************************************/
  29. static TCHAR * s_rgchDays[] = {
  30. TEXT("Sun"),
  31. TEXT("Mon"),
  32. TEXT("Tue"),
  33. TEXT("Wed"),
  34. TEXT("Thu"),
  35. TEXT("Fri"),
  36. TEXT("Sat") };
  37. static TCHAR * s_rgchMonths[] = {
  38. TEXT("Jan"),
  39. TEXT("Feb"),
  40. TEXT("Mar"),
  41. TEXT("Apr"),
  42. TEXT("May"),
  43. TEXT("Jun"),
  44. TEXT("Jul"),
  45. TEXT("Aug"),
  46. TEXT("Sep"),
  47. TEXT("Oct"),
  48. TEXT("Nov"),
  49. TEXT("Dec") };
  50. /************************************************************
  51. * Functions
  52. ************************************************************/
  53. int
  54. make_month(
  55. TCHAR * s
  56. )
  57. {
  58. int i;
  59. for (i=0; i<12; i++)
  60. if (!_strnicmp(s_rgchMonths[i], s, 3))
  61. return i + 1;
  62. return 0;
  63. }
  64. BOOL
  65. SystemTimeToGMT(
  66. IN const SYSTEMTIME & st,
  67. OUT CHAR * pszBuff,
  68. IN DWORD cbBuff
  69. )
  70. /*++
  71. Converts the given system time to string representation
  72. containing GMT Formatted String.
  73. Arguments:
  74. st System time that needs to be converted.
  75. pstr pointer to string which will contain the GMT time on
  76. successful return.
  77. cbBuff size of pszBuff in bytes
  78. Returns:
  79. TRUE on success. FALSE on failure.
  80. History:
  81. MuraliK 3-Jan-1995
  82. --*/
  83. {
  84. DBG_ASSERT( pszBuff != NULL);
  85. if ( cbBuff < 40 ) {
  86. SetLastError( ERROR_INSUFFICIENT_BUFFER );
  87. return FALSE;
  88. }
  89. //
  90. // Formats a string like: "Thu, 14 Jul 1994 15:26:05 GMT"
  91. //
  92. ::wsprintf( pszBuff,
  93. TEXT( "%s, %02d %s %04d %02d:%02d:%02d GMT"),
  94. s_rgchDays[st.wDayOfWeek],
  95. st.wDay,
  96. s_rgchMonths[st.wMonth - 1],
  97. st.wYear,
  98. st.wHour,
  99. st.wMinute,
  100. st.wSecond);
  101. return ( TRUE);
  102. } // SystemTimeToGMT()
  103. BOOL
  104. NtLargeIntegerTimeToLocalSystemTime(
  105. IN const LARGE_INTEGER * pliTime,
  106. OUT SYSTEMTIME * pst)
  107. /*++
  108. Converts the time returned by NTIO apis ( which is a LARGE_INTEGER) into
  109. Win32 SystemTime in Local Time zone.
  110. Arguments:
  111. pliTime pointer to large integer containing the time in NT format.
  112. pst pointer to SYSTEMTIME structure which contains the time
  113. fields on successful conversion.
  114. Returns:
  115. TRUE on success and FALSE on failure.
  116. History:
  117. MuraliK 27-Apr-1995
  118. Limitations:
  119. This is an NT specific function !! Reason is: Win32 uses FILETIME
  120. structure for times. However LARGE_INTEGER and FILETIME both use
  121. similar structure with one difference that is one has a LONG while
  122. other has a ULONG.
  123. --*/
  124. {
  125. FILETIME ftLocal;
  126. if ( pliTime == NULL || pst == NULL) {
  127. SetLastError( ERROR_INVALID_PARAMETER);
  128. return ( FALSE);
  129. }
  130. //
  131. // Convert the given large integer to local file time and
  132. // then convert that to SYSTEMTIME.
  133. // structure, containing the time details.
  134. // I dont like this cast ( assumes too much about time structures)
  135. // but again suitable methods are not available.
  136. //
  137. return (FileTimeToLocalFileTime((FILETIME *) pliTime,
  138. &ftLocal) &&
  139. FileTimeToSystemTime(&ftLocal, pst)
  140. );
  141. } // NtLargeIntegerTimeToLocalSystemTime()
  142. BOOL
  143. SystemTimeToGMTEx(
  144. IN const SYSTEMTIME & st,
  145. OUT CHAR * pszBuff,
  146. IN DWORD cbBuff,
  147. IN DWORD csecOffset
  148. )
  149. /*++
  150. Converts the given system time to string representation
  151. containing GMT Formatted String.
  152. Arguments:
  153. st System time that needs to be converted.
  154. pstr pointer to string which will contain the GMT time on
  155. successful return.
  156. cbBuff size of pszBuff in bytes
  157. csecOffset The number of seconds to offset the specified system time
  158. Returns:
  159. TRUE on success. FALSE on failure.
  160. History:
  161. MuraliK 3-Jan-1995
  162. --*/
  163. {
  164. SYSTEMTIME sttmp;
  165. DWORD dwSeconds = 0;
  166. ULARGE_INTEGER liTime;
  167. FILETIME ft;
  168. DBG_ASSERT( pszBuff != NULL);
  169. //
  170. // If an offset is specified, calculate that now
  171. //
  172. if (!SystemTimeToFileTime( &st, &ft )) {
  173. return(FALSE);
  174. }
  175. liTime.HighPart = ft.dwHighDateTime;
  176. liTime.LowPart = ft.dwLowDateTime;
  177. //
  178. // Nt Large integer times are stored in 100ns increments, so convert the
  179. // second offset to 100ns increments then add it
  180. //
  181. liTime.QuadPart += ((ULONGLONG) csecOffset) * (ULONGLONG) 10000000;
  182. ft.dwHighDateTime = liTime.HighPart;
  183. ft.dwLowDateTime = liTime.LowPart;
  184. FileTimeToSystemTime( &ft, &sttmp );
  185. return SystemTimeToGMT( sttmp,
  186. pszBuff,
  187. cbBuff );
  188. } // SystemTimeToGMTEx
  189. BOOL
  190. NtLargeIntegerTimeToSystemTime(
  191. IN const LARGE_INTEGER & liTime,
  192. OUT SYSTEMTIME * pst)
  193. /*++
  194. Converts the time returned by NTIO apis ( which is a LARGE_INTEGER) into
  195. Win32 SystemTime in GMT
  196. Arguments:
  197. liTime large integer containing the time in NT format.
  198. pst pointer to SYSTEMTIME structure which contains the time
  199. fields on successful conversion.
  200. Returns:
  201. TRUE on success and FALSE on failure.
  202. History:
  203. MuraliK 3-Jan-1995
  204. Limitations:
  205. This is an NT specific function !! Reason is: Win32 uses FILETIME
  206. structure for times. However LARGE_INTEGER and FILETIME both use
  207. similar structure with one difference that is one has a LONG while
  208. other has a ULONG. Will that make a difference ? God knows.
  209. Or substitute whatever you want for God...
  210. --*/
  211. {
  212. FILETIME ft;
  213. if ( pst == NULL) {
  214. SetLastError( ERROR_INVALID_PARAMETER);
  215. return ( FALSE);
  216. }
  217. //
  218. // convert li to filetime
  219. //
  220. ft.dwLowDateTime = liTime.LowPart;
  221. ft.dwHighDateTime = liTime.HighPart;
  222. //
  223. // convert to system time
  224. //
  225. if (!FileTimeToSystemTime(&ft,pst)) {
  226. return(FALSE);
  227. }
  228. return ( TRUE);
  229. } // NtLargeIntegerTimeToSystemTime()
  230. BOOL
  231. NtSystemTimeToLargeInteger(
  232. IN const SYSTEMTIME * pst,
  233. OUT LARGE_INTEGER * pli
  234. )
  235. {
  236. FILETIME ft;
  237. //
  238. // Convert to file time
  239. //
  240. if ( !SystemTimeToFileTime( pst, &ft ) ) {
  241. return(FALSE);
  242. }
  243. //
  244. // Convert file time to large integer
  245. //
  246. pli->LowPart = ft.dwLowDateTime;
  247. pli->HighPart = ft.dwHighDateTime;
  248. return(TRUE);
  249. }
  250. BOOL
  251. StringTimeToFileTime(
  252. IN const TCHAR * pszTime,
  253. OUT LARGE_INTEGER * pliTime
  254. )
  255. /*++
  256. Converts a string representation of a GMT time (three different
  257. varieties) to an NT representation of a file time.
  258. We handle the following variations:
  259. Sun, 06 Nov 1994 08:49:37 GMT (RFC 822 updated by RFC 1123)
  260. Sunday, 06-Nov-94 08:49:37 GMT (RFC 850)
  261. Sun Nov 6 08:49:37 1994 (ANSI C's asctime() format
  262. Arguments:
  263. pszTime String representation of time field
  264. pliTime large integer containing the time in NT format.
  265. Returns:
  266. TRUE on success and FALSE on failure.
  267. History:
  268. Johnl 24-Jan-1995 Modified from WWW library
  269. --*/
  270. {
  271. TCHAR * s;
  272. SYSTEMTIME st;
  273. if (!pszTime) {
  274. SetLastError( ERROR_INVALID_PARAMETER );
  275. return FALSE;
  276. }
  277. st.wMilliseconds = 0;
  278. if ((s = strchr(pszTime, ','))) { /* Thursday, 10-Jun-93 01:29:59 GMT */
  279. s++; /* or: Thu, 10 Jan 1993 01:29:59 GMT */
  280. while (*s && *s==' ') s++;
  281. if (strchr(s,'-')) { /* First format */
  282. if ((int)strlen(s) < 18) {
  283. SetLastError( ERROR_INVALID_PARAMETER );
  284. return FALSE;
  285. }
  286. st.wDay = (WORD)atoi(s);
  287. st.wMonth = (WORD)make_month(s+3);
  288. st.wYear = (WORD)atoi(s+7);
  289. st.wHour = (WORD)atoi(s+10);
  290. st.wMinute = (WORD)atoi(s+13);
  291. st.wSecond = (WORD)atoi(s+16);
  292. } else { /* Second format */
  293. if ((int)strlen(s) < 20) {
  294. SetLastError( ERROR_INVALID_PARAMETER );
  295. return FALSE;
  296. }
  297. st.wDay = (WORD)atoi(s);
  298. st.wMonth = (WORD)make_month(s+3);
  299. st.wYear = (WORD)atoi(s+7);
  300. st.wHour = (WORD)atoi(s+12);
  301. st.wMinute = (WORD)atoi(s+15);
  302. st.wSecond = (WORD)atoi(s+18);
  303. }
  304. } else { /* Try the other format: Wed Jun 9 01:29:59 1993 GMT */
  305. s = (TCHAR *) pszTime;
  306. while (*s && *s==' ') s++;
  307. if ((int)strlen(s) < 24) {
  308. SetLastError( ERROR_INVALID_PARAMETER );
  309. return FALSE;
  310. }
  311. st.wDay = (WORD)atoi(s+8);
  312. st.wMonth = (WORD)make_month(s+4);
  313. st.wYear = (WORD)atoi(s+22);
  314. st.wHour = (WORD)atoi(s+11);
  315. st.wMinute = (WORD)atoi(s+14);
  316. st.wSecond = (WORD)atoi(s+17);
  317. }
  318. //
  319. // Adjust for dates with only two digits
  320. //
  321. if ( st.wYear < 1000 ) {
  322. if ( st.wYear < 50 ) {
  323. st.wYear += 2000;
  324. } else {
  325. st.wYear += 1900;
  326. }
  327. }
  328. if ( !NtSystemTimeToLargeInteger( &st,pliTime )) {
  329. SetLastError( ERROR_INVALID_PARAMETER );
  330. return FALSE;
  331. }
  332. return(TRUE);
  333. }