| 1 | /* $Id: time.cpp,v 1.2 1999-06-10 17:06:47 phaller Exp $ */
|
|---|
| 2 |
|
|---|
| 3 | /*
|
|---|
| 4 | * Project Odin Software License can be found in LICENSE.TXT
|
|---|
| 5 | * Win32 NT Runtime / NTDLL for OS/2
|
|---|
| 6 | *
|
|---|
| 7 | * Copyright 1998 original WINE Author
|
|---|
| 8 | * Copyright 1998, 1999 Patrick Haller (phaller@gmx.net)
|
|---|
| 9 | *
|
|---|
| 10 | * Conversion between Time and TimeFields
|
|---|
| 11 | *
|
|---|
| 12 | * RtlTimeToTimeFields, RtlTimeFieldsToTime and defines are taken from ReactOS and
|
|---|
| 13 | * adapted to wine with special permissions of the author
|
|---|
| 14 | * Rex Jolliff (rex@lvcablemodem.com)
|
|---|
| 15 | *
|
|---|
| 16 | *
|
|---|
| 17 | */
|
|---|
| 18 |
|
|---|
| 19 | #include "ntdll.h"
|
|---|
| 20 | #include <string.h>
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 | #define TICKSPERSEC 10000000
|
|---|
| 24 | #define TICKSPERMSEC 10000
|
|---|
| 25 | #define SECSPERDAY 86400
|
|---|
| 26 | #define SECSPERHOUR 3600
|
|---|
| 27 | #define SECSPERMIN 60
|
|---|
| 28 | #define MINSPERHOUR 60
|
|---|
| 29 | #define HOURSPERDAY 24
|
|---|
| 30 | #define EPOCHWEEKDAY 0
|
|---|
| 31 | #define DAYSPERWEEK 7
|
|---|
| 32 | #define EPOCHYEAR 1601
|
|---|
| 33 | #define DAYSPERNORMALYEAR 365
|
|---|
| 34 | #define DAYSPERLEAPYEAR 366
|
|---|
| 35 | #define MONSPERYEAR 12
|
|---|
| 36 |
|
|---|
| 37 | static const int YearLengths[2] = {DAYSPERNORMALYEAR, DAYSPERLEAPYEAR};
|
|---|
| 38 | static const int MonthLengths[2][MONSPERYEAR] =
|
|---|
| 39 | {
|
|---|
| 40 | { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
|---|
| 41 | { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
|
|---|
| 42 | };
|
|---|
| 43 |
|
|---|
| 44 | static int IsLeapYear(int Year)
|
|---|
| 45 | {
|
|---|
| 46 | return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 1 : 0;
|
|---|
| 47 | }
|
|---|
| 48 |
|
|---|
| 49 | static void NormalizeTimeFields(CSHORT *FieldToNormalize,
|
|---|
| 50 | CSHORT *CarryField,
|
|---|
| 51 | int Modulus)
|
|---|
| 52 | {
|
|---|
| 53 | *FieldToNormalize = (CSHORT) (*FieldToNormalize - Modulus);
|
|---|
| 54 | *CarryField = (CSHORT) (*CarryField + 1);
|
|---|
| 55 | }
|
|---|
| 56 |
|
|---|
| 57 | /******************************************************************************
|
|---|
| 58 | * RtlTimeToTimeFields [NTDLL.265]
|
|---|
| 59 | *
|
|---|
| 60 | */
|
|---|
| 61 |
|
|---|
| 62 | /* @@@PH we need 64-bit arithmetics here */
|
|---|
| 63 | #if 0
|
|---|
| 64 | VOID WINAPI RtlTimeToTimeFields(
|
|---|
| 65 | PLARGE_INTEGER liTime,
|
|---|
| 66 | PTIME_FIELDS TimeFields)
|
|---|
| 67 | {
|
|---|
| 68 | const int *Months;
|
|---|
| 69 | int LeapSecondCorrections, SecondsInDay, CurYear;
|
|---|
| 70 | int LeapYear, CurMonth, GMTOffset;
|
|---|
| 71 | long int Days;
|
|---|
| 72 | long long int Time = *(long long int *)&liTime;
|
|---|
| 73 |
|
|---|
| 74 | /* Extract millisecond from time and convert time into seconds */
|
|---|
| 75 | TimeFields->Milliseconds = (CSHORT) ((Time % TICKSPERSEC) / TICKSPERMSEC);
|
|---|
| 76 | Time = Time / TICKSPERSEC;
|
|---|
| 77 |
|
|---|
| 78 | /* FIXME: Compute the number of leap second corrections here */
|
|---|
| 79 | LeapSecondCorrections = 0;
|
|---|
| 80 |
|
|---|
| 81 | /* FIXME: get the GMT offset here */
|
|---|
| 82 | GMTOffset = 0;
|
|---|
| 83 |
|
|---|
| 84 | /* Split the time into days and seconds within the day */
|
|---|
| 85 | Days = Time / SECSPERDAY;
|
|---|
| 86 | SecondsInDay = Time % SECSPERDAY;
|
|---|
| 87 |
|
|---|
| 88 | /* Adjust the values for GMT and leap seconds */
|
|---|
| 89 | SecondsInDay += (GMTOffset - LeapSecondCorrections);
|
|---|
| 90 | while (SecondsInDay < 0)
|
|---|
| 91 | { SecondsInDay += SECSPERDAY;
|
|---|
| 92 | Days--;
|
|---|
| 93 | }
|
|---|
| 94 | while (SecondsInDay >= SECSPERDAY)
|
|---|
| 95 | { SecondsInDay -= SECSPERDAY;
|
|---|
| 96 | Days++;
|
|---|
| 97 | }
|
|---|
| 98 |
|
|---|
| 99 | /* compute time of day */
|
|---|
| 100 | TimeFields->Hour = (CSHORT) (SecondsInDay / SECSPERHOUR);
|
|---|
| 101 | SecondsInDay = SecondsInDay % SECSPERHOUR;
|
|---|
| 102 | TimeFields->Minute = (CSHORT) (SecondsInDay / SECSPERMIN);
|
|---|
| 103 | TimeFields->Second = (CSHORT) (SecondsInDay % SECSPERMIN);
|
|---|
| 104 |
|
|---|
| 105 | /* FIXME: handle the possibility that we are on a leap second (i.e. Second = 60) */
|
|---|
| 106 |
|
|---|
| 107 | /* compute day of week */
|
|---|
| 108 | TimeFields->Weekday = (CSHORT) ((EPOCHWEEKDAY + Days) % DAYSPERWEEK);
|
|---|
| 109 |
|
|---|
| 110 | /* compute year */
|
|---|
| 111 | CurYear = EPOCHYEAR;
|
|---|
| 112 | /* FIXME: handle calendar modifications */
|
|---|
| 113 | while (1)
|
|---|
| 114 | { LeapYear = IsLeapYear(CurYear);
|
|---|
| 115 | if (Days < (long) YearLengths[LeapYear])
|
|---|
| 116 | { break;
|
|---|
| 117 | }
|
|---|
| 118 | CurYear++;
|
|---|
| 119 | Days = Days - (long) YearLengths[LeapYear];
|
|---|
| 120 | }
|
|---|
| 121 | TimeFields->Year = (CSHORT) CurYear;
|
|---|
| 122 |
|
|---|
| 123 | /* Compute month of year */
|
|---|
| 124 | Months = MonthLengths[LeapYear];
|
|---|
| 125 | for (CurMonth = 0; Days >= (long) Months[CurMonth]; CurMonth++)
|
|---|
| 126 | Days = Days - (long) Months[CurMonth];
|
|---|
| 127 | TimeFields->Month = (CSHORT) (CurMonth + 1);
|
|---|
| 128 | TimeFields->Day = (CSHORT) (Days + 1);
|
|---|
| 129 | }
|
|---|
| 130 |
|
|---|
| 131 |
|
|---|
| 132 | /******************************************************************************
|
|---|
| 133 | * RtlTimeFieldsToTime [NTDLL.265]
|
|---|
| 134 | *
|
|---|
| 135 | */
|
|---|
| 136 | BOOLEAN WINAPI RtlTimeFieldsToTime(
|
|---|
| 137 | PTIME_FIELDS tfTimeFields,
|
|---|
| 138 | PLARGE_INTEGER Time)
|
|---|
| 139 | {
|
|---|
| 140 | int CurYear, CurMonth;
|
|---|
| 141 | long long int rcTime;
|
|---|
| 142 | TIME_FIELDS TimeFields = *tfTimeFields;
|
|---|
| 143 |
|
|---|
| 144 | rcTime = 0;
|
|---|
| 145 |
|
|---|
| 146 | /* FIXME: normalize the TIME_FIELDS structure here */
|
|---|
| 147 | while (TimeFields.Second >= SECSPERMIN)
|
|---|
| 148 | { NormalizeTimeFields(&TimeFields.Second, &TimeFields.Minute, SECSPERMIN);
|
|---|
| 149 | }
|
|---|
| 150 | while (TimeFields.Minute >= MINSPERHOUR)
|
|---|
| 151 | { NormalizeTimeFields(&TimeFields.Minute, &TimeFields.Hour, MINSPERHOUR);
|
|---|
| 152 | }
|
|---|
| 153 | while (TimeFields.Hour >= HOURSPERDAY)
|
|---|
| 154 | { NormalizeTimeFields(&TimeFields.Hour, &TimeFields.Day, HOURSPERDAY);
|
|---|
| 155 | }
|
|---|
| 156 | while (TimeFields.Day > MonthLengths[IsLeapYear(TimeFields.Year)][TimeFields.Month - 1])
|
|---|
| 157 | { NormalizeTimeFields(&TimeFields.Day, &TimeFields.Month, SECSPERMIN);
|
|---|
| 158 | }
|
|---|
| 159 | while (TimeFields.Month > MONSPERYEAR)
|
|---|
| 160 | { NormalizeTimeFields(&TimeFields.Month, &TimeFields.Year, MONSPERYEAR);
|
|---|
| 161 | }
|
|---|
| 162 |
|
|---|
| 163 | /* FIXME: handle calendar corrections here */
|
|---|
| 164 | for (CurYear = EPOCHYEAR; CurYear < TimeFields.Year; CurYear++)
|
|---|
| 165 | { rcTime += YearLengths[IsLeapYear(CurYear)];
|
|---|
| 166 | }
|
|---|
| 167 | for (CurMonth = 1; CurMonth < TimeFields.Month; CurMonth++)
|
|---|
| 168 | { rcTime += MonthLengths[IsLeapYear(CurYear)][CurMonth - 1];
|
|---|
| 169 | }
|
|---|
| 170 | rcTime += TimeFields.Day - 1;
|
|---|
| 171 | rcTime *= SECSPERDAY;
|
|---|
| 172 | rcTime += TimeFields.Hour * SECSPERHOUR + TimeFields.Minute * SECSPERMIN + TimeFields.Second;
|
|---|
| 173 | rcTime *= TICKSPERSEC;
|
|---|
| 174 | rcTime += TimeFields.Milliseconds * TICKSPERMSEC;
|
|---|
| 175 | *Time = *(LARGE_INTEGER *)&rcTime;
|
|---|
| 176 |
|
|---|
| 177 | return TRUE;
|
|---|
| 178 | }
|
|---|
| 179 | #endif
|
|---|
| 180 |
|
|---|
| 181 | /************* end of code by Rex Jolliff (rex@lvcablemodem.com) *******************/
|
|---|
| 182 |
|
|---|
| 183 | /******************************************************************************
|
|---|
| 184 | * RtlSystemTimeToLocalTime [NTDLL]
|
|---|
| 185 | */
|
|---|
| 186 | VOID WINAPI RtlSystemTimeToLocalTime(PLARGE_INTEGER SystemTime,
|
|---|
| 187 | PLARGE_INTEGER LocalTime)
|
|---|
| 188 | {
|
|---|
| 189 | dprintf(("NTDLL: RtlSystemTimeToLocalTime(%08xh,%08xh) not implemented.\n",
|
|---|
| 190 | SystemTime,
|
|---|
| 191 | LocalTime));
|
|---|
| 192 |
|
|---|
| 193 | memcpy (LocalTime,
|
|---|
| 194 | SystemTime,
|
|---|
| 195 | sizeof (PLARGE_INTEGER));
|
|---|
| 196 | }
|
|---|
| 197 |
|
|---|
| 198 |
|
|---|
| 199 | /******************************************************************************
|
|---|
| 200 | * RtlToTimeInSecondsSince1980 [NTDLL]
|
|---|
| 201 | */
|
|---|
| 202 | BOOLEAN WINAPI RtlTimeToSecondsSince1980(LPFILETIME ft,
|
|---|
| 203 | LPDWORD timeret)
|
|---|
| 204 | {
|
|---|
| 205 | dprintf(("NTDLL: RtlTimeToSecondsSince1980(%08xh,%08xh) not implemented.\n",
|
|---|
| 206 | ft,
|
|---|
| 207 | timeret));
|
|---|
| 208 |
|
|---|
| 209 | /* 1980 = 1970+10*365 days + 29. februar 1972 + 29.februar 1976 */
|
|---|
| 210 | //*timeret = DOSFS_FileTimeToUnixTime(ft,NULL) - (10*365+2)*24*3600;
|
|---|
| 211 | return 1;
|
|---|
| 212 | }
|
|---|
| 213 |
|
|---|
| 214 | /******************************************************************************
|
|---|
| 215 | * RtlToTimeInSecondsSince1970 [NTDLL]
|
|---|
| 216 | */
|
|---|
| 217 | BOOLEAN WINAPI RtlTimeToSecondsSince1970(LPFILETIME ft,
|
|---|
| 218 | LPDWORD timeret)
|
|---|
| 219 | {
|
|---|
| 220 | dprintf(("NTDLL: RtlTimeToSecondsSince1970(%08xh,%08xh) not implemented.\n",
|
|---|
| 221 | ft,
|
|---|
| 222 | timeret));
|
|---|
| 223 |
|
|---|
| 224 | //*timeret = DOSFS_FileTimeToUnixTime(ft,NULL);
|
|---|
| 225 | return 1;
|
|---|
| 226 | }
|
|---|
| 227 |
|
|---|
| 228 |
|
|---|
| 229 | /******************************************************************************
|
|---|
| 230 | * RtlTimeToElapsedTimeFields [NTDLL.502]
|
|---|
| 231 | * FIXME: prototype guessed
|
|---|
| 232 | */
|
|---|
| 233 | VOID WINAPI RtlTimeToElapsedTimeFields(PLARGE_INTEGER liTime,
|
|---|
| 234 | PTIME_FIELDS TimeFields)
|
|---|
| 235 | {
|
|---|
| 236 | dprintf(("NTDLL: RtlTimeToElapsedTimeFields(%08xh,%08xh) not implemented.\n",
|
|---|
| 237 | liTime,
|
|---|
| 238 | TimeFields));
|
|---|
| 239 | }
|
|---|