Commit 04fc7c4bea9b4efa38a7398b6db56a8fe5273bfb
1 parent
6a7c4583
Add conversions to ISO-8601 date format
Showing
5 changed files
with
59 additions
and
1 deletions
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& 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& 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)); | ... | ... |