xref: /reactos/sdk/lib/ucrt/time/strtime.cpp (revision 04e0dc4a)
1*04e0dc4aSTimo Kreuzer //
2*04e0dc4aSTimo Kreuzer // strtime.cpp
3*04e0dc4aSTimo Kreuzer //
4*04e0dc4aSTimo Kreuzer //      Copyright (c) Microsoft Corporation. All rights reserved.
5*04e0dc4aSTimo Kreuzer //
6*04e0dc4aSTimo Kreuzer // The strtime family of functions, which return the current time as a string.
7*04e0dc4aSTimo Kreuzer //
8*04e0dc4aSTimo Kreuzer #include <corecrt_internal_securecrt.h>
9*04e0dc4aSTimo Kreuzer #include <corecrt_internal_time.h>
10*04e0dc4aSTimo Kreuzer 
11*04e0dc4aSTimo Kreuzer #pragma warning(disable:__WARNING_HIGH_PRIORITY_OVERFLOW_POSTCONDITION) // 26045 Potential postcondition violation that could result in overflow
12*04e0dc4aSTimo Kreuzer #pragma warning(disable:__WARNING_RETURNING_BAD_RESULT) // 28196 The requirement that 'return!=0' is not satisfied. (The expression does not evaluate to true.)
13*04e0dc4aSTimo Kreuzer 
14*04e0dc4aSTimo Kreuzer // Returns the current time as a string of the form "HH:MM:SS".  These functions
15*04e0dc4aSTimo Kreuzer // return an error code on failure, or zero on success.  The buffer must be at
16*04e0dc4aSTimo Kreuzer // least nine characters in size.
17*04e0dc4aSTimo Kreuzer template <typename Character>
18*04e0dc4aSTimo Kreuzer _Success_(buffer != 0 && size_in_chars >= 9)
19*04e0dc4aSTimo Kreuzer static errno_t __cdecl common_strtime_s(
_Out_writes_z_(size_in_chars)20*04e0dc4aSTimo Kreuzer     _Out_writes_z_(size_in_chars)   Character*  const   buffer,
21*04e0dc4aSTimo Kreuzer     _In_  _In_range_(>=, 9)         size_t      const   size_in_chars
22*04e0dc4aSTimo Kreuzer     ) throw()
23*04e0dc4aSTimo Kreuzer {
24*04e0dc4aSTimo Kreuzer     _VALIDATE_RETURN_ERRCODE(buffer != nullptr && size_in_chars > 0, EINVAL);
25*04e0dc4aSTimo Kreuzer     _RESET_STRING(buffer, size_in_chars);
26*04e0dc4aSTimo Kreuzer     _VALIDATE_RETURN_ERRCODE(size_in_chars >= 9, ERANGE);
27*04e0dc4aSTimo Kreuzer 
28*04e0dc4aSTimo Kreuzer     SYSTEMTIME local_time;
29*04e0dc4aSTimo Kreuzer     GetLocalTime(&local_time);
30*04e0dc4aSTimo Kreuzer 
31*04e0dc4aSTimo Kreuzer     int const hours   = local_time.wHour;
32*04e0dc4aSTimo Kreuzer     int const minutes = local_time.wMinute;
33*04e0dc4aSTimo Kreuzer     int const seconds = local_time.wSecond;
34*04e0dc4aSTimo Kreuzer 
35*04e0dc4aSTimo Kreuzer     static Character const zero_char = static_cast<Character>('0');
36*04e0dc4aSTimo Kreuzer 
37*04e0dc4aSTimo Kreuzer #pragma warning(disable:__WARNING_INCORRECT_VALIDATION) // 26014 Prefast doesn't notice the validation.
38*04e0dc4aSTimo Kreuzer 
39*04e0dc4aSTimo Kreuzer     // Store the components of the date into the string in HH:MM:SS form:
40*04e0dc4aSTimo Kreuzer     buffer[0] = static_cast<Character>(hours   / 10 + zero_char); // Tens of hour
41*04e0dc4aSTimo Kreuzer     buffer[1] = static_cast<Character>(hours   % 10 + zero_char); // Units of hour
42*04e0dc4aSTimo Kreuzer     buffer[2] = static_cast<Character>(':');
43*04e0dc4aSTimo Kreuzer     buffer[3] = static_cast<Character>(minutes / 10 + zero_char); // Tens of minute
44*04e0dc4aSTimo Kreuzer     buffer[4] = static_cast<Character>(minutes % 10 + zero_char); // Units of minute
45*04e0dc4aSTimo Kreuzer     buffer[5] = static_cast<Character>(':');
46*04e0dc4aSTimo Kreuzer     buffer[6] = static_cast<Character>(seconds / 10 + zero_char); // Tens of second
47*04e0dc4aSTimo Kreuzer     buffer[7] = static_cast<Character>(seconds % 10 + zero_char); // Units of second
48*04e0dc4aSTimo Kreuzer     buffer[8] = static_cast<Character>('\0');
49*04e0dc4aSTimo Kreuzer 
50*04e0dc4aSTimo Kreuzer     return 0;
51*04e0dc4aSTimo Kreuzer }
52*04e0dc4aSTimo Kreuzer 
_strtime_s(char * const buffer,size_t const size_in_chars)53*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _strtime_s(char* const buffer, size_t const size_in_chars)
54*04e0dc4aSTimo Kreuzer {
55*04e0dc4aSTimo Kreuzer     return common_strtime_s(buffer, size_in_chars);
56*04e0dc4aSTimo Kreuzer }
57*04e0dc4aSTimo Kreuzer 
_wstrtime_s(wchar_t * const buffer,size_t const size_in_chars)58*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _wstrtime_s(wchar_t* const buffer, size_t const size_in_chars)
59*04e0dc4aSTimo Kreuzer {
60*04e0dc4aSTimo Kreuzer     return common_strtime_s(buffer, size_in_chars);
61*04e0dc4aSTimo Kreuzer }
62*04e0dc4aSTimo Kreuzer 
63*04e0dc4aSTimo Kreuzer 
64*04e0dc4aSTimo Kreuzer 
65*04e0dc4aSTimo Kreuzer // Returns the current time as a string of the form "HH:MM:SS".  These functions
66*04e0dc4aSTimo Kreuzer // assume that the provided result buffer is at least nine characters in length.
67*04e0dc4aSTimo Kreuzer // Each returns the buffer on success, or null on failure.
68*04e0dc4aSTimo Kreuzer template <typename Character>
69*04e0dc4aSTimo Kreuzer _Success_(buffer != 0)
70*04e0dc4aSTimo Kreuzer _Ret_z_
71*04e0dc4aSTimo Kreuzer static Character* __cdecl common_strtime(_Out_writes_z_(9) Character* const buffer) throw()
72*04e0dc4aSTimo Kreuzer {
73*04e0dc4aSTimo Kreuzer     errno_t const status = common_strtime_s(buffer, 9);
74*04e0dc4aSTimo Kreuzer     if (status != 0)
75*04e0dc4aSTimo Kreuzer         return nullptr;
76*04e0dc4aSTimo Kreuzer 
77*04e0dc4aSTimo Kreuzer     return buffer;
78*04e0dc4aSTimo Kreuzer }
79*04e0dc4aSTimo Kreuzer 
_strtime(char * const buffer)80*04e0dc4aSTimo Kreuzer extern "C" char* __cdecl _strtime(char* const buffer)
81*04e0dc4aSTimo Kreuzer {
82*04e0dc4aSTimo Kreuzer     return common_strtime(buffer);
83*04e0dc4aSTimo Kreuzer }
84*04e0dc4aSTimo Kreuzer 
_wstrtime(wchar_t * const buffer)85*04e0dc4aSTimo Kreuzer extern "C" wchar_t* __cdecl _wstrtime(wchar_t* const buffer)
86*04e0dc4aSTimo Kreuzer {
87*04e0dc4aSTimo Kreuzer     return common_strtime(buffer);
88*04e0dc4aSTimo Kreuzer }
89