Skip to main content

The datetime.cpp File Reference

Included Headers

#include <cstdlib> #include <chrono> #include <memory> #include <array> #include <functional> #include "regex.h" #include "datetime.h" #include "config.h" #include "portable.h" #include "language.h" #include "message.h" #include "growbuf.h"

Classes Index

structSpecFormat
structDateTimeField

Typedefs Index

usingTMFieldAssigner = std::function< void(std::tm &, int value) >

Functions Index

std::tmgetCurrentDateTime ()

Returns the filled in std::tm for the current date and time. More...

QCStringdateToString (DateTimeType includeTime)

Returns the current date, when includeTime is set also the time is provided. More...

QCStringyearToString ()

Returns the current year as a string. More...

static voiddetermine_weekday (std::tm &tm)
QCStringdateTimeFromString (const QCString &spec, std::tm &dt, int &format)

Returns the filled in std::tm for a given string representing a date and/or time. More...

QCStringformatDateTime (const QCString &format, const std::tm &dt, int &formatUsed)

Return a string representation for a given std::tm value that is formatted according to the pattern given by a format. More...

Variables Index

static std::arrayg_specFormats = ...
static std::arrayg_assignValues = ...

Typedefs

TMFieldAssigner

using TMFieldAssigner = std::function< void(std::tm &,int value) >

Definition at line 90 of file datetime.cpp.

90using TMFieldAssigner = std::function< void(std::tm &,int value) >;

Functions

dateTimeFromString()

QCString dateTimeFromString (const QCString & spec, std::tm & dt, int & format)

Returns the filled in std::tm for a given string representing a date and/or time.

Parameters
[in] spec

The string representation of the date and/or time Possible formats:

  • the empty string: the current date and time is returned
  • YYYY-MM-DD HH:MM:SS: the date and time are fully specified
  • YYYY-MM-DD HH:MM: the date and time without seconds
  • YYYY-MM-DD: the date without time
  • HH:MM:SS: the time with seconds but without date
  • HH:MM: the time without seconds and without date
[out] dt

The corresponding datetime value.

[out] format

The parts that have been found in spec; a bitwise or of SF_Date, SF_Time and SF_Seconds.

Returns

An empty string if the spec has a supported format, or an error message if the format is invalid.

Definition at line 134 of file datetime.cpp.

134QCString dateTimeFromString(const QCString &spec,std::tm &dt,int &format)
135{
136 // for an empty spec field return the current date and time
137 dt = getCurrentDateTime();
138 if (spec.isEmpty())
139 {
140 format = SF_Date | SF_Time | SF_Seconds;
141 return QCString();
142 }
143
144 // find a matching pattern
145 std::string s = spec.str();
146 for (const auto &fmt : g_specFormats)
147 {
148 reg::Match m;
149 if (reg::match(s,m,fmt.re)) // match found
150 {
151 for (int i=0; i<fmt.count; i++)
152 {
153 int value = std::atoi(m[i+1].str().c_str());
154 const DateTimeField &dtf = g_assignValues[i+fmt.offset];
155 if (value<dtf.minVal || value>dtf.maxVal) // check if the value is in the expected range
156 {
157 return QCString().sprintf("value for %s is %d which is outside of the value range [%d..%d]",
158 dtf.name, value, dtf.minVal, dtf.maxVal);
159 }
160 dtf.assigner(dt,value);
161 }
162 format = fmt.format;
163 if (format&SF_Date) // if we have a date also determine the weekday
164 {
166 }
167 return QCString();
168 }
169 }
170
171 // no matching pattern found
172 return "invalid or non representable date/time argument";
173}

References DateTimeField::assigner, determine_weekday, g_assignValues, g_specFormats, getCurrentDateTime, QCString::isEmpty, reg::match, DateTimeField::maxVal, DateTimeField::minVal, DateTimeField::name, SF_Date, SF_Seconds, SF_Time, QCString::sprintf and QCString::str.

Referenced by DocPara::handleShowDate and showDate.

dateToString()

QCString dateToString (DateTimeType includeTime)

Returns the current date, when includeTime is set also the time is provided.

Parameters
[in] includeTime

include the time in the output

Definition at line 63 of file datetime.cpp.

64{
65 auto current = getCurrentDateTime();
66 return theTranslator->trDateTime(current.tm_year + 1900,
67 current.tm_mon + 1,
68 current.tm_mday,
69 (current.tm_wday+6)%7+1, // map: Sun=0..Sat=6 to Mon=1..Sun=7
70 current.tm_hour,
71 current.tm_min,
72 current.tm_sec,
73 includeTime);
74}

References getCurrentDateTime and theTranslator.

Referenced by RTFGenerator::endIndexSection, ManGenerator::endTitleHead, recordMetadata, substituteKeywords, substituteLatexKeywords and writeDefaultStyleSheet.

determine_weekday()

void determine_weekday (std::tm & tm)
static

Definition at line 121 of file datetime.cpp.

