Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 1 | /* |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 2 | * Nt time functions. |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 3 | * |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 4 | * RtlTimeToTimeFields, RtlTimeFieldsToTime and defines are taken from ReactOS and |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 5 | * adapted to wine with special permissions of the author. This code is |
| 6 | * Copyright 2002 Rex Jolliff (rex@lvcablemodem.com) |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 7 | * |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 8 | * Copyright 1999 Juergen Schmied |
| 9 | * |
| 10 | * This library is free software; you can redistribute it and/or |
| 11 | * modify it under the terms of the GNU Lesser General Public |
| 12 | * License as published by the Free Software Foundation; either |
| 13 | * version 2.1 of the License, or (at your option) any later version. |
| 14 | * |
| 15 | * This library is distributed in the hope that it will be useful, |
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 18 | * Lesser General Public License for more details. |
| 19 | * |
| 20 | * You should have received a copy of the GNU Lesser General Public |
| 21 | * License along with this library; if not, write to the Free Software |
Jonathan Ernst | 360a3f9 | 2006-05-18 14:49:52 +0200 | [diff] [blame] | 22 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 23 | */ |
| 24 | |
Patrik Stridvall | d016f81 | 2002-08-17 00:43:16 +0000 | [diff] [blame] | 25 | #include "config.h" |
Patrik Stridvall | 51e6c0c | 2002-08-31 19:04:14 +0000 | [diff] [blame] | 26 | #include "wine/port.h" |
Patrik Stridvall | d016f81 | 2002-08-17 00:43:16 +0000 | [diff] [blame] | 27 | |
Alexandre Julliard | e37c6e1 | 2003-09-05 23:08:26 +0000 | [diff] [blame] | 28 | #include <stdarg.h> |
Vincent Béron | ea966aa | 2002-11-27 20:14:45 +0000 | [diff] [blame] | 29 | #include <stdlib.h> |
Dmitry Timoshkov | a188662 | 2007-07-29 21:31:00 +0900 | [diff] [blame] | 30 | #include <errno.h> |
David Luyer | 26cd7a1 | 1999-03-25 15:57:35 +0000 | [diff] [blame] | 31 | #include <string.h> |
Alexandre Julliard | 25b23a0 | 2004-09-07 23:01:34 +0000 | [diff] [blame] | 32 | #include <limits.h> |
Alexandre Julliard | d76f9f9 | 2000-10-01 01:40:42 +0000 | [diff] [blame] | 33 | #include <time.h> |
Patrik Stridvall | d016f81 | 2002-08-17 00:43:16 +0000 | [diff] [blame] | 34 | #ifdef HAVE_SYS_TIME_H |
| 35 | # include <sys/time.h> |
| 36 | #endif |
| 37 | #ifdef HAVE_UNISTD_H |
| 38 | # include <unistd.h> |
| 39 | #endif |
Dimitrie O. Paun | 297f3d8 | 2003-01-07 20:36:20 +0000 | [diff] [blame] | 40 | |
| 41 | #define NONAMELESSUNION |
| 42 | #define NONAMELESSSTRUCT |
Ge van Geldorp | 1a1583a | 2005-11-28 17:32:54 +0100 | [diff] [blame] | 43 | #include "ntstatus.h" |
| 44 | #define WIN32_NO_STATUS |
Alexandre Julliard | e37c6e1 | 2003-09-05 23:08:26 +0000 | [diff] [blame] | 45 | #include "windef.h" |
Patrik Stridvall | 9c1de6d | 2002-09-12 22:07:02 +0000 | [diff] [blame] | 46 | #include "winternl.h" |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 47 | #include "wine/unicode.h" |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 48 | #include "wine/debug.h" |
Alexandre Julliard | 462172a | 2003-04-02 22:48:59 +0000 | [diff] [blame] | 49 | #include "ntdll_misc.h" |
Patrik Stridvall | b4b9fae | 1999-04-19 14:56:29 +0000 | [diff] [blame] | 50 | |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 51 | WINE_DEFAULT_DEBUG_CHANNEL(ntdll); |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 52 | |
Mike McCormack | 6b636e3 | 2005-06-25 18:00:57 +0000 | [diff] [blame] | 53 | static RTL_CRITICAL_SECTION TIME_GetBias_section; |
| 54 | static RTL_CRITICAL_SECTION_DEBUG critsect_debug = |
Huw Davies | 67e2d6c | 2004-02-27 00:43:20 +0000 | [diff] [blame] | 55 | { |
| 56 | 0, 0, &TIME_GetBias_section, |
| 57 | { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, |
Alexandre Julliard | 20a1a20 | 2005-09-09 10:19:44 +0000 | [diff] [blame] | 58 | 0, 0, { (DWORD_PTR)(__FILE__ ": TIME_GetBias_section") } |
Huw Davies | 67e2d6c | 2004-02-27 00:43:20 +0000 | [diff] [blame] | 59 | }; |
Mike McCormack | 6b636e3 | 2005-06-25 18:00:57 +0000 | [diff] [blame] | 60 | static RTL_CRITICAL_SECTION TIME_GetBias_section = { &critsect_debug, -1, 0, 0, 0, 0 }; |
Huw Davies | 67e2d6c | 2004-02-27 00:43:20 +0000 | [diff] [blame] | 61 | |
Rein Klazes | c5c93d1 | 2004-10-18 21:19:28 +0000 | [diff] [blame] | 62 | /* TimeZone registry key values */ |
| 63 | static const WCHAR TZInformationKeyW[] = { 'M','a','c','h','i','n','e','\\', |
| 64 | 'S','Y','S','T','E','M','\\','C','u','r','r','e','n','t','C','o','n','t','r', |
| 65 | 'o','l','S','e','t','\\','C','o','n','t','r','o','l','\\','T','i','m','e','z', |
| 66 | 'o','n','e','I','n','f','o','r','m','a','t','i','o','n', 0}; |
| 67 | static const WCHAR TZStandardStartW[] = { |
| 68 | 'S','t','a','n','d','a','r','d','s','t','a','r','t', 0}; |
| 69 | static const WCHAR TZDaylightStartW[] = { |
| 70 | 'D','a','y','l','i','g','h','t','s','t','a','r','t', 0}; |
| 71 | static const WCHAR TZDaylightBiasW[] = { |
| 72 | 'D','a','y','l','i','g','h','t','B','i','a','s', 0}; |
| 73 | static const WCHAR TZStandardBiasW[] = { |
| 74 | 'S','t','a','n','d','a','r','d','B','i','a','s', 0}; |
| 75 | static const WCHAR TZBiasW[] = {'B','i','a','s', 0}; |
| 76 | static const WCHAR TZDaylightNameW[] = { |
| 77 | 'D','a','y','l','i','g','h','t','N','a','m','e', 0}; |
| 78 | static const WCHAR TZStandardNameW[] = { |
| 79 | 'S','t','a','n','d','a','r','d','N','a','m','e', 0}; |
| 80 | |
Huw Davies | 67e2d6c | 2004-02-27 00:43:20 +0000 | [diff] [blame] | 81 | |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 82 | #define SETTIME_MAX_ADJUST 120 |
| 83 | |
| 84 | /* This structure is used to store strings that represent all of the time zones |
| 85 | * in the world. (This is used to help GetTimeZoneInformation) |
| 86 | */ |
| 87 | struct tagTZ_INFO |
| 88 | { |
| 89 | const char *psTZFromUnix; |
| 90 | WCHAR psTZWindows[32]; |
| 91 | int bias; |
| 92 | int dst; |
| 93 | }; |
| 94 | |
| 95 | static const struct tagTZ_INFO TZ_INFO[] = |
| 96 | { |
| 97 | {"MHT", |
| 98 | {'D','a','t','e','l','i','n','e',' ','S','t','a','n','d','a','r','d',' ', |
| 99 | 'T','i','m','e','\0'}, -720, 0}, |
| 100 | {"SST", |
| 101 | {'S','a','m','o','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m', |
| 102 | 'e','\0'}, 660, 0}, |
| 103 | {"HST", |
| 104 | {'H','a','w','a','i','i','a','n',' ','S','t','a','n','d','a','r','d',' ', |
| 105 | 'T','i','m','e','\0'}, 600, 0}, |
Mike McCormack | 5b40551 | 2005-11-08 10:57:50 +0000 | [diff] [blame] | 106 | {"AKST", |
| 107 | {'A','l','a','s','k','a','n',' ','S','t','a','n','d','a','r','d',' ', |
| 108 | 'T','i','m','e',0}, 540, 0 }, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 109 | {"AKDT", |
| 110 | {'A','l','a','s','k','a','n',' ','S','t','a','n','d','a','r','d',' ','T', |
| 111 | 'i','m','e','\0'}, 480, 1}, |
Roger Olson | 3078222 | 2004-11-02 05:22:01 +0000 | [diff] [blame] | 112 | {"PST", |
| 113 | {'P','a','c','i','f','i','c',' ','S','t','a','n','d','a','r','d',' ','T', |
| 114 | 'i','m','e','\0'}, 480, 0}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 115 | {"PDT", |
| 116 | {'P','a','c','i','f','i','c',' ','S','t','a','n','d','a','r','d',' ','T', |
| 117 | 'i','m','e','\0'}, 420, 1}, |
| 118 | {"MST", |
| 119 | {'U','S',' ','M','o','u','n','t','a','i','n',' ','S','t','a','n','d','a', |
| 120 | 'r','d',' ','T','i','m','e','\0'}, 420, 0}, |
| 121 | {"MDT", |
| 122 | {'M','o','u','n','t','a','i','n',' ','S','t','a','n','d','a','r','d',' ', |
| 123 | 'T','i','m','e','\0'}, 360, 1}, |
| 124 | {"CST", |
| 125 | {'C','e','n','t','r','a','l',' ','A','m','e','r','i','c','a',' ','S','t', |
| 126 | 'a','n','d','a','r','d',' ','T','i','m','e','\0'}, 360, 0}, |
| 127 | {"CDT", |
| 128 | {'C','e','n','t','r','a','l',' ','S','t','a','n','d','a','r','d',' ','T', |
| 129 | 'i','m','e','\0'}, 300, 1}, |
| 130 | {"COT", |
| 131 | {'S','A',' ','P','a','c','i','f','i','c',' ','S','t','a','n','d','a','r', |
| 132 | 'd',' ','T','i','m','e','\0'}, 300, 0}, |
Mike McCormack | 5b40551 | 2005-11-08 10:57:50 +0000 | [diff] [blame] | 133 | {"PET", |
| 134 | {'S','A',' ','P','a','c','i','f','i','c',' ','S','t','a','n','d','a','r', |
| 135 | 'd',' ','T','i','m','e',0}, 300, 0 }, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 136 | {"EDT", |
| 137 | {'E','a','s','t','e','r','n',' ','S','t','a','n','d','a','r','d',' ','T', |
| 138 | 'i','m','e','\0'}, 240, 1}, |
| 139 | {"EST", |
| 140 | {'U','S',' ','E','a','s','t','e','r','n',' ','S','t','a','n','d','a','r', |
| 141 | 'd',' ','T','i','m','e','\0'}, 300, 0}, |
Alex Villacís Lasso | 3cea3a5 | 2005-03-14 10:04:30 +0000 | [diff] [blame] | 142 | {"ECT", |
| 143 | {'E','a','s','t','e','r','n',' ','C','e','n','t','r','a','l',' ','S','t','a','n','d','a','r', |
| 144 | 'd',' ','T','i','m','e','\0'}, 300, 0}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 145 | {"ADT", |
| 146 | {'A','t','l','a','n','t','i','c',' ','S','t','a','n','d','a','r','d',' ', |
| 147 | 'T','i','m','e','\0'}, 180, 1}, |
| 148 | {"VET", |
| 149 | {'S','A',' ','W','e','s','t','e','r','n',' ','S','t','a','n','d','a','r', |
| 150 | 'd',' ','T','i','m','e','\0'}, 240, 0}, |
| 151 | {"CLT", |
| 152 | {'P','a','c','i','f','i','c',' ','S','A',' ','S','t','a','n','d','a','r', |
| 153 | 'd',' ','T','i','m','e','\0'}, 240, 0}, |
Mike McCormack | 5b40551 | 2005-11-08 10:57:50 +0000 | [diff] [blame] | 154 | {"CLST", |
| 155 | {'P','a','c','i','f','i','c',' ','S','A',' ','S','t','a','n','d','a','r', |
| 156 | 'd',' ','T','i','m','e',0}, 180, 1}, |
| 157 | {"AST", |
| 158 | {'A','t','l','a','n','t','i','c',' ','S','t','a','n','d','a','r','d',' ', |
| 159 | 'T','i','m','e',0}, 240, 0 }, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 160 | {"NDT", |
| 161 | {'N','e','w','f','o','u','n','d','l','a','n','d',' ','S','t','a','n','d', |
| 162 | 'a','r','d',' ','T','i','m','e','\0'}, 150, 1}, |
Mike McCormack | 5b40551 | 2005-11-08 10:57:50 +0000 | [diff] [blame] | 163 | {"NST", |
| 164 | {'N','e','w','f','o','u','n','d','l','a','n','d',' ','S','t','a','n','d', |
| 165 | 'a','r','d',' ','T','i','m','e',0}, 210, 0 }, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 166 | {"BRT", |
Marcelo Duarte | 37bc441 | 2005-02-14 11:03:05 +0000 | [diff] [blame] | 167 | {'B','r','a','z','i','l','i','a','n',' ','S','t','a','n','d','a','r','d', |
| 168 | ' ','T','i','m','e','\0'}, 180, 0}, |
Tony Lambregts | 5f0e554 | 2005-01-06 19:35:35 +0000 | [diff] [blame] | 169 | {"BRST", |
Marcelo Duarte | 37bc441 | 2005-02-14 11:03:05 +0000 | [diff] [blame] | 170 | {'B','r','a','z','i','l','i','a','n',' ','S','u','m','m','e','r', |
| 171 | ' ','T','i','m','e','\0'}, 120, 1}, |
Julio E. Gonzalez P | 5b98738 | 2007-07-04 20:52:29 -0400 | [diff] [blame] | 172 | {"PYT", |
| 173 | {'P','a','r','a','g','u','a','y','a','n',' ', |
| 174 | 'S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'}, 240, 0}, |
| 175 | {"PYST", |
| 176 | {'P','a','r','a','g','u','a','y','a','n',' ','S','u','m','m','e','r', |
| 177 | ' ','T','i','m','e','\0'}, 180, 1}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 178 | {"ART", |
| 179 | {'S','A',' ','E','a','s','t','e','r','n',' ','S','t','a','n','d','a','r', |
| 180 | 'd',' ','T','i','m','e','\0'}, 180, 0}, |
| 181 | {"WGST", |
| 182 | {'G','r','e','e','n','l','a','n','d',' ','S','t','a','n','d','a','r','d', |
| 183 | ' ','T','i','m','e','\0'}, 120, 1}, |
| 184 | {"GST", |
| 185 | {'M','i','d','-','A','t','l','a','n','t','i','c',' ','S','t','a','n','d', |
| 186 | 'a','r','d',' ','T','i','m','e','\0'}, 120, 0}, |
Mike McCormack | 5b40551 | 2005-11-08 10:57:50 +0000 | [diff] [blame] | 187 | {"AZOT", |
| 188 | {'A','z','o','r','e','s',' ','S','t','a','n','d','a','r','d',' ','T','i', |
| 189 | 'm','e',0}, 60, 0}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 190 | {"AZOST", |
| 191 | {'A','z','o','r','e','s',' ','S','t','a','n','d','a','r','d',' ','T','i', |
| 192 | 'm','e','\0'}, 0, 1}, |
| 193 | {"CVT", |
| 194 | {'C','a','p','e',' ','V','e','r','d','e',' ','S','t','a','n','d','a','r', |
| 195 | 'd',' ','T','i','m','e','\0'}, 60, 0}, |
Francois Gouget | ee7f5eb | 2005-05-07 14:50:56 +0000 | [diff] [blame] | 196 | {"WEST", |
| 197 | {'W','e','s','t','e','r','n',' ','E','u','r','o','p','e','a','n',' ','S','u','m','m','e','r',' ','T','i','m','e','\0'}, -60, 1}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 198 | {"WET", |
| 199 | {'G','r','e','e','n','w','i','c','h',' ','S','t','a','n','d','a','r','d', |
| 200 | ' ','T','i','m','e','\0'}, 0, 0}, |
| 201 | {"BST", |
| 202 | {'G','M','T',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'}, |
| 203 | -60, 1}, |
Juan Lang | 5e1b418 | 2005-05-10 08:25:30 +0000 | [diff] [blame] | 204 | {"IST", |
| 205 | {'I','r','i','s','h',' ','S','u','m','m','e','r',' ','T','i','m','e','\0'}, |
| 206 | -60, 1}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 207 | {"GMT", |
| 208 | {'G','M','T',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'}, |
| 209 | 0, 0}, |
Filip Navara | 63c6359 | 2004-10-04 19:29:16 +0000 | [diff] [blame] | 210 | {"UTC", |
| 211 | {'G','M','T',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'}, |
| 212 | 0, 0}, |
Michael Jung | 8229752 | 2004-11-02 05:28:01 +0000 | [diff] [blame] | 213 | {"CET", |
| 214 | {'C','e','n','t','r','a','l',' ','E','u','r','o','p','e','a','n',' ', |
| 215 | 'T','i','m','e','\0'}, -60, 0}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 216 | {"CEST", |
| 217 | {'C','e','n','t','r','a','l',' ','E','u','r','o','p','e',' ','S','t','a', |
| 218 | 'n','d','a','r','d',' ','T','i','m','e','\0'}, -120, 1}, |
Uwe Bonnes | d349908 | 2004-09-06 21:26:37 +0000 | [diff] [blame] | 219 | {"MET", |
| 220 | {'C','e','n','t','r','a','l',' ','E','u','r','o','p','e',' ','S','t','a', |
| 221 | 'n','d','a','r','d',' ','T','i','m','e','\0'}, -60, 0}, |
| 222 | {"MEST", |
| 223 | {'C','e','n','t','r','a','l',' ','E','u','r','o','p','e',' ','D','a','y', |
| 224 | 'l','i','g','h','t',' ','T','i','m','e','\0'}, -120, 1}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 225 | {"WAT", |
| 226 | {'W','.',' ','C','e','n','t','r','a','l',' ','A','f','r','i','c','a',' ', |
| 227 | 'S','t','a','n','d','a','r','d',' ','T','i','m','e','\0'}, -60, 0}, |
| 228 | {"EEST", |
| 229 | {'E','.',' ','E','u','r','o','p','e',' ','S','t','a','n','d','a','r','d', |
| 230 | ' ','T','i','m','e','\0'}, -180, 1}, |
| 231 | {"EET", |
| 232 | {'E','g','y','p','t',' ','S','t','a','n','d','a','r','d',' ','T','i','m', |
| 233 | 'e','\0'}, -120, 0}, |
| 234 | {"CAT", |
Stewart Allen | 7cb5543 | 2004-12-06 11:39:34 +0000 | [diff] [blame] | 235 | {'C','e','n','t','r','a','l',' ','A','f','r','i','c','a','n',' ' |
| 236 | ,'T','i','m','e','\0'}, -120, 0}, |
| 237 | {"SAST", |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 238 | {'S','o','u','t','h',' ','A','f','r','i','c','a',' ','S','t','a','n','d', |
| 239 | 'a','r','d',' ','T','i','m','e','\0'}, -120, 0}, |
| 240 | {"IST", |
| 241 | {'I','s','r','a','e','l',' ','S','t','a','n','d','a','r','d',' ','T','i', |
| 242 | 'm','e','\0'}, -120, 0}, |
Erez Volk | 14a3275 | 2007-05-15 20:43:51 +0300 | [diff] [blame] | 243 | {"IDT", |
| 244 | {'I','s','r','a','e','l',' ','S','t','a','n','d','a','r','d',' ','T','i', |
| 245 | 'm','e','\0'}, -180, 1}, |
Vitaly Lipatov | 4c801af | 2004-11-02 19:25:05 +0000 | [diff] [blame] | 246 | {"MSK", |
| 247 | {'R','u','s','s','i','a','n',' ','S','t','a','n','d','a','r','d',' ','T', |
| 248 | 'i','m','e','\0'}, -180, 0}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 249 | {"ADT", |
| 250 | {'A','r','a','b','i','c',' ','S','t','a','n','d','a','r','d',' ','T','i', |
| 251 | 'm','e','\0'}, -240, 1}, |
| 252 | {"AST", |
| 253 | {'A','r','a','b',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e', |
| 254 | '\0'}, -180, 0}, |
| 255 | {"MSD", |
| 256 | {'R','u','s','s','i','a','n',' ','S','t','a','n','d','a','r','d',' ','T', |
| 257 | 'i','m','e','\0'}, -240, 1}, |
| 258 | {"EAT", |
| 259 | {'E','.',' ','A','f','r','i','c','a',' ','S','t','a','n','d','a','r','d', |
| 260 | ' ','T','i','m','e','\0'}, -180, 0}, |
| 261 | {"IRST", |
| 262 | {'I','r','a','n',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e', |
Mike McCormack | 5b40551 | 2005-11-08 10:57:50 +0000 | [diff] [blame] | 263 | 0},-210, 0 }, |
| 264 | {"IRST", |
| 265 | {'I','r','a','n',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e', |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 266 | '\0'}, -270, 1}, |
| 267 | {"GST", |
| 268 | {'A','r','a','b','i','a','n',' ','S','t','a','n','d','a','r','d',' ','T', |
| 269 | 'i','m','e','\0'}, -240, 0}, |
Mike McCormack | 5b40551 | 2005-11-08 10:57:50 +0000 | [diff] [blame] | 270 | {"AZT", |
| 271 | {'C','a','u','c','a','s','u','s',' ','S','t','a','n','d','a','r','d',' ', |
| 272 | 'T','i','m','e',0}, -240, 0 }, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 273 | {"AZST", |
| 274 | {'C','a','u','c','a','s','u','s',' ','S','t','a','n','d','a','r','d',' ', |
| 275 | 'T','i','m','e','\0'}, -300, 1}, |
| 276 | {"AFT", |
| 277 | {'A','f','g','h','a','n','i','s','t','a','n',' ','S','t','a','n','d','a', |
| 278 | 'r','d',' ','T','i','m','e','\0'}, -270, 0}, |
Tony Lambregts | e1ff586d | 2005-01-20 10:52:57 +0000 | [diff] [blame] | 279 | {"SAMT", |
| 280 | {'S','a','m','a','r','a',' ','S','t','a','n','d','a','r','d',' ','T','i', |
Konstantin Kondratyuk | b7c38b0 | 2007-07-24 08:57:55 +0400 | [diff] [blame] | 281 | 'm','e','(','W','i','n','t','e','r',')','\0'}, -240, 0}, |
| 282 | {"SAMST", |
| 283 | {'S','a','m','a','r','a',' ','D','a','y','l','i','g','h','t',' ','T','i', |
| 284 | 'm','e','(','S','u','m','m','e','r',')','\0'}, -300, 1}, |
Sergei Butakov | 4f53d5a | 2006-02-07 16:51:51 +0100 | [diff] [blame] | 285 | {"YEKT", |
| 286 | {'U','r','a','l','s',' ','S','t','a','n','d','a','r','d', |
| 287 | ' ','T','i','m','e',' ','(','W','i','n','t','e','r',')','\0'}, -300, 0}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 288 | {"YEKST", |
Sergei Butakov | 4f53d5a | 2006-02-07 16:51:51 +0100 | [diff] [blame] | 289 | {'U','r','a','l','s',' ','D','a','y','l','i','g','h','t', |
| 290 | ' ','T','i','m','e',' ','(','S','u','m','m','e','r',')','\0'}, -360, 1}, |
Konstantin Kondratyuk | 4f97674 | 2007-02-08 17:13:13 +0300 | [diff] [blame] | 291 | {"OMST", |
| 292 | {'O','m','s','k',' ','S','t','a','n','d','a','r','d', |
| 293 | ' ','T','i','m','e',' ','(','W','i','n','t','e','r',')','\0'}, -360, 0}, |
| 294 | {"OMSST", |
| 295 | {'O','m','s','k',' ','D','a','y','l','i','g','h','t', |
| 296 | ' ','T','i','m','e',' ','(','S','u','m','m','e','r',')','\0'}, -420, 1}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 297 | {"PKT", |
| 298 | {'W','e','s','t',' ','A','s','i','a',' ','S','t','a','n','d','a','r','d', |
| 299 | ' ','T','i','m','e','\0'}, -300, 0}, |
| 300 | {"IST", |
| 301 | {'I','n','d','i','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m', |
| 302 | 'e','\0'}, -330, 0}, |
| 303 | {"NPT", |
| 304 | {'N','e','p','a','l',' ','S','t','a','n','d','a','r','d',' ','T','i','m', |
| 305 | 'e','\0'}, -345, 0}, |
| 306 | {"ALMST", |
| 307 | {'N','.',' ','C','e','n','t','r','a','l',' ','A','s','i','a',' ','S','t', |
| 308 | 'a','n','d','a','r','d',' ','T','i','m','e','\0'}, -420, 1}, |
| 309 | {"BDT", |
| 310 | {'C','e','n','t','r','a','l',' ','A','s','i','a',' ','S','t','a','n','d', |
| 311 | 'a','r','d',' ','T','i','m','e','\0'}, -360, 0}, |
| 312 | {"LKT", |
| 313 | {'S','r','i',' ','L','a','n','k','a',' ','S','t','a','n','d','a','r','d', |
| 314 | ' ','T','i','m','e','\0'}, -360, 0}, |
| 315 | {"MMT", |
| 316 | {'M','y','a','n','m','a','r',' ','S','t','a','n','d','a','r','d',' ','T', |
| 317 | 'i','m','e','\0'}, -390, 0}, |
| 318 | {"ICT", |
| 319 | {'S','E',' ','A','s','i','a',' ','S','t','a','n','d','a','r','d',' ','T', |
| 320 | 'i','m','e','\0'}, -420, 0}, |
Mike McCormack | 5b40551 | 2005-11-08 10:57:50 +0000 | [diff] [blame] | 321 | {"KRAT", |
| 322 | {'N','o','r','t','h',' ','A','s','i','a',' ','S','t','a','n','d','a','r', |
| 323 | 'd',' ','T','i','m','e',0}, -420, 0}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 324 | {"KRAST", |
| 325 | {'N','o','r','t','h',' ','A','s','i','a',' ','S','t','a','n','d','a','r', |
| 326 | 'd',' ','T','i','m','e','\0'}, -480, 1}, |
Mike McCormack | 5b40551 | 2005-11-08 10:57:50 +0000 | [diff] [blame] | 327 | {"IRKT", |
| 328 | {'N','o','r','t','h',' ','A','s','i','a',' ','E','a','s','t',' ','S','t', |
| 329 | 'a','n','d','a','r','d',' ','T','i','m','e',0}, -480, 0}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 330 | {"CST", |
| 331 | {'C','h','i','n','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m', |
| 332 | 'e','\0'}, -480, 0}, |
| 333 | {"IRKST", |
| 334 | {'N','o','r','t','h',' ','A','s','i','a',' ','E','a','s','t',' ','S','t', |
| 335 | 'a','n','d','a','r','d',' ','T','i','m','e','\0'}, -540, 1}, |
| 336 | {"SGT", |
| 337 | {'M','a','l','a','y',' ','P','e','n','i','n','s','u','l','a',' ','S','t', |
| 338 | 'a','n','d','a','r','d',' ','T','i','m','e','\0'}, -480, 0}, |
| 339 | {"WST", |
| 340 | {'W','.',' ','A','u','s','t','r','a','l','i','a',' ','S','t','a','n','d', |
| 341 | 'a','r','d',' ','T','i','m','e','\0'}, -480, 0}, |
Harry McNally | ca2c987 | 2007-01-10 20:49:53 +0900 | [diff] [blame] | 342 | {"WST", |
| 343 | {'W','.',' ','A','u','s','t','r','a','l','i','a',' ','S','u','m','m','e', |
| 344 | 'r',' ','T','i','m','e','\0'}, -540, 1}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 345 | {"JST", |
| 346 | {'T','o','k','y','o',' ','S','t','a','n','d','a','r','d',' ','T','i','m', |
| 347 | 'e','\0'}, -540, 0}, |
| 348 | {"KST", |
| 349 | {'K','o','r','e','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m', |
| 350 | 'e','\0'}, -540, 0}, |
| 351 | {"YAKST", |
| 352 | {'Y','a','k','u','t','s','k',' ','S','t','a','n','d','a','r','d',' ','T', |
| 353 | 'i','m','e','\0'}, -600, 1}, |
| 354 | {"CST", |
| 355 | {'C','e','n','.',' ','A','u','s','t','r','a','l','i','a',' ','S','t','a', |
| 356 | 'n','d','a','r','d',' ','T','i','m','e','\0'}, -570, 0}, |
Kieran Clancy | d1c7458 | 2005-11-03 13:21:23 +0000 | [diff] [blame] | 357 | {"CST", |
| 358 | {'C','e','n','.',' ','A','u','s','t','r','a','l','i','a',' ','D','a','y', |
| 359 | 'l','i','g','h','t',' ','T','i','m','e','\0'}, -630, 1}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 360 | {"EST", |
| 361 | {'E','.',' ','A','u','s','t','r','a','l','i','a',' ','S','t','a','n','d', |
| 362 | 'a','r','d',' ','T','i','m','e','\0'}, -600, 0}, |
Troy Rollo | 418853e | 2005-01-27 11:11:54 +0000 | [diff] [blame] | 363 | {"EST", |
| 364 | {'E','.',' ','A','u','s','t','r','a','l','i','a',' ','S','t','a','n','d', |
| 365 | 'a','r','d',' ','T','i','m','e','\0'}, -660, 1}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 366 | {"GST", |
| 367 | {'W','e','s','t',' ','P','a','c','i','f','i','c',' ','S','t','a','n','d', |
| 368 | 'a','r','d',' ','T','i','m','e','\0'}, -600, 0}, |
Mike McCormack | 5b40551 | 2005-11-08 10:57:50 +0000 | [diff] [blame] | 369 | {"VLAT", |
| 370 | {'V','l','a','d','i','v','o','s','t','o','k',' ','S','t','a','n','d','a', |
| 371 | 'r','d',' ','T','i','m','e',0}, -600, 0 }, |
| 372 | {"ChST", |
| 373 | {'W','e','s','t',' ','P','a','c','i','f','i','c',' ','S','t','a','n','d', |
| 374 | 'a','r','d',' ','T','i','m','e',0}, -600, 0}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 375 | {"VLAST", |
| 376 | {'V','l','a','d','i','v','o','s','t','o','k',' ','S','t','a','n','d','a', |
| 377 | 'r','d',' ','T','i','m','e','\0'}, -660, 1}, |
Mike McCormack | 5b40551 | 2005-11-08 10:57:50 +0000 | [diff] [blame] | 378 | {"MAGT", |
| 379 | {'C','e','n','t','r','a','l',' ','P','a','c','i','f','i','c',' ','S','t', |
| 380 | 'a','n','d','a','r','d',' ','T','i','m','e',0}, -660, 0}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 381 | {"MAGST", |
| 382 | {'C','e','n','t','r','a','l',' ','P','a','c','i','f','i','c',' ','S','t', |
| 383 | 'a','n','d','a','r','d',' ','T','i','m','e','\0'}, -720, 1}, |
| 384 | {"NZST", |
| 385 | {'N','e','w',' ','Z','e','a','l','a','n','d',' ','S','t','a','n','d','a', |
| 386 | 'r','d',' ','T','i','m','e','\0'}, -720, 0}, |
Darryl Dixon | aef6fe3 | 2005-02-22 14:49:59 +0000 | [diff] [blame] | 387 | {"NZDT", |
| 388 | {'N','e','w',' ','Z','e','a','l','a','n','d',' ','D','a','y','l','i','g', |
| 389 | 'h','t',' ','T','i','m','e','\0'}, -780, 1}, |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 390 | {"FJT", |
| 391 | {'F','i','j','i',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e', |
| 392 | '\0'}, -720, 0}, |
| 393 | {"TOT", |
| 394 | {'T','o','n','g','a',' ','S','t','a','n','d','a','r','d',' ','T','i','m', |
Alexander Yaworsky | ed92345 | 2004-11-21 15:34:28 +0000 | [diff] [blame] | 395 | 'e','\0'}, -780, 0}, |
| 396 | {"NOVT", |
Mike McCormack | 5b40551 | 2005-11-08 10:57:50 +0000 | [diff] [blame] | 397 | {'N','.',' ','C','e','n','t','r','a','l',' ','A','s','i','a',' ','S','t', |
| 398 | 'a','n','d','a','r','d',' ','T','i','m','e',0 }, -360, 0}, |
| 399 | {"NOVT", |
Alexander Yaworsky | ed92345 | 2004-11-21 15:34:28 +0000 | [diff] [blame] | 400 | {'N','o','v','o','s','i','b','i','r','s','k',' ','S','t','a','n','d','a', |
Rustam Chernotkach | 1283bd9 | 2005-03-22 18:17:31 +0000 | [diff] [blame] | 401 | 'r','d',' ','T','i','m','e','\0'}, -360, 1}, |
| 402 | {"ANAT", |
| 403 | {'A','n','a','d','y','r',' ','S','t','a','n','d','a','r','d',' ','T','i', |
Ivan Wong | bf8f93d | 2005-05-04 09:45:48 +0000 | [diff] [blame] | 404 | 'm','e','\0'}, -720, 1}, |
| 405 | {"HKT", |
| 406 | {'H','o','n','g',' ','K','o','n','g',' ','S','t','a','n','d','a','r','d', |
Gabriel Gambetta | fd62fcf | 2005-05-12 09:54:39 +0000 | [diff] [blame] | 407 | ' ','T','i','m','e','\0'}, -480, 0}, |
| 408 | {"UYT", |
Vijay Kiran Kamuju | bb53d09 | 2005-09-26 09:55:59 +0000 | [diff] [blame] | 409 | {'U','r','u','g','u','a','y','a','n',' ','T','i','m','e','\0'}, 180, 0}, |
Gabriel Gambetta | cc578af | 2007-03-25 14:33:20 -0300 | [diff] [blame] | 410 | {"UYST", |
| 411 | {'U','r','u','g','u','a','y','a','n',' ','S','u','m','m','e','r',' ','T', |
| 412 | 'i','m','e','\0'}, 120, 1}, |
Vijay Kiran Kamuju | bb53d09 | 2005-09-26 09:55:59 +0000 | [diff] [blame] | 413 | {"MYT", |
| 414 | {'M','a','l','a','y','s','i','a','n',' ','T','i','m','e','\0'}, -480, 0}, |
Vijay Kiran Kamuju | e573caf | 2005-10-10 18:03:56 +0000 | [diff] [blame] | 415 | {"PHT", |
| 416 | {'P','h','i','l','i','p','p','i','n','e',' ','T','i','m','e','\0'}, -480, 0}, |
Vijay Kiran Kamuju | bb53d09 | 2005-09-26 09:55:59 +0000 | [diff] [blame] | 417 | {"NOVST", |
| 418 | {'N','o','v','o','s','i','b','i','r','s','k',' ','S','u','m','m','e','r', |
Alexey Markachev | 160f1c3 | 2007-04-26 13:03:55 +0400 | [diff] [blame] | 419 | ' ','T','i','m','e','\0'}, -420, 1}, |
Lei Zhang | 9ee4d85 | 2007-07-29 22:01:56 -0700 | [diff] [blame] | 420 | {"BOT", |
| 421 | {'B','o','l','i','v','i','a','n',' ','T','i','m','e','\0'}, 240, 0}, |
Vijay Kiran Kamuju | ee87f03 | 2006-06-23 12:42:05 -0400 | [diff] [blame] | 422 | {"UZT", |
| 423 | {'U','z','b','e','k','i','s','t','h','a','n',' ','T','i','m','e','\0'}, -300, 0} |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 424 | }; |
| 425 | |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 426 | #define TICKSPERSEC 10000000 |
| 427 | #define TICKSPERMSEC 10000 |
| 428 | #define SECSPERDAY 86400 |
| 429 | #define SECSPERHOUR 3600 |
| 430 | #define SECSPERMIN 60 |
| 431 | #define MINSPERHOUR 60 |
| 432 | #define HOURSPERDAY 24 |
Alexandre Julliard | dcc3afd | 2002-12-13 20:53:04 +0000 | [diff] [blame] | 433 | #define EPOCHWEEKDAY 1 /* Jan 1, 1601 was Monday */ |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 434 | #define DAYSPERWEEK 7 |
| 435 | #define EPOCHYEAR 1601 |
| 436 | #define DAYSPERNORMALYEAR 365 |
| 437 | #define DAYSPERLEAPYEAR 366 |
| 438 | #define MONSPERYEAR 12 |
Huw Davies | 166faa4 | 2004-02-24 01:01:27 +0000 | [diff] [blame] | 439 | #define DAYSPERQUADRICENTENNIUM (365 * 400 + 97) |
| 440 | #define DAYSPERNORMALCENTURY (365 * 100 + 24) |
| 441 | #define DAYSPERNORMALQUADRENNIUM (365 * 4 + 1) |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 442 | |
Alexandre Julliard | d76f9f9 | 2000-10-01 01:40:42 +0000 | [diff] [blame] | 443 | /* 1601 to 1970 is 369 years plus 89 leap days */ |
Alexandre Julliard | fbef57c | 2003-03-31 01:37:04 +0000 | [diff] [blame] | 444 | #define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY) |
| 445 | #define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC) |
Alexandre Julliard | d76f9f9 | 2000-10-01 01:40:42 +0000 | [diff] [blame] | 446 | /* 1601 to 1980 is 379 years plus 91 leap days */ |
Alexandre Julliard | fbef57c | 2003-03-31 01:37:04 +0000 | [diff] [blame] | 447 | #define SECS_1601_TO_1980 ((379 * 365 + 91) * (ULONGLONG)SECSPERDAY) |
| 448 | #define TICKS_1601_TO_1980 (SECS_1601_TO_1980 * TICKSPERSEC) |
Alexandre Julliard | 25b23a0 | 2004-09-07 23:01:34 +0000 | [diff] [blame] | 449 | /* max ticks that can be represented as Unix time */ |
| 450 | #define TICKS_1601_TO_UNIX_MAX ((SECS_1601_TO_1970 + INT_MAX) * TICKSPERSEC) |
Alexandre Julliard | d76f9f9 | 2000-10-01 01:40:42 +0000 | [diff] [blame] | 451 | |
| 452 | |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 453 | static const int MonthLengths[2][MONSPERYEAR] = |
| 454 | { |
| 455 | { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, |
| 456 | { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } |
| 457 | }; |
| 458 | |
Patrik Stridvall | 896889f | 1999-05-08 12:50:36 +0000 | [diff] [blame] | 459 | static inline int IsLeapYear(int Year) |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 460 | { |
| 461 | return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 1 : 0; |
| 462 | } |
| 463 | |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 464 | /****************************************************************************** |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 465 | * RtlTimeToTimeFields [NTDLL.@] |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 466 | * |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 467 | * Convert a time into a TIME_FIELDS structure. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 468 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 469 | * PARAMS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 470 | * liTime [I] Time to convert. |
| 471 | * TimeFields [O] Destination for the converted time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 472 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 473 | * RETURNS |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 474 | * Nothing. |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 475 | */ |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 476 | VOID WINAPI RtlTimeToTimeFields( |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 477 | const LARGE_INTEGER *liTime, |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 478 | PTIME_FIELDS TimeFields) |
| 479 | { |
Rein Klazes | dceae02 | 2004-11-06 03:53:53 +0000 | [diff] [blame] | 480 | int SecondsInDay; |
| 481 | long int cleaps, years, yearday, months; |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 482 | long int Days; |
Rein Klazes | dceae02 | 2004-11-06 03:53:53 +0000 | [diff] [blame] | 483 | LONGLONG Time; |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 484 | |
| 485 | /* Extract millisecond from time and convert time into seconds */ |
Rein Klazes | dceae02 | 2004-11-06 03:53:53 +0000 | [diff] [blame] | 486 | TimeFields->Milliseconds = |
| 487 | (CSHORT) (( liTime->QuadPart % TICKSPERSEC) / TICKSPERMSEC); |
| 488 | Time = liTime->QuadPart / TICKSPERSEC; |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 489 | |
György 'Nog' Jeney | 39433b9 | 2002-11-06 21:57:23 +0000 | [diff] [blame] | 490 | /* The native version of RtlTimeToTimeFields does not take leap seconds |
| 491 | * into account */ |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 492 | |
| 493 | /* Split the time into days and seconds within the day */ |
| 494 | Days = Time / SECSPERDAY; |
| 495 | SecondsInDay = Time % SECSPERDAY; |
| 496 | |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 497 | /* compute time of day */ |
| 498 | TimeFields->Hour = (CSHORT) (SecondsInDay / SECSPERHOUR); |
| 499 | SecondsInDay = SecondsInDay % SECSPERHOUR; |
| 500 | TimeFields->Minute = (CSHORT) (SecondsInDay / SECSPERMIN); |
| 501 | TimeFields->Second = (CSHORT) (SecondsInDay % SECSPERMIN); |
| 502 | |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 503 | /* compute day of week */ |
| 504 | TimeFields->Weekday = (CSHORT) ((EPOCHWEEKDAY + Days) % DAYSPERWEEK); |
| 505 | |
Rein Klazes | dceae02 | 2004-11-06 03:53:53 +0000 | [diff] [blame] | 506 | /* compute year, month and day of month. */ |
| 507 | cleaps=( 3 * ((4 * Days + 1227) / DAYSPERQUADRICENTENNIUM) + 3 ) / 4; |
| 508 | Days += 28188 + cleaps; |
| 509 | years = (20 * Days - 2442) / (5 * DAYSPERNORMALQUADRENNIUM); |
| 510 | yearday = Days - (years * DAYSPERNORMALQUADRENNIUM)/4; |
| 511 | months = (64 * yearday) / 1959; |
| 512 | /* the result is based on a year starting on March. |
| 513 | * To convert take 12 from Januari and Februari and |
| 514 | * increase the year by one. */ |
| 515 | if( months < 14 ) { |
| 516 | TimeFields->Month = months - 1; |
| 517 | TimeFields->Year = years + 1524; |
| 518 | } else { |
| 519 | TimeFields->Month = months - 13; |
| 520 | TimeFields->Year = years + 1525; |
| 521 | } |
| 522 | /* calculation of day of month is based on the wonderful |
| 523 | * sequence of INT( n * 30.6): it reproduces the |
| 524 | * 31-30-31-30-31-31 month lengths exactly for small n's */ |
| 525 | TimeFields->Day = yearday - (1959 * months) / 64 ; |
| 526 | return; |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 527 | } |
György 'Nog' Jeney | 39433b9 | 2002-11-06 21:57:23 +0000 | [diff] [blame] | 528 | |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 529 | /****************************************************************************** |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 530 | * RtlTimeFieldsToTime [NTDLL.@] |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 531 | * |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 532 | * Convert a TIME_FIELDS structure into a time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 533 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 534 | * PARAMS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 535 | * ftTimeFields [I] TIME_FIELDS structure to convert. |
| 536 | * Time [O] Destination for the converted time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 537 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 538 | * RETURNS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 539 | * Success: TRUE. |
| 540 | * Failure: FALSE. |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 541 | */ |
| 542 | BOOLEAN WINAPI RtlTimeFieldsToTime( |
| 543 | PTIME_FIELDS tfTimeFields, |
| 544 | PLARGE_INTEGER Time) |
| 545 | { |
Rein Klazes | dceae02 | 2004-11-06 03:53:53 +0000 | [diff] [blame] | 546 | int month, year, cleaps, day; |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 547 | |
| 548 | /* FIXME: normalize the TIME_FIELDS structure here */ |
Rein Klazes | dceae02 | 2004-11-06 03:53:53 +0000 | [diff] [blame] | 549 | /* No, native just returns 0 (error) if the fields are not */ |
| 550 | if( tfTimeFields->Milliseconds< 0 || tfTimeFields->Milliseconds > 999 || |
| 551 | tfTimeFields->Second < 0 || tfTimeFields->Second > 59 || |
| 552 | tfTimeFields->Minute < 0 || tfTimeFields->Minute > 59 || |
| 553 | tfTimeFields->Hour < 0 || tfTimeFields->Hour > 23 || |
| 554 | tfTimeFields->Month < 1 || tfTimeFields->Month > 12 || |
| 555 | tfTimeFields->Day < 1 || |
| 556 | tfTimeFields->Day > MonthLengths |
| 557 | [ tfTimeFields->Month ==2 || IsLeapYear(tfTimeFields->Year)] |
| 558 | [ tfTimeFields->Month - 1] || |
| 559 | tfTimeFields->Year < 1601 ) |
| 560 | return FALSE; |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 561 | |
Rein Klazes | dceae02 | 2004-11-06 03:53:53 +0000 | [diff] [blame] | 562 | /* now calculate a day count from the date |
| 563 | * First start counting years from March. This way the leap days |
| 564 | * are added at the end of the year, not somewhere in the middle. |
| 565 | * Formula's become so much less complicate that way. |
| 566 | * To convert: add 12 to the month numbers of Jan and Feb, and |
| 567 | * take 1 from the year */ |
| 568 | if(tfTimeFields->Month < 3) { |
| 569 | month = tfTimeFields->Month + 13; |
| 570 | year = tfTimeFields->Year - 1; |
| 571 | } else { |
| 572 | month = tfTimeFields->Month + 1; |
| 573 | year = tfTimeFields->Year; |
| 574 | } |
| 575 | cleaps = (3 * (year / 100) + 3) / 4; /* nr of "century leap years"*/ |
| 576 | day = (36525 * year) / 100 - cleaps + /* year * dayperyr, corrected */ |
| 577 | (1959 * month) / 64 + /* months * daypermonth */ |
| 578 | tfTimeFields->Day - /* day of the month */ |
| 579 | 584817 ; /* zero that on 1601-01-01 */ |
| 580 | /* done */ |
| 581 | |
| 582 | Time->QuadPart = (((((LONGLONG) day * HOURSPERDAY + |
| 583 | tfTimeFields->Hour) * MINSPERHOUR + |
| 584 | tfTimeFields->Minute) * SECSPERMIN + |
| 585 | tfTimeFields->Second ) * 1000 + |
| 586 | tfTimeFields->Milliseconds ) * TICKSPERMSEC; |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 587 | |
Rein Klazes | dceae02 | 2004-11-06 03:53:53 +0000 | [diff] [blame] | 588 | return TRUE; |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 589 | } |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 590 | |
Huw Davies | 64ed848 | 2004-02-26 05:26:34 +0000 | [diff] [blame] | 591 | /*********************************************************************** |
| 592 | * TIME_GetBias [internal] |
| 593 | * |
| 594 | * Helper function calculates delta local time from UTC. |
| 595 | * |
| 596 | * PARAMS |
| 597 | * utc [I] The current utc time. |
| 598 | * pdaylight [I] Local daylight. |
| 599 | * |
| 600 | * RETURNS |
| 601 | * The bias for the current timezone. |
| 602 | */ |
| 603 | static int TIME_GetBias(time_t utc, int *pdaylight) |
| 604 | { |
Huw Davies | 67e2d6c | 2004-02-27 00:43:20 +0000 | [diff] [blame] | 605 | struct tm *ptm; |
| 606 | static time_t last_utc; |
| 607 | static int last_bias; |
Rein Klazes | 5040309 | 2004-03-01 21:23:18 +0000 | [diff] [blame] | 608 | static int last_daylight; |
Huw Davies | 67e2d6c | 2004-02-27 00:43:20 +0000 | [diff] [blame] | 609 | int ret; |
| 610 | |
| 611 | RtlEnterCriticalSection( &TIME_GetBias_section ); |
Dmitry Timoshkov | 6119f49 | 2007-07-29 21:33:23 +0900 | [diff] [blame] | 612 | if (utc != last_utc) |
Huw Davies | 67e2d6c | 2004-02-27 00:43:20 +0000 | [diff] [blame] | 613 | { |
| 614 | ptm = localtime(&utc); |
Dmitry Timoshkov | 6119f49 | 2007-07-29 21:33:23 +0900 | [diff] [blame] | 615 | last_daylight = ptm->tm_isdst; /* daylight for local timezone */ |
Huw Davies | 67e2d6c | 2004-02-27 00:43:20 +0000 | [diff] [blame] | 616 | ptm = gmtime(&utc); |
Dmitry Timoshkov | 6119f49 | 2007-07-29 21:33:23 +0900 | [diff] [blame] | 617 | ptm->tm_isdst = last_daylight; /* use local daylight, not that of Greenwich */ |
Huw Davies | 67e2d6c | 2004-02-27 00:43:20 +0000 | [diff] [blame] | 618 | last_utc = utc; |
Dmitry Timoshkov | 6119f49 | 2007-07-29 21:33:23 +0900 | [diff] [blame] | 619 | last_bias = (int)(utc - mktime(ptm)); |
Huw Davies | 67e2d6c | 2004-02-27 00:43:20 +0000 | [diff] [blame] | 620 | } |
Dmitry Timoshkov | 6119f49 | 2007-07-29 21:33:23 +0900 | [diff] [blame] | 621 | |
| 622 | *pdaylight = last_daylight; |
| 623 | ret = last_bias; |
| 624 | |
Huw Davies | 67e2d6c | 2004-02-27 00:43:20 +0000 | [diff] [blame] | 625 | RtlLeaveCriticalSection( &TIME_GetBias_section ); |
| 626 | return ret; |
Huw Davies | 64ed848 | 2004-02-26 05:26:34 +0000 | [diff] [blame] | 627 | } |
| 628 | |
György 'Nog' Jeney | 4d6ba25 | 2002-12-11 00:19:56 +0000 | [diff] [blame] | 629 | /****************************************************************************** |
| 630 | * RtlLocalTimeToSystemTime [NTDLL.@] |
| 631 | * |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 632 | * Convert a local time into system time. |
György 'Nog' Jeney | 4d6ba25 | 2002-12-11 00:19:56 +0000 | [diff] [blame] | 633 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 634 | * PARAMS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 635 | * LocalTime [I] Local time to convert. |
| 636 | * SystemTime [O] Destination for the converted time. |
György 'Nog' Jeney | 4d6ba25 | 2002-12-11 00:19:56 +0000 | [diff] [blame] | 637 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 638 | * RETURNS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 639 | * Success: STATUS_SUCCESS. |
| 640 | * Failure: An NTSTATUS error code indicating the problem. |
György 'Nog' Jeney | 4d6ba25 | 2002-12-11 00:19:56 +0000 | [diff] [blame] | 641 | */ |
| 642 | NTSTATUS WINAPI RtlLocalTimeToSystemTime( const LARGE_INTEGER *LocalTime, |
| 643 | PLARGE_INTEGER SystemTime) |
| 644 | { |
Huw Davies | 64ed848 | 2004-02-26 05:26:34 +0000 | [diff] [blame] | 645 | time_t gmt; |
| 646 | int bias, daylight; |
György 'Nog' Jeney | 4d6ba25 | 2002-12-11 00:19:56 +0000 | [diff] [blame] | 647 | |
| 648 | TRACE("(%p, %p)\n", LocalTime, SystemTime); |
| 649 | |
Huw Davies | 64ed848 | 2004-02-26 05:26:34 +0000 | [diff] [blame] | 650 | gmt = time(NULL); |
| 651 | bias = TIME_GetBias(gmt, &daylight); |
| 652 | |
Robert Shearman | abf2de2 | 2005-02-08 12:13:36 +0000 | [diff] [blame] | 653 | SystemTime->QuadPart = LocalTime->QuadPart - bias * (LONGLONG)TICKSPERSEC; |
György 'Nog' Jeney | 4d6ba25 | 2002-12-11 00:19:56 +0000 | [diff] [blame] | 654 | return STATUS_SUCCESS; |
| 655 | } |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 656 | |
| 657 | /****************************************************************************** |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 658 | * RtlSystemTimeToLocalTime [NTDLL.@] |
| 659 | * |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 660 | * Convert a system time into a local time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 661 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 662 | * PARAMS |
| 663 | * SystemTime [I] System time to convert. |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 664 | * LocalTime [O] Destination for the converted time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 665 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 666 | * RETURNS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 667 | * Success: STATUS_SUCCESS. |
| 668 | * Failure: An NTSTATUS error code indicating the problem. |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 669 | */ |
György 'Nog' Jeney | 4d6ba25 | 2002-12-11 00:19:56 +0000 | [diff] [blame] | 670 | NTSTATUS WINAPI RtlSystemTimeToLocalTime( const LARGE_INTEGER *SystemTime, |
| 671 | PLARGE_INTEGER LocalTime ) |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 672 | { |
Huw Davies | 64ed848 | 2004-02-26 05:26:34 +0000 | [diff] [blame] | 673 | time_t gmt; |
| 674 | int bias, daylight; |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 675 | |
György 'Nog' Jeney | 4d6ba25 | 2002-12-11 00:19:56 +0000 | [diff] [blame] | 676 | TRACE("(%p, %p)\n", SystemTime, LocalTime); |
| 677 | |
Huw Davies | 64ed848 | 2004-02-26 05:26:34 +0000 | [diff] [blame] | 678 | gmt = time(NULL); |
| 679 | bias = TIME_GetBias(gmt, &daylight); |
| 680 | |
Robert Shearman | abf2de2 | 2005-02-08 12:13:36 +0000 | [diff] [blame] | 681 | LocalTime->QuadPart = SystemTime->QuadPart + bias * (LONGLONG)TICKSPERSEC; |
György 'Nog' Jeney | 4d6ba25 | 2002-12-11 00:19:56 +0000 | [diff] [blame] | 682 | return STATUS_SUCCESS; |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 683 | } |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 684 | |
| 685 | /****************************************************************************** |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 686 | * RtlTimeToSecondsSince1970 [NTDLL.@] |
| 687 | * |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 688 | * Convert a time into a count of seconds since 1970. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 689 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 690 | * PARAMS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 691 | * Time [I] Time to convert. |
| 692 | * Seconds [O] Destination for the converted time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 693 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 694 | * RETURNS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 695 | * Success: TRUE. |
| 696 | * Failure: FALSE, if the resulting value will not fit in a DWORD. |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 697 | */ |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 698 | BOOLEAN WINAPI RtlTimeToSecondsSince1970( const LARGE_INTEGER *Time, LPDWORD Seconds ) |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 699 | { |
Ge van Geldorp | 399901e | 2004-01-23 01:51:33 +0000 | [diff] [blame] | 700 | ULONGLONG tmp = ((ULONGLONG)Time->u.HighPart << 32) | Time->u.LowPart; |
Robert Shearman | abf2de2 | 2005-02-08 12:13:36 +0000 | [diff] [blame] | 701 | tmp = RtlLargeIntegerDivide( tmp, TICKSPERSEC, NULL ); |
Alexandre Julliard | d76f9f9 | 2000-10-01 01:40:42 +0000 | [diff] [blame] | 702 | tmp -= SECS_1601_TO_1970; |
| 703 | if (tmp > 0xffffffff) return FALSE; |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 704 | *Seconds = (DWORD)tmp; |
Alexandre Julliard | 0aa6cc2 | 2000-07-29 21:56:59 +0000 | [diff] [blame] | 705 | return TRUE; |
| 706 | } |
| 707 | |
| 708 | /****************************************************************************** |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 709 | * RtlTimeToSecondsSince1980 [NTDLL.@] |
| 710 | * |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 711 | * Convert a time into a count of seconds since 1980. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 712 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 713 | * PARAMS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 714 | * Time [I] Time to convert. |
| 715 | * Seconds [O] Destination for the converted time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 716 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 717 | * RETURNS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 718 | * Success: TRUE. |
| 719 | * Failure: FALSE, if the resulting value will not fit in a DWORD. |
Alexandre Julliard | 0aa6cc2 | 2000-07-29 21:56:59 +0000 | [diff] [blame] | 720 | */ |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 721 | BOOLEAN WINAPI RtlTimeToSecondsSince1980( const LARGE_INTEGER *Time, LPDWORD Seconds ) |
Alexandre Julliard | 0aa6cc2 | 2000-07-29 21:56:59 +0000 | [diff] [blame] | 722 | { |
Ge van Geldorp | 399901e | 2004-01-23 01:51:33 +0000 | [diff] [blame] | 723 | ULONGLONG tmp = ((ULONGLONG)Time->u.HighPart << 32) | Time->u.LowPart; |
Robert Shearman | abf2de2 | 2005-02-08 12:13:36 +0000 | [diff] [blame] | 724 | tmp = RtlLargeIntegerDivide( tmp, TICKSPERSEC, NULL ); |
Alexandre Julliard | fbef57c | 2003-03-31 01:37:04 +0000 | [diff] [blame] | 725 | tmp -= SECS_1601_TO_1980; |
Alexandre Julliard | d76f9f9 | 2000-10-01 01:40:42 +0000 | [diff] [blame] | 726 | if (tmp > 0xffffffff) return FALSE; |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 727 | *Seconds = (DWORD)tmp; |
Alexandre Julliard | 0aa6cc2 | 2000-07-29 21:56:59 +0000 | [diff] [blame] | 728 | return TRUE; |
| 729 | } |
| 730 | |
| 731 | /****************************************************************************** |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 732 | * RtlSecondsSince1970ToTime [NTDLL.@] |
| 733 | * |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 734 | * Convert a count of seconds since 1970 to a time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 735 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 736 | * PARAMS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 737 | * Seconds [I] Time to convert. |
| 738 | * Time [O] Destination for the converted time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 739 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 740 | * RETURNS |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 741 | * Nothing. |
Alexandre Julliard | 0aa6cc2 | 2000-07-29 21:56:59 +0000 | [diff] [blame] | 742 | */ |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 743 | void WINAPI RtlSecondsSince1970ToTime( DWORD Seconds, LARGE_INTEGER *Time ) |
Alexandre Julliard | 0aa6cc2 | 2000-07-29 21:56:59 +0000 | [diff] [blame] | 744 | { |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 745 | ULONGLONG secs = Seconds * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; |
Ge van Geldorp | 399901e | 2004-01-23 01:51:33 +0000 | [diff] [blame] | 746 | Time->u.LowPart = (DWORD)secs; |
| 747 | Time->u.HighPart = (DWORD)(secs >> 32); |
Alexandre Julliard | 0aa6cc2 | 2000-07-29 21:56:59 +0000 | [diff] [blame] | 748 | } |
| 749 | |
| 750 | /****************************************************************************** |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 751 | * RtlSecondsSince1980ToTime [NTDLL.@] |
| 752 | * |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 753 | * Convert a count of seconds since 1980 to a time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 754 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 755 | * PARAMS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 756 | * Seconds [I] Time to convert. |
| 757 | * Time [O] Destination for the converted time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 758 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 759 | * RETURNS |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 760 | * Nothing. |
Alexandre Julliard | 0aa6cc2 | 2000-07-29 21:56:59 +0000 | [diff] [blame] | 761 | */ |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 762 | void WINAPI RtlSecondsSince1980ToTime( DWORD Seconds, LARGE_INTEGER *Time ) |
Alexandre Julliard | 0aa6cc2 | 2000-07-29 21:56:59 +0000 | [diff] [blame] | 763 | { |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 764 | ULONGLONG secs = Seconds * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1980; |
Ge van Geldorp | 399901e | 2004-01-23 01:51:33 +0000 | [diff] [blame] | 765 | Time->u.LowPart = (DWORD)secs; |
| 766 | Time->u.HighPart = (DWORD)(secs >> 32); |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 767 | } |
| 768 | |
| 769 | /****************************************************************************** |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 770 | * RtlTimeToElapsedTimeFields [NTDLL.@] |
| 771 | * |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 772 | * Convert a time to a count of elapsed seconds. |
| 773 | * |
| 774 | * PARAMS |
| 775 | * Time [I] Time to convert. |
| 776 | * TimeFields [O] Destination for the converted time. |
| 777 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 778 | * RETURNS |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 779 | * Nothing. |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 780 | */ |
Alexandre Julliard | a16ed90 | 2002-12-18 02:31:33 +0000 | [diff] [blame] | 781 | void WINAPI RtlTimeToElapsedTimeFields( const LARGE_INTEGER *Time, PTIME_FIELDS TimeFields ) |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 782 | { |
Alexandre Julliard | a16ed90 | 2002-12-18 02:31:33 +0000 | [diff] [blame] | 783 | LONGLONG time; |
Mike McCormack | b5bd4a1 | 2005-09-02 14:47:36 +0000 | [diff] [blame] | 784 | INT rem; |
Alexandre Julliard | a16ed90 | 2002-12-18 02:31:33 +0000 | [diff] [blame] | 785 | |
| 786 | time = RtlExtendedLargeIntegerDivide( Time->QuadPart, TICKSPERSEC, &rem ); |
| 787 | TimeFields->Milliseconds = rem / TICKSPERMSEC; |
| 788 | |
| 789 | /* time is now in seconds */ |
| 790 | TimeFields->Year = 0; |
| 791 | TimeFields->Month = 0; |
| 792 | TimeFields->Day = RtlExtendedLargeIntegerDivide( time, SECSPERDAY, &rem ); |
| 793 | |
| 794 | /* rem is now the remaining seconds in the last day */ |
| 795 | TimeFields->Second = rem % 60; |
| 796 | rem /= 60; |
| 797 | TimeFields->Minute = rem % 60; |
| 798 | TimeFields->Hour = rem / 60; |
Juergen Schmied | 026d9db | 1999-03-09 17:47:51 +0000 | [diff] [blame] | 799 | } |
Alexandre Julliard | d76f9f9 | 2000-10-01 01:40:42 +0000 | [diff] [blame] | 800 | |
| 801 | /*********************************************************************** |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 802 | * NtQuerySystemTime [NTDLL.@] |
| 803 | * ZwQuerySystemTime [NTDLL.@] |
| 804 | * |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 805 | * Get the current system time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 806 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 807 | * PARAMS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 808 | * Time [O] Destination for the current system time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 809 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 810 | * RETURNS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 811 | * Success: STATUS_SUCCESS. |
| 812 | * Failure: An NTSTATUS error code indicating the problem. |
Alexandre Julliard | d76f9f9 | 2000-10-01 01:40:42 +0000 | [diff] [blame] | 813 | */ |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 814 | NTSTATUS WINAPI NtQuerySystemTime( PLARGE_INTEGER Time ) |
Alexandre Julliard | d76f9f9 | 2000-10-01 01:40:42 +0000 | [diff] [blame] | 815 | { |
Alexandre Julliard | d76f9f9 | 2000-10-01 01:40:42 +0000 | [diff] [blame] | 816 | struct timeval now; |
| 817 | |
| 818 | gettimeofday( &now, 0 ); |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 819 | Time->QuadPart = now.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; |
| 820 | Time->QuadPart += now.tv_usec * 10; |
Patrik Stridvall | 9c1de6d | 2002-09-12 22:07:02 +0000 | [diff] [blame] | 821 | return STATUS_SUCCESS; |
Alexandre Julliard | d76f9f9 | 2000-10-01 01:40:42 +0000 | [diff] [blame] | 822 | } |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 823 | |
Alexandre Julliard | 9ad5628 | 2005-07-14 10:32:46 +0000 | [diff] [blame] | 824 | /****************************************************************************** |
| 825 | * NtQueryPerformanceCounter [NTDLL.@] |
| 826 | * |
| 827 | * Note: Windows uses a timer clocked at a multiple of 1193182 Hz. There is a |
| 828 | * good number of applications that crash when the returned frequency is either |
Francois Gouget | ebadbd4 | 2007-08-09 10:42:59 +0200 | [diff] [blame^] | 829 | * lower or higher than what Windows gives. Also too high counter values are |
Alexandre Julliard | 9ad5628 | 2005-07-14 10:32:46 +0000 | [diff] [blame] | 830 | * reported to give problems. |
| 831 | */ |
| 832 | NTSTATUS WINAPI NtQueryPerformanceCounter( PLARGE_INTEGER Counter, PLARGE_INTEGER Frequency ) |
| 833 | { |
Alexandre Julliard | aaf477f | 2007-04-17 20:08:59 +0200 | [diff] [blame] | 834 | LARGE_INTEGER now; |
Alexandre Julliard | 9ad5628 | 2005-07-14 10:32:46 +0000 | [diff] [blame] | 835 | |
| 836 | if (!Counter) return STATUS_ACCESS_VIOLATION; |
Alexandre Julliard | aaf477f | 2007-04-17 20:08:59 +0200 | [diff] [blame] | 837 | |
| 838 | /* convert a counter that increments at a rate of 10 MHz |
Alexandre Julliard | 9ad5628 | 2005-07-14 10:32:46 +0000 | [diff] [blame] | 839 | * to one of 1.193182 MHz, with some care for arithmetic |
Alexandre Julliard | aaf477f | 2007-04-17 20:08:59 +0200 | [diff] [blame] | 840 | * overflow and good accuracy (21/176 = 0.11931818) */ |
| 841 | NtQuerySystemTime( &now ); |
| 842 | Counter->QuadPart = ((now.QuadPart - server_start_time) * 21) / 176; |
Alexandre Julliard | 9ad5628 | 2005-07-14 10:32:46 +0000 | [diff] [blame] | 843 | if (Frequency) Frequency->QuadPart = 1193182; |
| 844 | return STATUS_SUCCESS; |
| 845 | } |
| 846 | |
Jacek Caban | 2333c80 | 2006-04-19 21:21:52 +0200 | [diff] [blame] | 847 | |
| 848 | /****************************************************************************** |
| 849 | * NtGetTickCount (NTDLL.@) |
| 850 | * ZwGetTickCount (NTDLL.@) |
| 851 | */ |
| 852 | ULONG WINAPI NtGetTickCount(void) |
| 853 | { |
Alexandre Julliard | aaf477f | 2007-04-17 20:08:59 +0200 | [diff] [blame] | 854 | LARGE_INTEGER now; |
Jacek Caban | 2333c80 | 2006-04-19 21:21:52 +0200 | [diff] [blame] | 855 | |
Alexandre Julliard | aaf477f | 2007-04-17 20:08:59 +0200 | [diff] [blame] | 856 | NtQuerySystemTime( &now ); |
| 857 | return (now.QuadPart - server_start_time) / 10000; |
Jacek Caban | 2333c80 | 2006-04-19 21:21:52 +0200 | [diff] [blame] | 858 | } |
| 859 | |
| 860 | |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 861 | /*********************************************************************** |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 862 | * TIME_GetTZAsStr [internal] |
| 863 | * |
| 864 | * Helper function that returns the given timezone as a string. |
| 865 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 866 | * PARAMS |
| 867 | * utc [I] The current utc time. |
| 868 | * bias [I] The bias of the current timezone. |
| 869 | * dst [I] ?? |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 870 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 871 | * RETURNS |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 872 | * Timezone name. |
| 873 | * |
| 874 | * NOTES: |
| 875 | * This could be done with a hash table instead of merely iterating through a |
| 876 | * table, however with the small amount of entries (60 or so) I didn't think |
| 877 | * it was worth it. |
| 878 | */ |
| 879 | static const WCHAR* TIME_GetTZAsStr (time_t utc, int bias, int dst) |
| 880 | { |
| 881 | char psTZName[7]; |
| 882 | struct tm *ptm = localtime(&utc); |
Hans Leidekker | a9b4a47 | 2004-08-13 23:53:44 +0000 | [diff] [blame] | 883 | unsigned int i; |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 884 | |
| 885 | if (!strftime (psTZName, 7, "%Z", ptm)) |
Dmitry Timoshkov | a188662 | 2007-07-29 21:31:00 +0900 | [diff] [blame] | 886 | { |
| 887 | WARN("strftime error %d\n", errno); |
| 888 | return NULL; |
| 889 | } |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 890 | |
| 891 | for (i=0; i<(sizeof(TZ_INFO) / sizeof(struct tagTZ_INFO)); i++) |
| 892 | { |
| 893 | if ( strcmp(TZ_INFO[i].psTZFromUnix, psTZName) == 0 && |
| 894 | TZ_INFO[i].bias == bias && |
| 895 | TZ_INFO[i].dst == dst |
| 896 | ) |
| 897 | return TZ_INFO[i].psTZWindows; |
| 898 | } |
Marcelo Duarte | 37bc441 | 2005-02-14 11:03:05 +0000 | [diff] [blame] | 899 | FIXME("Can't match system time zone name \"%s\", bias=%d and dst=%d " |
| 900 | "to an entry in TZ_INFO. Please add appropriate entry to " |
| 901 | "TZ_INFO and submit as patch to wine-patches\n",psTZName,bias,dst); |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 902 | return NULL; |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 903 | } |
| 904 | |
Rein Klazes | c5c93d1 | 2004-10-18 21:19:28 +0000 | [diff] [blame] | 905 | /*** TIME_GetTimeZoneInfoFromReg: helper for GetTimeZoneInformation ***/ |
| 906 | |
| 907 | |
Mike McCormack | 78911f3 | 2005-06-20 18:37:17 +0000 | [diff] [blame] | 908 | static int TIME_GetTimeZoneInfoFromReg(RTL_TIME_ZONE_INFORMATION *tzinfo) |
Rein Klazes | c5c93d1 | 2004-10-18 21:19:28 +0000 | [diff] [blame] | 909 | { |
| 910 | BYTE buf[90]; |
| 911 | KEY_VALUE_PARTIAL_INFORMATION * KpInfo = |
| 912 | (KEY_VALUE_PARTIAL_INFORMATION *) buf; |
Mike McCormack | 5b2d5fd | 2005-06-17 13:58:33 +0000 | [diff] [blame] | 913 | HANDLE hkey; |
Rein Klazes | c5c93d1 | 2004-10-18 21:19:28 +0000 | [diff] [blame] | 914 | DWORD size; |
| 915 | OBJECT_ATTRIBUTES attr; |
| 916 | UNICODE_STRING nameW; |
| 917 | |
| 918 | attr.Length = sizeof(attr); |
| 919 | attr.RootDirectory = 0; |
| 920 | attr.ObjectName = &nameW; |
| 921 | attr.Attributes = 0; |
| 922 | attr.SecurityDescriptor = NULL; |
| 923 | attr.SecurityQualityOfService = NULL; |
| 924 | RtlInitUnicodeString( &nameW, TZInformationKeyW); |
| 925 | if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) { |
| 926 | |
| 927 | #define GTZIFR_N( valkey, tofield) \ |
| 928 | RtlInitUnicodeString( &nameW, valkey );\ |
| 929 | if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, KpInfo,\ |
| 930 | sizeof(buf), &size )) { \ |
| 931 | if( size >= (sizeof((tofield)) + \ |
Mike McCormack | c818a4e | 2005-09-21 09:46:28 +0000 | [diff] [blame] | 932 | offsetof(KEY_VALUE_PARTIAL_INFORMATION,Data))) { \ |
Rein Klazes | c5c93d1 | 2004-10-18 21:19:28 +0000 | [diff] [blame] | 933 | memcpy(&(tofield), \ |
| 934 | KpInfo->Data, sizeof(tofield)); \ |
| 935 | } \ |
| 936 | } |
| 937 | #define GTZIFR_S( valkey, tofield) \ |
| 938 | RtlInitUnicodeString( &nameW, valkey );\ |
| 939 | if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, KpInfo,\ |
| 940 | sizeof(buf), &size )) { \ |
Alexandre Julliard | b965457 | 2005-04-21 17:18:50 +0000 | [diff] [blame] | 941 | size_t len = (strlenW( (WCHAR*)KpInfo->Data ) + 1) * sizeof(WCHAR); \ |
| 942 | if (len > sizeof(tofield)) len = sizeof(tofield); \ |
| 943 | memcpy( tofield, KpInfo->Data, len ); \ |
| 944 | tofield[(len/sizeof(WCHAR))-1] = 0; \ |
Rein Klazes | c5c93d1 | 2004-10-18 21:19:28 +0000 | [diff] [blame] | 945 | } |
Alexandre Julliard | b965457 | 2005-04-21 17:18:50 +0000 | [diff] [blame] | 946 | |
Rein Klazes | c5c93d1 | 2004-10-18 21:19:28 +0000 | [diff] [blame] | 947 | GTZIFR_N( TZStandardStartW, tzinfo->StandardDate) |
| 948 | GTZIFR_N( TZDaylightStartW, tzinfo->DaylightDate) |
| 949 | GTZIFR_N( TZBiasW, tzinfo->Bias) |
| 950 | GTZIFR_N( TZStandardBiasW, tzinfo->StandardBias) |
| 951 | GTZIFR_N( TZDaylightBiasW, tzinfo->DaylightBias) |
| 952 | GTZIFR_S( TZStandardNameW, tzinfo->StandardName) |
| 953 | GTZIFR_S( TZDaylightNameW, tzinfo->DaylightName) |
| 954 | |
| 955 | #undef GTZIFR_N |
| 956 | #undef GTZIFR_S |
| 957 | NtClose( hkey ); |
| 958 | return 1; |
| 959 | } |
| 960 | return 0; |
| 961 | } |
| 962 | |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 963 | /*********************************************************************** |
| 964 | * RtlQueryTimeZoneInformation [NTDLL.@] |
| 965 | * |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 966 | * Get information about the current timezone. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 967 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 968 | * PARAMS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 969 | * tzinfo [O] Destination for the retrieved timezone info. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 970 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 971 | * RETURNS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 972 | * Success: STATUS_SUCCESS. |
| 973 | * Failure: An NTSTATUS error code indicating the problem. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 974 | */ |
Mike McCormack | 78911f3 | 2005-06-20 18:37:17 +0000 | [diff] [blame] | 975 | NTSTATUS WINAPI RtlQueryTimeZoneInformation(RTL_TIME_ZONE_INFORMATION *tzinfo) |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 976 | { |
| 977 | time_t gmt; |
| 978 | int bias, daylight; |
| 979 | const WCHAR *psTZ; |
| 980 | |
Mike McCormack | 78911f3 | 2005-06-20 18:37:17 +0000 | [diff] [blame] | 981 | memset(tzinfo, 0, sizeof(RTL_TIME_ZONE_INFORMATION)); |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 982 | |
Dmitry Timoshkov | a188662 | 2007-07-29 21:31:00 +0900 | [diff] [blame] | 983 | if( !TIME_GetTimeZoneInfoFromReg(tzinfo)) |
| 984 | { |
| 985 | WARN("TIME_GetTimeZoneInfoFromReg failed\n"); |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 986 | |
Rein Klazes | c5c93d1 | 2004-10-18 21:19:28 +0000 | [diff] [blame] | 987 | gmt = time(NULL); |
| 988 | bias = TIME_GetBias(gmt, &daylight); |
Dmitry Timoshkov | a188662 | 2007-07-29 21:31:00 +0900 | [diff] [blame] | 989 | TRACE("bias %d, daylight %d\n", -bias/60, daylight); |
Rein Klazes | c5c93d1 | 2004-10-18 21:19:28 +0000 | [diff] [blame] | 990 | |
| 991 | tzinfo->Bias = -bias / 60; |
| 992 | tzinfo->StandardBias = 0; |
| 993 | tzinfo->DaylightBias = -60; |
| 994 | tzinfo->StandardName[0]='\0'; |
| 995 | tzinfo->DaylightName[0]='\0'; |
| 996 | psTZ = TIME_GetTZAsStr (gmt, (-bias/60), daylight); |
| 997 | if (psTZ) strcpyW( tzinfo->StandardName, psTZ ); |
| 998 | } |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 999 | return STATUS_SUCCESS; |
| 1000 | } |
| 1001 | |
| 1002 | /*********************************************************************** |
| 1003 | * RtlSetTimeZoneInformation [NTDLL.@] |
| 1004 | * |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 1005 | * Set the current time zone information. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 1006 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 1007 | * PARAMS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 1008 | * tzinfo [I] Timezone information to set. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 1009 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 1010 | * RETURNS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 1011 | * Success: STATUS_SUCCESS. |
| 1012 | * Failure: An NTSTATUS error code indicating the problem. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 1013 | * |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 1014 | */ |
Mike McCormack | 78911f3 | 2005-06-20 18:37:17 +0000 | [diff] [blame] | 1015 | NTSTATUS WINAPI RtlSetTimeZoneInformation( const RTL_TIME_ZONE_INFORMATION *tzinfo ) |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 1016 | { |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 1017 | return STATUS_PRIVILEGE_NOT_HELD; |
| 1018 | } |
| 1019 | |
| 1020 | /*********************************************************************** |
| 1021 | * NtSetSystemTime [NTDLL.@] |
| 1022 | * ZwSetSystemTime [NTDLL.@] |
| 1023 | * |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 1024 | * Set the system time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 1025 | * |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 1026 | * PARAMS |
| 1027 | * NewTime [I] The time to set. |
| 1028 | * OldTime [O] Optional destination for the previous system time. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 1029 | * |
Jon Griffiths | cd4234a | 2003-03-18 18:35:48 +0000 | [diff] [blame] | 1030 | * RETURNS |
Jon Griffiths | 0892285 | 2003-08-19 00:56:34 +0000 | [diff] [blame] | 1031 | * Success: STATUS_SUCCESS. |
| 1032 | * Failure: An NTSTATUS error code indicating the problem. |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 1033 | */ |
| 1034 | NTSTATUS WINAPI NtSetSystemTime(const LARGE_INTEGER *NewTime, LARGE_INTEGER *OldTime) |
| 1035 | { |
| 1036 | TIME_FIELDS tf; |
| 1037 | struct timeval tv; |
| 1038 | struct timezone tz; |
| 1039 | struct tm t; |
| 1040 | time_t sec, oldsec; |
| 1041 | int dst, bias; |
| 1042 | int err; |
| 1043 | |
| 1044 | /* Return the old time if necessary */ |
| 1045 | if(OldTime) |
| 1046 | NtQuerySystemTime(OldTime); |
| 1047 | |
| 1048 | RtlTimeToTimeFields(NewTime, &tf); |
| 1049 | |
| 1050 | /* call gettimeofday to get the current timezone */ |
| 1051 | gettimeofday(&tv, &tz); |
| 1052 | oldsec = tv.tv_sec; |
| 1053 | /* get delta local time from utc */ |
| 1054 | bias = TIME_GetBias(oldsec, &dst); |
| 1055 | |
| 1056 | /* get the number of seconds */ |
| 1057 | t.tm_sec = tf.Second; |
| 1058 | t.tm_min = tf.Minute; |
| 1059 | t.tm_hour = tf.Hour; |
| 1060 | t.tm_mday = tf.Day; |
| 1061 | t.tm_mon = tf.Month - 1; |
| 1062 | t.tm_year = tf.Year - 1900; |
| 1063 | t.tm_isdst = dst; |
| 1064 | sec = mktime (&t); |
| 1065 | /* correct for timezone and daylight */ |
| 1066 | sec += bias; |
| 1067 | |
| 1068 | /* set the new time */ |
| 1069 | tv.tv_sec = sec; |
| 1070 | tv.tv_usec = tf.Milliseconds * 1000; |
| 1071 | |
| 1072 | /* error and sanity check*/ |
| 1073 | if(sec == (time_t)-1 || abs((int)(sec-oldsec)) > SETTIME_MAX_ADJUST) { |
| 1074 | err = 2; |
| 1075 | } else { |
| 1076 | #ifdef HAVE_SETTIMEOFDAY |
| 1077 | err = settimeofday(&tv, NULL); /* 0 is OK, -1 is error */ |
| 1078 | if(err == 0) |
| 1079 | return STATUS_SUCCESS; |
| 1080 | #else |
| 1081 | err = 1; |
| 1082 | #endif |
| 1083 | } |
| 1084 | |
| 1085 | ERR("Cannot set time to %d/%d/%d %d:%d:%d Time adjustment %ld %s\n", |
| 1086 | tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute, tf.Second, |
Gerald Pfeifer | aa0f379 | 2003-10-02 04:29:30 +0000 | [diff] [blame] | 1087 | (long)(sec-oldsec), |
| 1088 | err == -1 ? "No Permission" |
| 1089 | : sec == (time_t)-1 ? "" : "is too large." ); |
György 'Nog' Jeney | 6f3015b | 2002-11-25 01:12:39 +0000 | [diff] [blame] | 1090 | |
| 1091 | if(err == 2) |
| 1092 | return STATUS_INVALID_PARAMETER; |
| 1093 | else if(err == -1) |
| 1094 | return STATUS_PRIVILEGE_NOT_HELD; |
| 1095 | else |
| 1096 | return STATUS_NOT_IMPLEMENTED; |
| 1097 | } |