- sorted API by groups
[wine/wine-kai.git] / dlls / ntdll / time.c
blob8a7296c6a477c57642d4135ac84322e9bfb86acd
1 /*
2 * Conversion between Time and TimeFields
4 * RtlTimeToTimeFields, RtlTimeFieldsToTime and defines are taken from ReactOS and
5 * adapted to wine with special permissions of the author
6 * Rex Jolliff (rex@lvcablemodem.com)
7 *
8 *
9 */
11 #include <ntddk.h>
13 #include <debug.h>
14 #include <file.h>
16 #define TICKSPERSEC 10000000
17 #define TICKSPERMSEC 10000
18 #define SECSPERDAY 86400
19 #define SECSPERHOUR 3600
20 #define SECSPERMIN 60
21 #define MINSPERHOUR 60
22 #define HOURSPERDAY 24
23 #define EPOCHWEEKDAY 0
24 #define DAYSPERWEEK 7
25 #define EPOCHYEAR 1601
26 #define DAYSPERNORMALYEAR 365
27 #define DAYSPERLEAPYEAR 366
28 #define MONSPERYEAR 12
30 static const int YearLengths[2] = {DAYSPERNORMALYEAR, DAYSPERLEAPYEAR};
31 static const int MonthLengths[2][MONSPERYEAR] =
33 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
34 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
37 static __inline int IsLeapYear(int Year)
39 return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 1 : 0;
42 static __inline void NormalizeTimeFields(CSHORT *FieldToNormalize, CSHORT *CarryField,int Modulus)
44 *FieldToNormalize = (CSHORT) (*FieldToNormalize - Modulus);
45 *CarryField = (CSHORT) (*CarryField + 1);
48 /******************************************************************************
49 * RtlTimeToTimeFields [NTDLL.265]
53 VOID WINAPI RtlTimeToTimeFields(
54 PLARGE_INTEGER liTime,
55 PTIME_FIELDS TimeFields)
57 const int *Months;
58 int LeapSecondCorrections, SecondsInDay, CurYear;
59 int LeapYear, CurMonth, GMTOffset;
60 long int Days;
61 long long int Time = *(long long int *)&liTime;
63 /* Extract millisecond from time and convert time into seconds */
64 TimeFields->Milliseconds = (CSHORT) ((Time % TICKSPERSEC) / TICKSPERMSEC);
65 Time = Time / TICKSPERSEC;
67 /* FIXME: Compute the number of leap second corrections here */
68 LeapSecondCorrections = 0;
70 /* FIXME: get the GMT offset here */
71 GMTOffset = 0;
73 /* Split the time into days and seconds within the day */
74 Days = Time / SECSPERDAY;
75 SecondsInDay = Time % SECSPERDAY;
77 /* Adjust the values for GMT and leap seconds */
78 SecondsInDay += (GMTOffset - LeapSecondCorrections);
79 while (SecondsInDay < 0)
80 { SecondsInDay += SECSPERDAY;
81 Days--;
83 while (SecondsInDay >= SECSPERDAY)
84 { SecondsInDay -= SECSPERDAY;
85 Days++;
88 /* compute time of day */
89 TimeFields->Hour = (CSHORT) (SecondsInDay / SECSPERHOUR);
90 SecondsInDay = SecondsInDay % SECSPERHOUR;
91 TimeFields->Minute = (CSHORT) (SecondsInDay / SECSPERMIN);
92 TimeFields->Second = (CSHORT) (SecondsInDay % SECSPERMIN);
94 /* FIXME: handle the possibility that we are on a leap second (i.e. Second = 60) */
96 /* compute day of week */
97 TimeFields->Weekday = (CSHORT) ((EPOCHWEEKDAY + Days) % DAYSPERWEEK);
99 /* compute year */
100 CurYear = EPOCHYEAR;
101 /* FIXME: handle calendar modifications */
102 while (1)
103 { LeapYear = IsLeapYear(CurYear);
104 if (Days < (long) YearLengths[LeapYear])
105 { break;
107 CurYear++;
108 Days = Days - (long) YearLengths[LeapYear];
110 TimeFields->Year = (CSHORT) CurYear;
112 /* Compute month of year */
113 Months = MonthLengths[LeapYear];
114 for (CurMonth = 0; Days >= (long) Months[CurMonth]; CurMonth++)
115 Days = Days - (long) Months[CurMonth];
116 TimeFields->Month = (CSHORT) (CurMonth + 1);
117 TimeFields->Day = (CSHORT) (Days + 1);
119 /******************************************************************************
120 * RtlTimeFieldsToTime [NTDLL.265]
123 BOOLEAN WINAPI RtlTimeFieldsToTime(
124 PTIME_FIELDS tfTimeFields,
125 PLARGE_INTEGER Time)
127 int CurYear, CurMonth;
128 long long int rcTime;
129 TIME_FIELDS TimeFields = *tfTimeFields;
131 rcTime = 0;
133 /* FIXME: normalize the TIME_FIELDS structure here */
134 while (TimeFields.Second >= SECSPERMIN)
135 { NormalizeTimeFields(&TimeFields.Second, &TimeFields.Minute, SECSPERMIN);
137 while (TimeFields.Minute >= MINSPERHOUR)
138 { NormalizeTimeFields(&TimeFields.Minute, &TimeFields.Hour, MINSPERHOUR);
140 while (TimeFields.Hour >= HOURSPERDAY)
141 { NormalizeTimeFields(&TimeFields.Hour, &TimeFields.Day, HOURSPERDAY);
143 while (TimeFields.Day > MonthLengths[IsLeapYear(TimeFields.Year)][TimeFields.Month - 1])
144 { NormalizeTimeFields(&TimeFields.Day, &TimeFields.Month, SECSPERMIN);
146 while (TimeFields.Month > MONSPERYEAR)
147 { NormalizeTimeFields(&TimeFields.Month, &TimeFields.Year, MONSPERYEAR);
150 /* FIXME: handle calendar corrections here */
151 for (CurYear = EPOCHYEAR; CurYear < TimeFields.Year; CurYear++)
152 { rcTime += YearLengths[IsLeapYear(CurYear)];
154 for (CurMonth = 1; CurMonth < TimeFields.Month; CurMonth++)
155 { rcTime += MonthLengths[IsLeapYear(CurYear)][CurMonth - 1];
157 rcTime += TimeFields.Day - 1;
158 rcTime *= SECSPERDAY;
159 rcTime += TimeFields.Hour * SECSPERHOUR + TimeFields.Minute * SECSPERMIN + TimeFields.Second;
160 rcTime *= TICKSPERSEC;
161 rcTime += TimeFields.Milliseconds * TICKSPERMSEC;
162 *Time = *(LARGE_INTEGER *)&rcTime;
164 return TRUE;
166 /************* end of code by Rex Jolliff (rex@lvcablemodem.com) *******************/
168 /******************************************************************************
169 * RtlSystemTimeToLocalTime [NTDLL]
171 VOID WINAPI RtlSystemTimeToLocalTime(
172 IN PLARGE_INTEGER SystemTime,
173 OUT PLARGE_INTEGER LocalTime)
175 FIXME(ntdll,"(%p, %p),stub!\n",SystemTime,LocalTime);
177 memcpy (LocalTime, SystemTime, sizeof (PLARGE_INTEGER));
179 /******************************************************************************
180 * RtlToTimeInSecondsSince1980 [NTDLL]
182 BOOLEAN WINAPI RtlTimeToSecondsSince1980(
183 LPFILETIME ft,
184 LPDWORD timeret)
186 /* 1980 = 1970+10*365 days + 29. februar 1972 + 29.februar 1976 */
187 *timeret = DOSFS_FileTimeToUnixTime(ft,NULL) - (10*365+2)*24*3600;
188 return 1;
191 /******************************************************************************
192 * RtlToTimeInSecondsSince1970 [NTDLL]
194 BOOLEAN WINAPI RtlTimeToSecondsSince1970(
195 LPFILETIME ft,
196 LPDWORD timeret)
198 *timeret = DOSFS_FileTimeToUnixTime(ft,NULL);
199 return 1;
202 /******************************************************************************
203 * RtlTimeToElapsedTimeFields [NTDLL.502]
204 * FIXME: prototype guessed
206 VOID WINAPI RtlTimeToElapsedTimeFields(
207 PLARGE_INTEGER liTime,
208 PTIME_FIELDS TimeFields)
210 FIXME(ntdll,"(%p,%p): stub\n",liTime,TimeFields);