121static void determine_weekday( std::tm& tm )
122{
123 auto cpy = tm;
124 // there are some problems when the hr:min:sec are on 00:00:00 in determining the weekday
125 cpy.tm_hour = 12;
126 const auto as_time_t = std::mktime( &cpy ) ;
127 if (as_time_t != -1)
128 {
129 cpy = *std::localtime( &as_time_t ) ;
130 tm.tm_wday = cpy.tm_wday;
131 }
132}

Referenced by dateTimeFromString.

formatDateTime()

QCString formatDateTime (const QCString & format, const std::tm & dt, int & formatUsed)

Return a string representation for a given std::tm value that is formatted according to the pattern given by a format.

Parameters
[in] format

the string used for format the date and time, e.g. Y-m-d

[in] dt

the date and time value to fill in

[out] formatUsed

A bitwise OR of SF_Date, SF_Time and SF_Seconds representing the the types of markers found in the format string.

Definition at line 175 of file datetime.cpp.

175QCString formatDateTime(const QCString &format,const std::tm &dt,int &formatUsed)
176{
177 formatUsed = 0;
178 auto getYear = [](const std::tm &dat) { return dat.tm_year+1900; };
179 auto getMonth = [](const std::tm &dat) { return dat.tm_mon+1; };
180 auto getDay = [](const std::tm &dat) { return dat.tm_mday; };
181 auto getDayOfWeek = [](const std::tm &dat) { return (dat.tm_wday+6)%7+1; };
182 GrowBuf growBuf;
183 char c = 0;
184 const char *p = format.data();
185 const char *fmt_zero = "%02d";
186 const char *fmt_nonzero = "%d";
187 const char *fmt_selected = nullptr;
188 if (p==nullptr) return QCString();
189 while ((c=*p++))
190 {
191 char nc = *p;
192 switch (c)
193 {
194 case '%':
195 fmt_selected = nc=='-' ? fmt_nonzero : fmt_zero; // %-H produces 1 and %H produces 1
196 if (nc=='-') nc=*++p; // skip over -
197 switch (nc)
198 {
199 case '%': growBuf.addChar('%'); break;
200 case 'y': growBuf.addInt(fmt_selected,getYear(dt)%100); formatUsed|=SF_Date; break;
201 case 'Y': growBuf.addInt("%d",getYear(dt)); formatUsed|=SF_Date; break;
202 case 'm': growBuf.addInt(fmt_selected,getMonth(dt)); formatUsed|=SF_Date; break;
203 case 'b': growBuf.addStr(theTranslator->trMonth(getMonth(dt),false,false)); formatUsed|=SF_Date; break;
204 case 'B': growBuf.addStr(theTranslator->trMonth(getMonth(dt),false,true)); formatUsed|=SF_Date; break;
205 case 'd': growBuf.addInt(fmt_selected,getDay(dt)); formatUsed|=SF_Date; break;
206 case 'u': growBuf.addInt("%d",getDayOfWeek(dt)); /* Monday = 1 ... Sunday = 7 */ formatUsed|=SF_Date; break;
207 case 'w': growBuf.addInt("%d",getDayOfWeek(dt)%7); /* Sunday = 0 ... Saturday = 6 */ formatUsed|=SF_Date; break;
208 case 'a': growBuf.addStr(theTranslator->trDayOfWeek(getDayOfWeek(dt),false,false)); formatUsed|=SF_Date; break;
209 case 'A': growBuf.addStr(theTranslator->trDayOfWeek(getDayOfWeek(dt),false,true)); formatUsed|=SF_Date; break;
210 case 'H': growBuf.addInt(fmt_selected,dt.tm_hour); formatUsed|=SF_Time; break;
211 case 'I': growBuf.addInt(fmt_selected,dt.tm_hour%12); formatUsed|=SF_Time; break;
212 case 'p': growBuf.addStr(theTranslator->trDayPeriod(dt.tm_hour>=12)); formatUsed|=SF_Time; break;
213 case 'M': growBuf.addInt(fmt_selected,dt.tm_min); formatUsed|=SF_Time; break;
214 case 'S': growBuf.addInt(fmt_selected,dt.tm_sec); formatUsed|=SF_Seconds; break;
215 default:
216 growBuf.addChar(c);
217 if (*(p-1)=='-') growBuf.addChar('-');
218 growBuf.addChar(nc);
219 break;
220 }
221 p++;
222 break;
223 default:
224 growBuf.addChar(c);
225 break;
226 }
227 }
228 growBuf.addChar(0);
229 return growBuf.get();
230}

References GrowBuf::addChar, GrowBuf::addInt, GrowBuf::addStr, QCString::data, GrowBuf::get, SF_Date, SF_Seconds, SF_Time and theTranslator.

Referenced by DocPara::handleShowDate and showDate.

getCurrentDateTime()

std::tm getCurrentDateTime ()

Returns the filled in std::tm for the current date and time.

Definition at line 30 of file datetime.cpp.

