aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QUtil.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2021-02-09 20:56:35 +0100
committerJay Berkenbilt <ejb@ql.org>2021-02-09 23:50:24 +0100
commitbf0e6eb3022bf2fde5623a0a3d151c07f5e82945 (patch)
tree72a4c73a318fd7020ad1a01ffb2469b0f2b7d62e /libqpdf/QUtil.cc
parentbfbeec5497c04e58e25fa207773ece1d29b67000 (diff)
downloadqpdf-bf0e6eb3022bf2fde5623a0a3d151c07f5e82945.tar.zst
Add QUtil methods for dealing with PDF timestamp strings
Diffstat (limited to 'libqpdf/QUtil.cc')
-rw-r--r--libqpdf/QUtil.cc103
1 files changed, 103 insertions, 0 deletions
diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc
index dc847679..4df76fa8 100644
--- a/libqpdf/QUtil.cc
+++ b/libqpdf/QUtil.cc
@@ -23,6 +23,7 @@
#include <fcntl.h>
#include <memory>
#include <locale>
+#include <regex>
#ifndef QPDF_NO_WCHAR_T
# include <cwchar>
#endif
@@ -823,6 +824,108 @@ QUtil::get_current_time()
#endif
}
+QUtil::QPDFTime
+QUtil::get_current_qpdf_time()
+{
+#ifdef _WIN32
+ SYSTEMTIME ltime;
+ GetLocalTime(&ltime);
+ TIME_ZONE_INFORMATION tzinfo;
+ GetTimeZoneInformation(&tzinfo);
+ return QPDFTime(static_cast<int>(ltime.wYear),
+ static_cast<int>(ltime.wMonth),
+ static_cast<int>(ltime.wDay),
+ static_cast<int>(ltime.wHour),
+ static_cast<int>(ltime.wMinute),
+ static_cast<int>(ltime.wSecond),
+ static_cast<int>(tzinfo.Bias));
+#else
+ struct tm ltime;
+ time_t now = time(0);
+ tzset();
+ localtime_r(&now, &ltime);
+ return QPDFTime(static_cast<int>(ltime.tm_year + 1900),
+ static_cast<int>(ltime.tm_mon + 1),
+ static_cast<int>(ltime.tm_mday),
+ static_cast<int>(ltime.tm_hour),
+ static_cast<int>(ltime.tm_min),
+ static_cast<int>(ltime.tm_sec),
+ static_cast<int>(timezone / 60));
+#endif
+}
+
+std::string
+QUtil::qpdf_time_to_pdf_time(QPDFTime const& qtm)
+{
+ std::string tz_offset;
+ int t = qtm.tz_delta;
+ if (t == 0)
+ {
+ tz_offset = "Z";
+ }
+ else
+ {
+ if (t < 0)
+ {
+ t = -t;
+ tz_offset += "+";
+ }
+ else
+ {
+ tz_offset += "-";
+ }
+ tz_offset +=
+ QUtil::int_to_string(t / 60, 2) + "'" +
+ QUtil::int_to_string(t % 60, 2) + "'";
+ }
+ return ("D:" +
+ QUtil::int_to_string(qtm.year, 4) +
+ QUtil::int_to_string(qtm.month, 2) +
+ QUtil::int_to_string(qtm.day, 2) +
+ QUtil::int_to_string(qtm.hour, 2) +
+ QUtil::int_to_string(qtm.minute, 2) +
+ QUtil::int_to_string(qtm.second, 2) +
+ tz_offset);
+}
+
+bool
+QUtil::pdf_time_to_qpdf_time(std::string const& str, QPDFTime* qtm)
+{
+ static std::regex pdf_date("^D:([0-9]{4})([0-9]{2})([0-9]{2})"
+ "([0-9]{2})([0-9]{2})([0-9]{2})"
+ "(?:(Z)|([\\+\\-])([0-9]{2})'([0-9]{2})')$");
+ std::smatch m;
+ if (! std::regex_match(str, m, pdf_date))
+ {
+ return false;
+ }
+ int tz_delta = 0;
+ auto to_i = [](std::string const& s) {
+ return QUtil::string_to_int(s.c_str());
+ };
+
+ if (m[7] == "")
+ {
+ tz_delta = ((to_i(m[9]) * 60) +
+ to_i(m[10]));
+ if (m[8] == "+")
+ {
+ tz_delta = -tz_delta;
+ }
+ }
+ if (qtm)
+ {
+ *qtm = QPDFTime(to_i(m[1]),
+ to_i(m[2]),
+ to_i(m[3]),
+ to_i(m[4]),
+ to_i(m[5]),
+ to_i(m[6]),
+ tz_delta);
+ }
+ return true;
+}
+
std::string
QUtil::toUTF8(unsigned long uval)
{