diff options
| author | Joel Klinghed <the_jk@spawned.biz> | 2021-11-17 22:34:57 +0100 |
|---|---|---|
| committer | Joel Klinghed <the_jk@spawned.biz> | 2021-11-17 22:34:57 +0100 |
| commit | 6232d13f5321b87ddf12a1aa36b4545da45f173d (patch) | |
| tree | 23f3316470a14136debd9d02f9e920ca2b06f4cc /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.cc | 66 |
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); +} |
