1 /*
2 This file is part of Warzone 2100.
3 Copyright (C) 2020 Warzone 2100 Project
4
5 Warzone 2100 is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 Warzone 2100 is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with Warzone 2100; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include "wztime.h"
21 #include <iomanip>
22 #include <sstream>
23 #include "wzglobal.h"
24 #include "frame.h"
25
getUtcTime(std::time_t const & timer)26 tm getUtcTime(std::time_t const &timer)
27 {
28 struct tm timeinfo = {};
29 #if defined(WZ_OS_WIN)
30 if (gmtime_s(&timeinfo, &timer) != 0)
31 {
32 // Invalid argument to gmtime_s
33 debug(LOG_ERROR, "Invalid time_t argument");
34 }
35 #else
36 if (!gmtime_r(&timer, &timeinfo))
37 {
38 debug(LOG_ERROR, "gmtime_r failed");
39 }
40 #endif
41 return timeinfo;
42 }
43
getLocalTimeOpt(std::time_t const & timer)44 optional<tm> getLocalTimeOpt(std::time_t const &timer)
45 {
46 struct tm timeinfo = {};
47 #if defined(WZ_OS_WIN)
48 errno_t result = localtime_s(&timeinfo, &timer);
49 if (result != 0)
50 {
51 char sys_msg[80];
52 if (strerror_s(sys_msg, sizeof(sys_msg), result) != 0)
53 {
54 strncpy(sys_msg, "unknown error", sizeof(sys_msg));
55 }
56 debug(LOG_ERROR, "localtime_s failed with error: %s", sys_msg);
57 return nullopt;
58 }
59 #else
60 if (!localtime_r(&timer, &timeinfo))
61 {
62 debug(LOG_ERROR, "localtime_r failed");
63 return nullopt;
64 }
65 #endif
66 return timeinfo;
67 }
68
getLocalTime(std::time_t const & timer)69 tm getLocalTime(std::time_t const &timer)
70 {
71 auto result = getLocalTimeOpt(timer);
72 if (!result.has_value())
73 {
74 struct tm zeroResult = {};
75 return zeroResult;
76 }
77 return result.value();
78 }
79
formatLocalDateTime_Internal(char const * format,tm const & tmVal,optional<std::locale> locale=nullopt)80 static std::string const formatLocalDateTime_Internal(char const *format, tm const &tmVal, optional<std::locale> locale = nullopt)
81 {
82 std::stringstream ss;
83 if (locale.has_value())
84 {
85 ss.imbue(locale.value());
86 }
87 ss << std::put_time(&tmVal, format);
88 return ss.str();
89 }
90
formatLocalDateTime(char const * format,std::time_t const & timer)91 std::string const formatLocalDateTime(char const *format, std::time_t const &timer)
92 {
93 auto timeinfo = getLocalTime(timer);
94 return formatLocalDateTime_Internal(format, timeinfo);
95 }
96
formatLocalDateTime(char const * format)97 std::string const formatLocalDateTime(char const *format)
98 {
99 auto timeinfo = getLocalTime(std::time(nullptr));
100 return formatLocalDateTime_Internal(format, timeinfo);
101 }
102
getAscTime(tm const & tmVal)103 std::string const getAscTime(tm const &tmVal)
104 {
105 return formatLocalDateTime_Internal("%c", tmVal, std::locale::classic());
106 }
107