xref: /reactos/sdk/lib/ucrt/time/ctime.cpp (revision a6a07059)
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(
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 
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 
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 
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 
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)
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 
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 
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 
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 
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