Commit 04fc7c4bea9b4efa38a7398b6db56a8fe5273bfb

Authored by Jay Berkenbilt
1 parent 6a7c4583

Add conversions to ISO-8601 date format

ChangeLog
  1 +2022-05-30 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Add QUtil::qpdf_time_to_iso8601 and QUtil::pdf_time_to_iso8601
  4 + for converting PDF/qpdf timestamps to ISO-8601 date format.
  5 +
1 6 2022-05-18 Jay Berkenbilt <ejb@ql.org>
2 7  
3 8 * Add QUtil::FileCloser to the public API. This is a simple inline
... ...
include/qpdf/QUtil.hh
... ... @@ -284,6 +284,10 @@ namespace QUtil
284 284 QPDF_DLL
285 285 std::string qpdf_time_to_pdf_time(QPDFTime const&);
286 286  
  287 + // Convert QPDFTime to a second-granularity ISO-8601 timestamp.
  288 + QPDF_DLL
  289 + std::string qpdf_time_to_iso8601(QPDFTime const&);
  290 +
287 291 // Convert a PDF timestamp string to a QPDFTime. If syntactically
288 292 // valid, return true and fill in qtm. If not valid, return false,
289 293 // and do not modify qtm. If qtm is null, just check the validity
... ... @@ -291,6 +295,11 @@ namespace QUtil
291 295 QPDF_DLL
292 296 bool pdf_time_to_qpdf_time(std::string const&, QPDFTime* qtm = nullptr);
293 297  
  298 + // Convert PDF timestamp to a second-granularity ISO-8601
  299 + // timestamp. If syntactically valid, return true and initialize
  300 + // iso8601. Otherwise, return false.
  301 + bool pdf_time_to_iso8601(std::string const& pdf_time, std::string& iso8601);
  302 +
294 303 // Return a string containing the byte representation of the UTF-8
295 304 // encoding for the unicode value passed in.
296 305 QPDF_DLL
... ...
libqpdf/QUtil.cc
... ... @@ -984,6 +984,32 @@ QUtil::qpdf_time_to_pdf_time(QPDFTime const&amp; qtm)
984 984 QUtil::int_to_string(qtm.second, 2) + tz_offset);
985 985 }
986 986  
  987 +std::string
  988 +QUtil::qpdf_time_to_iso8601(QPDFTime const& qtm)
  989 +{
  990 + std::string tz_offset;
  991 + int t = qtm.tz_delta;
  992 + if (t == 0) {
  993 + tz_offset = "Z";
  994 + } else {
  995 + if (t < 0) {
  996 + t = -t;
  997 + tz_offset += "+";
  998 + } else {
  999 + tz_offset += "-";
  1000 + }
  1001 + tz_offset += QUtil::int_to_string(t / 60, 2) + ":" +
  1002 + QUtil::int_to_string(t % 60, 2);
  1003 + }
  1004 + return (
  1005 + QUtil::int_to_string(qtm.year, 4) + "-" +
  1006 + QUtil::int_to_string(qtm.month, 2) + "-" +
  1007 + QUtil::int_to_string(qtm.day, 2) + "T" +
  1008 + QUtil::int_to_string(qtm.hour, 2) + ":" +
  1009 + QUtil::int_to_string(qtm.minute, 2) + ":" +
  1010 + QUtil::int_to_string(qtm.second, 2) + tz_offset);
  1011 +}
  1012 +
987 1013 bool
988 1014 QUtil::pdf_time_to_qpdf_time(std::string const& str, QPDFTime* qtm)
989 1015 {
... ... @@ -1018,6 +1044,17 @@ QUtil::pdf_time_to_qpdf_time(std::string const&amp; str, QPDFTime* qtm)
1018 1044 return true;
1019 1045 }
1020 1046  
  1047 +bool
  1048 +QUtil::pdf_time_to_iso8601(std::string const& pdf_time, std::string& iso8601)
  1049 +{
  1050 + QPDFTime qtm;
  1051 + if (pdf_time_to_qpdf_time(pdf_time, &qtm)) {
  1052 + iso8601 = qpdf_time_to_iso8601(qtm);
  1053 + return true;
  1054 + }
  1055 + return false;
  1056 +}
  1057 +
1021 1058 std::string
1022 1059 QUtil::toUTF8(unsigned long uval)
1023 1060 {
... ...
libtests/qtest/qutil/qutil.out
... ... @@ -127,7 +127,10 @@ rename over existing
127 127 delete file
128 128 ---- timestamp
129 129 D:20210209144925-05'00'
  130 +2021-02-09T14:49:25-05:00
130 131 D:20210210011925+05'30'
  132 +2021-02-10T01:19:25+05:30
131 133 D:20210209191925Z
  134 +2021-02-09T19:19:25Z
132 135 ---- is_long_long
133 136 done
... ...
libtests/qutil.cc
... ... @@ -656,10 +656,14 @@ timestamp_test()
656 656 {
657 657 auto check = [](QUtil::QPDFTime const& t) {
658 658 std::string pdf = QUtil::qpdf_time_to_pdf_time(t);
659   - std::cout << pdf << std::endl;
  659 + std::string iso8601 = QUtil::qpdf_time_to_iso8601(t);
  660 + std::cout << pdf << std::endl << iso8601 << std::endl;
660 661 QUtil::QPDFTime t2;
  662 + std::string iso8601_2;
661 663 assert(QUtil::pdf_time_to_qpdf_time(pdf, &t2));
662 664 assert(QUtil::qpdf_time_to_pdf_time(t2) == pdf);
  665 + assert(QUtil::pdf_time_to_iso8601(pdf, iso8601_2));
  666 + assert(iso8601 == iso8601_2);
663 667 };
664 668 check(QUtil::QPDFTime(2021, 2, 9, 14, 49, 25, 300));
665 669 check(QUtil::QPDFTime(2021, 2, 10, 1, 19, 25, -330));
... ...