summaryrefslogtreecommitdiff
path: root/src/date.cc
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@spawned.biz>2021-11-17 22:34:57 +0100
committerJoel Klinghed <the_jk@spawned.biz>2021-11-17 22:34:57 +0100
commit6232d13f5321b87ddf12a1aa36b4545da45f173d (patch)
tree23f3316470a14136debd9d02f9e920ca2b06f4cc /src/date.cc
Travel3: Simple image and video display site
Reads the images and videos from filesystem and builds a site in memroy.
Diffstat (limited to 'src/date.cc')
-rw-r--r--src/date.cc66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/date.cc b/src/date.cc
new file mode 100644
index 0000000..23f0ad6
--- /dev/null
+++ b/src/date.cc
@@ -0,0 +1,66 @@
+#include "common.hh"
+
+#include "date.hh"
+
+#include <pthread.h>
+#include <time.h>
+
+namespace {
+
+// localtime_r doesn't guarantee to call tzset as localtime does.
+pthread_once_t tzset_called = PTHREAD_ONCE_INIT;
+
+} // namespace
+
+Date Date::from_format(std::string const& format,
+ std::string const& str,
+ bool local_time) {
+ struct tm tm = {};
+ tm.tm_isdst = -1; // Must be -1 so that mktime figures it out by itself.
+ auto* end = strptime(str.c_str(), format.c_str(), &tm);
+ if (end && !*end)
+ return local_time ? mktime(&tm) : timegm(&tm);
+ return Date();
+}
+
+std::string Date::to_format(std::string const& format,
+ bool local_time) const {
+ if (empty() || format.empty())
+ return std::string();
+
+ if (local_time)
+ pthread_once(&tzset_called, tzset);
+
+ struct tm mem = {};
+ auto* tm = local_time ? localtime_r(&time_, &mem) : gmtime_r(&time_, &mem);
+ if (!tm)
+ return std::string();
+
+ std::string ret;
+ ret.resize(64);
+ while (true) {
+ auto len = strftime(ret.data(), ret.size(), format.c_str(), tm);
+ if (len > 0) {
+ ret.resize(len);
+ return ret;
+ }
+ ret.resize(ret.size() * 2);
+ }
+}
+
+Date Date::day(bool local_time) const {
+ if (empty())
+ return *this;
+
+ if (local_time)
+ pthread_once(&tzset_called, tzset);
+
+ struct tm tm = {};
+ auto* ret = local_time ? localtime_r(&time_, &tm) : gmtime_r(&time_, &tm);
+ if (!ret)
+ return *this;
+ ret->tm_hour = 0;
+ ret->tm_min = 0;
+ ret->tm_sec = 0;
+ return local_time ? mktime(ret) : timegm(ret);
+}