1 //
2 // loctotime.cpp
3 //
4 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //
6 // Defines the loctotime_t() family of functions, which convert a local time to
7 // the internal time format (one of the time_t types).
8 //
9 #include <corecrt_internal_time.h>
10
11
12
13 // Converts a local time to a time_t value. Returns the time_t value on success;
14 // returns a time_t with the value -1 and sets errno on failure. The 'dstflag'
15 // is 1 for Daylight Time, 0 for Standard Time, and -1 if not specified.
16 template <typename TimeType>
common_loctotime_t(int yr,int const mo,int const dy,int const hr,int const mn,int const sc,int const dstflag)17 static TimeType __cdecl common_loctotime_t(
18 int yr, // Zero-based
19 int const mo, // One-based
20 int const dy, // One-based
21 int const hr,
22 int const mn,
23 int const sc,
24 int const dstflag
25 ) throw()
26 {
27 typedef __crt_time_time_t_traits<TimeType> time_traits;
28
29 static TimeType const invalid_time = static_cast<TimeType>(-1);
30
31 // Adjust the absolute year to be an offset from the year 1900:
32 yr -= 1900;
33
34 _VALIDATE_RETURN_NOEXC(yr >= _BASE_YEAR && yr <= time_traits::max_year, EINVAL, invalid_time)
35 _VALIDATE_RETURN_NOEXC(mo >= 1 && mo <= 12, EINVAL, invalid_time)
36 _VALIDATE_RETURN_NOEXC(__crt_time_is_day_valid(yr, mo - 1, dy), EINVAL, invalid_time)
37 _VALIDATE_RETURN_NOEXC(hr >= 0 && hr <= 23, EINVAL, invalid_time)
38 _VALIDATE_RETURN_NOEXC(mn >= 0 && mn <= 59, EINVAL, invalid_time)
39 _VALIDATE_RETURN_NOEXC(sc >= 0 && sc <= 59, EINVAL, invalid_time)
40
41 // Compute the number of elapsed days in the current year:
42 int elapsed_days_this_year = dy + _days[mo - 1];
43 if (__crt_time_is_leap_year(yr) && mo > 2)
44 ++elapsed_days_this_year;
45
46 TimeType const elapsed_years = static_cast<TimeType>(yr) - _BASE_YEAR;
47 TimeType const elapsed_leap_years = static_cast<TimeType>(__crt_time_elapsed_leap_years(yr));
48
49 // The number of elapsed days is the number of days in each completed year
50 // since the epoch, plus one day per leap year, plus the number of days
51 // elapsed so far this year:
52 TimeType const elapsed_days =
53 elapsed_years * 365 +
54 elapsed_leap_years +
55 elapsed_days_this_year;
56
57 TimeType const elapsed_hours = elapsed_days * 24 + hr;
58 TimeType const elapsed_minutes = elapsed_hours * 60 + mn;
59 TimeType const elapsed_seconds = elapsed_minutes * 60 + sc;
60
61 // Account for the time zone:
62 __tzset();
63
64 int daylight = 0;
65 long dstbias = 0;
66 long timezone = 0;
67 _ERRCHECK(_get_daylight(&daylight));
68 _ERRCHECK(_get_dstbias (&dstbias ));
69 _ERRCHECK(_get_timezone(&timezone));
70
71 TimeType const timezone_adjusted_seconds = elapsed_seconds + timezone;
72
73 // Determine whether we are in Daylight Savings Time and adjust:
74 TimeType const dst_adjusted_seconds = timezone_adjusted_seconds + dstbias;
75
76 if (dstflag == 1)
77 return dst_adjusted_seconds;
78
79 tm tm_value;
80 tm_value.tm_yday = elapsed_days_this_year;
81 tm_value.tm_year = yr;
82 tm_value.tm_mon = mo - 1;
83 tm_value.tm_hour = hr;
84 tm_value.tm_min = mn;
85 tm_value.tm_sec = sc;
86 if (dstflag == -1 && daylight != 0 && _isindst(&tm_value))
87 return dst_adjusted_seconds;
88
89 // Otherwise, we are not in Daylight Savings Time:
90 return timezone_adjusted_seconds;
91 }
92
__loctotime32_t(int const yr,int const mo,int const dy,int const hr,int const mn,int const sc,int const dstflag)93 extern "C" __time32_t __cdecl __loctotime32_t(
94 int const yr,
95 int const mo,
96 int const dy,
97 int const hr,
98 int const mn,
99 int const sc,
100 int const dstflag
101 )
102 {
103 return common_loctotime_t<__time32_t>(yr, mo, dy, hr, mn, sc, dstflag);
104 }
105
__loctotime64_t(int const yr,int const mo,int const dy,int const hr,int const mn,int const sc,int const dstflag)106 extern "C" __time64_t __cdecl __loctotime64_t(
107 int const yr,
108 int const mo,
109 int const dy,
110 int const hr,
111 int const mn,
112 int const sc,
113 int const dstflag
114 )
115 {
116 return common_loctotime_t<__time64_t>(yr, mo, dy, hr, mn, sc, dstflag);
117 }
118