aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2022-05-30 15:00:36 +0200
committerJay Berkenbilt <ejb@ql.org>2022-05-31 02:03:08 +0200
commit04fc7c4bea9b4efa38a7398b6db56a8fe5273bfb (patch)
tree4148a27d5f8f2d01681d1c6c41b9fceabe2a1042
parent6a7c45838171fd8cc4508d09626e27d9066bb39d (diff)
downloadqpdf-04fc7c4bea9b4efa38a7398b6db56a8fe5273bfb.tar.zst
Add conversions to ISO-8601 date format
-rw-r--r--ChangeLog5
-rw-r--r--include/qpdf/QUtil.hh9
-rw-r--r--libqpdf/QUtil.cc37
-rw-r--r--libtests/qtest/qutil/qutil.out3
-rw-r--r--libtests/qutil.cc6
5 files changed, 59 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 4a8122fc..ea445e64 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2022-05-30 Jay Berkenbilt <ejb@ql.org>
+
+ * Add QUtil::qpdf_time_to_iso8601 and QUtil::pdf_time_to_iso8601
+ for converting PDF/qpdf timestamps to ISO-8601 date format.
+
2022-05-18 Jay Berkenbilt <ejb@ql.org>
* Add QUtil::FileCloser to the public API. This is a simple inline
diff --git a/include/qpdf/QUtil.hh b/include/qpdf/QUtil.hh
index 283db861..32aeae1f 100644
--- a/include/qpdf/QUtil.hh
+++ b/include/qpdf/QUtil.hh
@@ -284,6 +284,10 @@ namespace QUtil
QPDF_DLL
std::string qpdf_time_to_pdf_time(QPDFTime const&);
+ // Convert QPDFTime to a second-granularity ISO-8601 timestamp.
+ QPDF_DLL
+ std::string qpdf_time_to_iso8601(QPDFTime const&);
+
// Convert a PDF timestamp string to a QPDFTime. If syntactically
// valid, return true and fill in qtm. If not valid, return false,
// and do not modify qtm. If qtm is null, just check the validity
@@ -291,6 +295,11 @@ namespace QUtil
QPDF_DLL
bool pdf_time_to_qpdf_time(std::string const&, QPDFTime* qtm = nullptr);
+ // Convert PDF timestamp to a second-granularity ISO-8601
+ // timestamp. If syntactically valid, return true and initialize
+ // iso8601. Otherwise, return false.
+ bool pdf_time_to_iso8601(std::string const& pdf_time, std::string& iso8601);
+
// Return a string containing the byte representation of the UTF-8
// encoding for the unicode value passed in.
QPDF_DLL
diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc
index 3e68d95e..7a5d3caf 100644
--- a/libqpdf/QUtil.cc
+++ b/libqpdf/QUtil.cc
@@ -984,6 +984,32 @@ QUtil::qpdf_time_to_pdf_time(QPDFTime const& qtm)
QUtil::int_to_string(qtm.second, 2) + tz_offset);
}
+std::string
+QUtil::qpdf_time_to_iso8601(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 (
+ QUtil::int_to_string(qtm.year, 4) + "-" +
+ QUtil::int_to_string(qtm.month, 2) + "-" +
+ QUtil::int_to_string(qtm.day, 2) + "T" +
+ 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)
{
@@ -1018,6 +1044,17 @@ QUtil::pdf_time_to_qpdf_time(std::string const& str, QPDFTime* qtm)
return true;
}
+bool
+QUtil::pdf_time_to_iso8601(std::string const& pdf_time, std::string& iso8601)
+{
+ QPDFTime qtm;
+ if (pdf_time_to_qpdf_time(pdf_time, &qtm)) {
+ iso8601 = qpdf_time_to_iso8601(qtm);
+ return true;
+ }
+ return false;
+}
+
std::string
QUtil::toUTF8(unsigned long uval)
{
diff --git a/libtests/qtest/qutil/qutil.out b/libtests/qtest/qutil/qutil.out
index d91acba9..48d22fb9 100644
--- a/libtests/qtest/qutil/qutil.out
+++ b/libtests/qtest/qutil/qutil.out
@@ -127,7 +127,10 @@ rename over existing
delete file
---- timestamp
D:20210209144925-05'00'
+2021-02-09T14:49:25-05:00
D:20210210011925+05'30'
+2021-02-10T01:19:25+05:30
D:20210209191925Z
+2021-02-09T19:19:25Z
---- is_long_long
done
diff --git a/libtests/qutil.cc b/libtests/qutil.cc
index ea0aece7..995a7599 100644
--- a/libtests/qutil.cc
+++ b/libtests/qutil.cc
@@ -656,10 +656,14 @@ timestamp_test()
{
auto check = [](QUtil::QPDFTime const& t) {
std::string pdf = QUtil::qpdf_time_to_pdf_time(t);
- std::cout << pdf << std::endl;
+ std::string iso8601 = QUtil::qpdf_time_to_iso8601(t);
+ std::cout << pdf << std::endl << iso8601 << std::endl;
QUtil::QPDFTime t2;
+ std::string iso8601_2;
assert(QUtil::pdf_time_to_qpdf_time(pdf, &t2));
assert(QUtil::qpdf_time_to_pdf_time(t2) == pdf);
+ assert(QUtil::pdf_time_to_iso8601(pdf, iso8601_2));
+ assert(iso8601 == iso8601_2);
};
check(QUtil::QPDFTime(2021, 2, 9, 14, 49, 25, 300));
check(QUtil::QPDFTime(2021, 2, 10, 1, 19, 25, -330));