31{
32 QCString sourceDateEpoch = Portable::getenv("SOURCE_DATE_EPOCH");
33 if (!sourceDateEpoch.isEmpty()) // see https://reproducible-builds.org/specs/source-date-epoch/
34 {
35 bool ok = false;
36 uint64_t epoch = sourceDateEpoch.toUInt64(&ok);
37 if (!ok)
38 {
39 static bool warnedOnce=FALSE;
40 if (!warnedOnce)
41 {
42 warn_uncond("Environment variable SOURCE_DATE_EPOCH does not contain a valid number; value is '{}'\n",
43 sourceDateEpoch);
44 warnedOnce=TRUE;
45 }
46 }
47 else // use given epoch value as current 'built' time
48 {
49 auto epoch_start = std::chrono::time_point<std::chrono::system_clock>{};
50 auto epoch_seconds = std::chrono::seconds(epoch);
51 auto build_time = epoch_start + epoch_seconds;
52 std::time_t time = std::chrono::system_clock::to_time_t(build_time);
53 return *gmtime(&time);
54 }
55 }
56
57 // return current local time
58 auto now = std::chrono::system_clock::now();
59 std::time_t time = std::chrono::system_clock::to_time_t(now);
60 return *localtime(&time);
61}

References FALSE, Portable::getenv, QCString::isEmpty, QCString::toUInt64, TRUE and warn_uncond.

Referenced by dateTimeFromString, dateToRTFDateString, dateToString and yearToString.

yearToString()

QCString yearToString ()

Returns the current year as a string.

Definition at line 76 of file datetime.cpp.

77{
78 auto current = getCurrentDateTime();
79 return QCString().setNum(current.tm_year+1900);
80}

References getCurrentDateTime and QCString::setNum.

Referenced by substituteKeywords.

Variables

g_assignValues

std::array g_assignValues
static
Initialiser
{ DateTimeField{ [](std::tm &tm,int value) { tm.tm_year = value-1900; }, 1900, 9999, "year" }, DateTimeField{ [](std::tm &tm,int value) { tm.tm_mon = value-1; }, 1, 12, "month" }, DateTimeField{ [](std::tm &tm,int value) { tm.tm_mday = value; }, 1, 31, "day" }, DateTimeField{ [](std::tm &tm,int value) { tm.tm_hour = value; }, 0, 23, "hour" }, DateTimeField{ [](std::tm &tm,int value) { tm.tm_min = value; }, 0, 59, "minute" }, DateTimeField{ [](std::tm &tm,int value) { tm.tm_sec = value; }, 0, 59, "second" } }

Definition at line 110 of file datetime.cpp.

111{
112 // assigner, minVal, maxVal, name
113 DateTimeField{ [](std::tm &tm,int value) { tm.tm_year = value-1900; }, 1900, 9999, "year" },
114 DateTimeField{ [](std::tm &tm,int value) { tm.tm_mon = value-1; }, 1, 12, "month" },
115 DateTimeField{ [](std::tm &tm,int value) { tm.tm_mday = value; }, 1, 31, "day" },
116 DateTimeField{ [](std::tm &tm,int value) { tm.tm_hour = value; }, 0, 23, "hour" },
117 DateTimeField{ [](std::tm &tm,int value) { tm.tm_min = value; }, 0, 59, "minute" },
118 DateTimeField{ [](std::tm &tm,int value) { tm.tm_sec = value; }, 0, 59, "second" }
119};

Referenced by dateTimeFromString.

g_specFormats

std::array g_specFormats
static
Initialiser
{ SpecFormat{ std::string_view(R"((\d+)-(\d+)-(\d+)\s*(\d+):(\d+):(\d+))"), 6, 0, SF_Date|SF_Time|SF_Seconds }, SpecFormat{ std::string_view(R"((\d+)-(\d+)-(\d+)\s*(\d+):(\d+))"), 5, 0, SF_Date|SF_Time }, SpecFormat{ std::string_view(R"((\d+)-(\d+)-(\d+))"), 3, 0, SF_Date }, SpecFormat{ std::string_view(R"((\d+):(\d+):(\d+))"), 3, 3, SF_Time|SF_Seconds }, SpecFormat{ std::string_view(R"((\d+):(\d+))"), 2, 3, SF_Time } }

Definition at line 100 of file datetime.cpp.

101{
102 // regular expression, num values, offset, format bits
103 SpecFormat{ std::string_view(R"((\d+)-(\d+)-(\d+)\s*(\d+):(\d+):(\d+))"), 6, 0, SF_Date|SF_Time|SF_Seconds }, // format 13-04-2015 12:34:56
104 SpecFormat{ std::string_view(R"((\d+)-(\d+)-(\d+)\s*(\d+):(\d+))"), 5, 0, SF_Date|SF_Time }, // format 13-04-2015 12:34
105 SpecFormat{ std::string_view(R"((\d+)-(\d+)-(\d+))"), 3, 0, SF_Date }, // format 13-04-2015
106 SpecFormat{ std::string_view(R"((\d+):(\d+):(\d+))"), 3, 3, SF_Time|SF_Seconds }, // format 12:34:56
107 SpecFormat{ std::string_view(R"((\d+):(\d+))"), 2, 3, SF_Time } // format 12:34
108};

Referenced by dateTimeFromString.


Generated via doxygen2docusaurus by Doxygen 1.14.0.