1 //
2 // ctime.cpp
3 //
4 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //
6 // The ctime() family of functions, which convert a time_t into a string.
7 //
8 #include <corecrt_internal_securecrt.h>
9 #include <corecrt_internal_time.h>
10
11
12
13 // Converts a time stored as a time_t into a string of the form:
14 //
15 // Tue May 1 14:25:03 1984
16 //
17 // Returns zero on success; returns an error code and sets errno on failure. The
18 // buffer is always null terminated as long as it is at least one character in
19 // length.
20 template <typename TimeType, typename Character>
21 static errno_t __cdecl common_ctime_s(
_Out_writes_z_(size_in_chars)22 _Out_writes_z_(size_in_chars) _Post_readable_size_(26) Character* const buffer,
23 _In_range_(>=,26) size_t const size_in_chars,
24 TimeType const* const time_t_value
25 ) throw()
26 {
27 typedef __crt_time_traits<TimeType, Character> time_traits;
28
29 _VALIDATE_RETURN_ERRCODE(buffer != nullptr && size_in_chars > 0, EINVAL)
30
31 _RESET_STRING(buffer, size_in_chars);
32
33 _VALIDATE_RETURN_ERRCODE (size_in_chars >= 26, EINVAL)
34 _VALIDATE_RETURN_ERRCODE (time_t_value != nullptr, EINVAL)
35 _VALIDATE_RETURN_ERRCODE_NOEXC(*time_t_value >= 0, EINVAL)
36
37 tm tm_value;
38 errno_t const status = time_traits::localtime_s(&tm_value, time_t_value);
39 if (status != 0)
40 return status;
41
42 return time_traits::tasctime_s(buffer, size_in_chars, &tm_value);
43 }
44
_ctime32_s(char * const buffer,size_t const size_in_chars,__time32_t const * const time_t_value)45 extern "C" errno_t __cdecl _ctime32_s(
46 char* const buffer,
47 size_t const size_in_chars,
48 __time32_t const* const time_t_value
49 )
50 {
51 return common_ctime_s(buffer, size_in_chars, time_t_value);
52 }
53
_wctime32_s(wchar_t * const buffer,size_t const size_in_chars,__time32_t const * const time_t_value)54 extern "C" errno_t __cdecl _wctime32_s(
55 wchar_t* const buffer,
56 size_t const size_in_chars,
57 __time32_t const* const time_t_value
58 )
59 {
60 return common_ctime_s(buffer, size_in_chars, time_t_value);
61 }
62
_ctime64_s(char * const buffer,size_t const size_in_chars,__time64_t const * const time_t_value)63 extern "C" errno_t __cdecl _ctime64_s(
64 char* const buffer,
65 size_t const size_in_chars,
66 __time64_t const* const time_t_value
67 )
68 {
69 return common_ctime_s(buffer, size_in_chars, time_t_value);
70 }
71
_wctime64_s(wchar_t * const buffer,size_t const size_in_chars,__time64_t const * const time_t_value)72 extern "C" errno_t __cdecl _wctime64_s(
73 wchar_t* const buffer,
74 size_t const size_in_chars,
75 __time64_t const* const time_t_value
76 )
77 {
78 return common_ctime_s(buffer, size_in_chars, time_t_value);
79 }
80
81
82
83 // Converts a time stored as a time_t into a string of the form, just as the
84 // secure _s version (defined above) does. Returns a pointer to a thread-local
85 // buffer containing the resulting time string.
86 template <typename TimeType, typename Character>
87 _Ret_writes_z_(26)
88 _Success_(return != 0)
common_ctime(TimeType const * const time_t_value)89 static Character* __cdecl common_ctime(
90 TimeType const* const time_t_value
91 ) throw()
92 {
93 typedef __crt_time_traits<TimeType, Character> time_traits;
94
95 _VALIDATE_RETURN (time_t_value != nullptr, EINVAL, nullptr)
96 _VALIDATE_RETURN_NOEXC(*time_t_value >= 0, EINVAL, nullptr)
97
98 tm tm_value;
99 errno_t const status = time_traits::localtime_s(&tm_value, time_t_value);
100 if (status != 0)
101 return nullptr;
102
103 return time_traits::tasctime(&tm_value);
104 }
105
_ctime32(__time32_t const * const time_t_value)106 extern "C" char* __cdecl _ctime32(__time32_t const* const time_t_value)
107 {
108 return common_ctime<__time32_t, char>(time_t_value);
109 }
110
_wctime32(__time32_t const * const time_t_value)111 extern "C" wchar_t* __cdecl _wctime32(__time32_t const* const time_t_value)
112 {
113 return common_ctime<__time32_t, wchar_t>(time_t_value);
114 }
115
_ctime64(__time64_t const * const time_t_value)116 extern "C" char* __cdecl _ctime64(__time64_t const* const time_t_value)
117 {
118 return common_ctime<__time64_t, char>(time_t_value);
119 }
120
_wctime64(__time64_t const * const time_t_value)121 extern "C" wchar_t* __cdecl _wctime64(__time64_t const* const time_t_value)
122 {
123 return common_ctime<__time64_t, wchar_t>(time_t_value);
124 }
125