Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ah-date.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32# ifndef AH_DATE_H
33# define AH_DATE_H
34
46# include <array>
47# include <ctime>
48# include <limits>
49# include <string>
50
51# include <ah-errors.H>
52
53namespace Aleph
54{
55 namespace detail
56 {
57 inline constexpr size_t tm_epoch_year = 1900u;
58 inline constexpr size_t max_supported_year =
59 static_cast<size_t>(std::numeric_limits<int>::max()) + tm_epoch_year;
60 inline constexpr time_t seconds_per_day =
61 static_cast<time_t>(24 * 60 * 60);
62 } // namespace detail
63
65 [[nodiscard]] inline bool is_leap_year(const size_t yy) noexcept
66 {
67 return (yy % 4 == 0 and yy % 100 != 0) or (yy % 400 == 0);
68 }
69
71 [[nodiscard]] inline bool valid_month(const size_t mm) noexcept
72 {
73 return mm >= 1 and mm <= 12;
74 }
75
77 [[nodiscard]] inline bool valid_day(const size_t yy, const size_t mm, const size_t dd) noexcept
78 {
79 if (not valid_month(mm) or dd == 0)
80 return false;
81
82 static constexpr std::array<size_t, 12> month_lengths =
83 {31u, 28u, 31u, 30u, 31u, 30u, 31u, 31u, 30u, 31u, 30u, 31u};
84
85 const size_t base = month_lengths[mm - 1];
86 const size_t extra = (mm == 2 and is_leap_year(yy)) ? 1u : 0u;
87
88 return dd <= base + extra;
89 }
90
92 inline time_t to_time_t(const size_t dd, const size_t mm, const size_t yy)
93 {
96 << "Year " << yy << " is outside the supported range ["
98
100 << "Invalid date components"
101 << " (dd=" << dd << ", mm=" << mm << ", yy=" << yy << ')';
102
103 std::tm tm{};
104 tm.tm_mday = static_cast<int>(dd);
105 tm.tm_mon = static_cast<int>(mm) - 1;
106 tm.tm_year = static_cast<int>(yy) - 1900;
107 tm.tm_isdst = -1;
108
109 return std::mktime(&tm);
110 }
111
113 inline time_t to_time_t(const std::string & s, const std::string & format)
114 {
115 std::tm tm{};
116 const char *res = ::strptime(s.c_str(), format.c_str(), &tm);
117 ah_domain_error_if(res == nullptr or *res != '\0')
118 << "Input string '" << s << "' does not match format '" << format << '\'';
119
120 tm.tm_isdst = -1;
121 return std::mktime(&tm);
122 }
123
125 inline time_t to_time_t(const std::string & s)
126 {
127 return to_time_t(s, "%Y-%m-%d %H:%M:%S");
128 }
129
131 inline size_t to_days(const time_t t)
132 {
133 ah_domain_error_if(t < 0)
134 << "to_days() expects non-negative timestamps";
135
136 return static_cast<size_t>(t / detail::seconds_per_day);
137 }
138
140 inline std::string to_string(const time_t t, const std::string & format)
141 {
142 const std::tm *tm_ptr = std::localtime(&t);
143 ah_runtime_error_if(tm_ptr == nullptr) << "localtime() failed";
144
145 std::tm tm = *tm_ptr;
146 char buff[128]{};
147 const size_t written = std::strftime(buff, sizeof(buff), format.c_str(), &tm);
149 << "Unable to format time using pattern '" << format << "'";
150
151 return std::string(buff, written);
152 }
153
154}
155
156# endif
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
Definition ah-errors.H:522
#define ah_runtime_error_if(C)
Throws std::runtime_error if condition holds.
Definition ah-errors.H:266
#define ah_range_error_if(C)
Throws std::range_error if condition holds.
Definition ah-errors.H:207
constexpr size_t tm_epoch_year
Definition ah-date.H:57
constexpr time_t seconds_per_day
Definition ah-date.H:60
constexpr size_t max_supported_year
Definition ah-date.H:58
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
size_t to_days(const time_t t)
Return the number of whole days represented by t.
Definition ah-date.H:131
bool valid_month(const size_t mm) noexcept
Check whether the month number is within the [1, 12] range.
Definition ah-date.H:71
bool is_leap_year(const size_t yy) noexcept
Return true if the provided year is a leap year.
Definition ah-date.H:65
bool valid_day(const size_t yy, const size_t mm, const size_t dd) noexcept
Check whether a given day exists for the supplied month/year.
Definition ah-date.H:77
time_t to_time_t(const size_t dd, const size_t mm, const size_t yy)
Convert a (day, month, year) triple to a POSIX time_t value.
Definition ah-date.H:92
std::string to_string(const time_t t, const std::string &format)
Format a time_t value into a string using format.
Definition ah-date.H:140
DynList< T > maps(const C &c, Op op)
Classic map operation.