Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
a66ed048
Commit
a66ed048
authored
Dec 10, 2012
by
Piotr Caban
Committed by
Alexandre Julliard
Dec 10, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcrt: Fixed mktime and _mktime64 implementation.
parent
59776ccc
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
142 additions
and
23 deletions
+142
-23
time.c
dlls/msvcrt/time.c
+142
-23
No files found.
dlls/msvcrt/time.c
View file @
a66ed048
...
...
@@ -52,20 +52,6 @@ static inline int IsLeapYear(int Year)
return
Year
%
4
==
0
&&
(
Year
%
100
!=
0
||
Year
%
400
==
0
);
}
static
inline
void
msvcrt_tm_to_unix
(
struct
tm
*
dest
,
const
struct
MSVCRT_tm
*
src
)
{
memset
(
dest
,
0
,
sizeof
(
*
dest
)
);
dest
->
tm_sec
=
src
->
tm_sec
;
dest
->
tm_min
=
src
->
tm_min
;
dest
->
tm_hour
=
src
->
tm_hour
;
dest
->
tm_mday
=
src
->
tm_mday
;
dest
->
tm_mon
=
src
->
tm_mon
;
dest
->
tm_year
=
src
->
tm_year
;
dest
->
tm_wday
=
src
->
tm_wday
;
dest
->
tm_yday
=
src
->
tm_yday
;
dest
->
tm_isdst
=
src
->
tm_isdst
;
}
static
inline
void
unix_tm_to_msvcrt
(
struct
MSVCRT_tm
*
dest
,
const
struct
tm
*
src
)
{
memset
(
dest
,
0
,
sizeof
(
*
dest
)
);
...
...
@@ -177,6 +163,57 @@ void CDECL MSVCRT__tzset(void)
_munlock
(
_TIME_LOCK
);
}
static
void
_tzset_init
(
void
)
{
static
BOOL
init
=
FALSE
;
if
(
!
init
)
{
_mlock
(
_TIME_LOCK
);
if
(
!
init
)
{
MSVCRT__tzset
();
init
=
TRUE
;
}
_munlock
(
_TIME_LOCK
);
}
}
static
BOOL
is_dst
(
const
SYSTEMTIME
*
st
)
{
TIME_ZONE_INFORMATION
tmp
;
SYSTEMTIME
out
;
if
(
!
MSVCRT___daylight
)
return
FALSE
;
if
(
tzi
.
DaylightDate
.
wMonth
)
{
tmp
=
tzi
;
}
else
if
(
st
->
wYear
>=
2007
)
{
memset
(
&
tmp
,
0
,
sizeof
(
tmp
));
tmp
.
StandardDate
.
wMonth
=
11
;
tmp
.
StandardDate
.
wDay
=
1
;
tmp
.
StandardDate
.
wHour
=
2
;
tmp
.
DaylightDate
.
wMonth
=
3
;
tmp
.
DaylightDate
.
wDay
=
2
;
tmp
.
DaylightDate
.
wHour
=
2
;
}
else
{
memset
(
&
tmp
,
0
,
sizeof
(
tmp
));
tmp
.
StandardDate
.
wMonth
=
10
;
tmp
.
StandardDate
.
wDay
=
5
;
tmp
.
StandardDate
.
wHour
=
2
;
tmp
.
DaylightDate
.
wMonth
=
4
;
tmp
.
DaylightDate
.
wDay
=
1
;
tmp
.
DaylightDate
.
wHour
=
2
;
}
tmp
.
Bias
=
0
;
tmp
.
StandardBias
=
0
;
tmp
.
DaylightBias
=
MSVCRT__dstbias
/
60
;
if
(
!
SystemTimeToTzSpecificLocalTime
(
&
tmp
,
st
,
&
out
))
return
FALSE
;
return
memcmp
(
st
,
&
out
,
sizeof
(
SYSTEMTIME
));
}
#define SECSPERDAY 86400
/* 1601 to 1970 is 369 years plus 89 leap days */
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY)
...
...
@@ -184,19 +221,100 @@ void CDECL MSVCRT__tzset(void)
#define TICKSPERMSEC 10000
#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC)
static
MSVCRT___time64_t
mktime_helper
(
struct
MSVCRT_tm
*
mstm
,
BOOL
local
)
{
SYSTEMTIME
st
;
FILETIME
ft
;
MSVCRT___time64_t
ret
=
0
;
int
i
;
BOOL
use_dst
=
FALSE
;
ret
=
mstm
->
tm_year
+
mstm
->
tm_mon
/
12
;
mstm
->
tm_mon
%=
12
;
if
(
mstm
->
tm_mon
<
0
)
{
mstm
->
tm_mon
+=
12
;
ret
--
;
}
if
(
ret
<
70
||
ret
>
1100
)
{
*
MSVCRT__errno
()
=
MSVCRT_EINVAL
;
return
-
1
;
}
memset
(
&
st
,
0
,
sizeof
(
SYSTEMTIME
));
st
.
wDay
=
1
;
st
.
wMonth
=
mstm
->
tm_mon
+
1
;
st
.
wYear
=
ret
+
1900
;
if
(
!
SystemTimeToFileTime
(
&
st
,
&
ft
))
{
*
MSVCRT__errno
()
=
MSVCRT_EINVAL
;
return
-
1
;
}
ret
=
((
MSVCRT___time64_t
)
ft
.
dwHighDateTime
<<
32
)
+
ft
.
dwLowDateTime
;
ret
+=
(
MSVCRT___time64_t
)
mstm
->
tm_sec
*
TICKSPERSEC
;
ret
+=
(
MSVCRT___time64_t
)
mstm
->
tm_min
*
60
*
TICKSPERSEC
;
ret
+=
(
MSVCRT___time64_t
)
mstm
->
tm_hour
*
60
*
60
*
TICKSPERSEC
;
ret
+=
(
MSVCRT___time64_t
)(
mstm
->
tm_mday
-
1
)
*
SECSPERDAY
*
TICKSPERSEC
;
ft
.
dwLowDateTime
=
ret
&
0xffffffff
;
ft
.
dwHighDateTime
=
ret
>>
32
;
FileTimeToSystemTime
(
&
ft
,
&
st
);
if
(
local
)
{
_tzset_init
();
use_dst
=
is_dst
(
&
st
);
if
((
mstm
->
tm_isdst
<=-
1
&&
use_dst
)
||
(
mstm
->
tm_isdst
>=
1
))
{
SYSTEMTIME
tmp
;
ret
+=
(
MSVCRT___time64_t
)
MSVCRT__dstbias
*
TICKSPERSEC
;
ft
.
dwLowDateTime
=
ret
&
0xffffffff
;
ft
.
dwHighDateTime
=
ret
>>
32
;
FileTimeToSystemTime
(
&
ft
,
&
tmp
);
if
(
!
is_dst
(
&
tmp
))
{
st
=
tmp
;
use_dst
=
FALSE
;
}
else
{
use_dst
=
TRUE
;
}
}
else
if
(
mstm
->
tm_isdst
==
0
&&
use_dst
)
{
ret
-=
(
MSVCRT___time64_t
)
MSVCRT__dstbias
*
TICKSPERSEC
;
ft
.
dwLowDateTime
=
ret
&
0xffffffff
;
ft
.
dwHighDateTime
=
ret
>>
32
;
FileTimeToSystemTime
(
&
ft
,
&
st
);
ret
+=
(
MSVCRT___time64_t
)
MSVCRT__dstbias
*
TICKSPERSEC
;
}
ret
+=
(
MSVCRT___time64_t
)
MSVCRT___timezone
*
TICKSPERSEC
;
}
mstm
->
tm_sec
=
st
.
wSecond
;
mstm
->
tm_min
=
st
.
wMinute
;
mstm
->
tm_hour
=
st
.
wHour
;
mstm
->
tm_mday
=
st
.
wDay
;
mstm
->
tm_mon
=
st
.
wMonth
-
1
;
mstm
->
tm_year
=
st
.
wYear
-
1900
;
mstm
->
tm_wday
=
st
.
wDayOfWeek
;
for
(
i
=
mstm
->
tm_yday
=
0
;
i
<
st
.
wMonth
-
1
;
i
++
)
mstm
->
tm_yday
+=
MonthLengths
[
IsLeapYear
(
st
.
wYear
)][
i
];
mstm
->
tm_yday
+=
st
.
wDay
-
1
;
mstm
->
tm_isdst
=
use_dst
?
1
:
0
;
if
(
ret
<
TICKS_1601_TO_1970
)
{
*
MSVCRT__errno
()
=
MSVCRT_EINVAL
;
return
-
1
;
}
ret
=
(
ret
-
TICKS_1601_TO_1970
)
/
TICKSPERSEC
;
return
ret
;
}
/**********************************************************************
* _mktime64 (MSVCRT.@)
*/
MSVCRT___time64_t
CDECL
MSVCRT__mktime64
(
struct
MSVCRT_tm
*
mstm
)
{
time_t
secs
;
struct
tm
tm
;
msvcrt_tm_to_unix
(
&
tm
,
mstm
);
secs
=
mktime
(
&
tm
);
unix_tm_to_msvcrt
(
mstm
,
&
tm
);
return
secs
<
0
?
-
1
:
secs
;
return
mktime_helper
(
mstm
,
TRUE
);
}
/**********************************************************************
...
...
@@ -204,7 +322,8 @@ MSVCRT___time64_t CDECL MSVCRT__mktime64(struct MSVCRT_tm *mstm)
*/
MSVCRT___time32_t
CDECL
MSVCRT__mktime32
(
struct
MSVCRT_tm
*
mstm
)
{
return
MSVCRT__mktime64
(
mstm
);
MSVCRT___time64_t
ret
=
MSVCRT__mktime64
(
mstm
);
return
ret
==
(
MSVCRT___time32_t
)
ret
?
ret
:
-
1
;
}
/**********************************************************************
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment