Commit 64c07a20 authored by Brad Hards's avatar Brad Hards

qt4/src/poppler-qt4.h and qt4/src/poppler-document.cc: add convertDate() function that

turns char* PDF date strings into QDateTime. This version handles
the timezone conversions. Refactored the existing date() method
to use it.

qt4/tests/check_dateConversion.cpp: unit tests for convertDate()
qt4/tests/check_metadata.cpp: update to reflect UTC.
qt4/tests/.cvsignore: suppress check_dateConversion
parent 4b2e3b51
2005-12-27 Brad Hards <bradh@frogmouth.net>
* qt4/src/poppler-qt4.h:
* qt4/src/poppler-document.cc: add convertDate() function that
turns char* PDF date strings into QDateTime. This version handles
the timezone conversions. Refactored the existing date() method
to use it.
* qt4/tests/check_dateConversion.cpp: unit tests for convertDate()
* qt4/tests/check_metadata.cpp: update to reflect UTC.
* qt4/tests/.cvsignore: suppress check_dateConversion
* qt4/src/Doxyfile (JAVADOC_AUTOBRIEF): Turned on automatic
\brief mode.
......
......@@ -280,43 +280,15 @@ namespace Poppler {
char *s;
int year, mon, day, hour, min, sec;
Dict *infoDict = info.getDict();
QString result;
QDateTime result;
if ( infoDict->lookup( type.toLatin1().data(), &obj )->isString() )
{
s = obj.getString()->getCString();
if ( s[0] == 'D' && s[1] == ':' )
s += 2;
/* FIXME process time zone on systems that support it */
if ( sscanf( s, "%4d%2d%2d%2d%2d%2d", &year, &mon, &day, &hour, &min, &sec ) == 6 )
{
/* Workaround for y2k bug in Distiller 3 stolen from gpdf, hoping that it won't
* * be used after y2.2k */
if ( year < 1930 && strlen (s) > 14) {
int century, years_since_1900;
if ( sscanf( s, "%2d%3d%2d%2d%2d%2d%2d",
&century, &years_since_1900,
&mon, &day, &hour, &min, &sec) == 7 )
year = century * 100 + years_since_1900;
else {
obj.free();
info.free();
return QDateTime();
}
}
QDate d( year, mon, day ); //CHECK: it was mon-1, Jan->0 (??)
QTime t( hour, min, sec );
if ( d.isValid() && t.isValid() ) {
obj.free();
info.free();
return QDateTime( d, t );
}
}
result = Poppler::convertDate(obj.getString()->getCString());
}
obj.free();
info.free();
return QDateTime();
return result;
}
bool Document::isEncrypted() const
......@@ -390,4 +362,59 @@ namespace Poppler {
return page(index);
}
QDateTime convertDate( char *dateString )
{
int year;
int mon = 1;
int day = 1;
int hour = 0;
int min = 0;
int sec = 0;
char tz = 0x00;
int tzHours = 0;
int tzMins = 0;
if ( dateString[0] == 'D' && dateString[1] == ':' )
dateString += 2;
if ( sscanf( dateString,
"%4d%2d%2d%2d%2d%2d%c%2d%*c%2d",
&year, &mon, &day, &hour, &min, &sec,
&tz, &tzHours, &tzMins ) > 0 ) {
/* Workaround for y2k bug in Distiller 3 stolen from gpdf, hoping that it won't
* be used after y2.2k */
if ( year < 1930 && strlen (dateString) > 14) {
int century, years_since_1900;
if ( sscanf( dateString, "%2d%3d%2d%2d%2d%2d%2d",
&century, &years_since_1900,
&mon, &day, &hour, &min, &sec) == 7 )
year = century * 100 + years_since_1900;
else {
return QDateTime();
}
}
QDate d( year, mon, day );
QTime t( hour, min, sec );
if ( d.isValid() && t.isValid() ) {
QDateTime dt( d, t, Qt::UTC );
if ( tz ) {
// then we have some form of timezone
if ( 'Z' == tz ) {
// We are already at UTC
} else if ( '+' == tz ) {
// local time is ahead of UTC
dt = dt.addSecs(-1*((tzHours*60)+tzMins)*60);
} else if ( '-' == tz ) {
// local time is behind UTC
dt = dt.addSecs(((tzHours*60)+tzMins)*60);
} else {
qWarning("unexpected tz val");
}
}
return dt;
}
}
return QDateTime();
}
}
......@@ -531,6 +531,11 @@ delete pixmap;
Document::Document(DocumentData *dataA);
};
/**
Conversion from PDF date string format to QDateTime
*/
QDateTime convertDate( char *dateString );
}
#endif
......
......@@ -9,6 +9,7 @@ stress-poppler-qt4
test-poppler-qt4
test-password-qt4
poppler-fonts
check_dateConversion
check_fonts
check_metadata
check_permissions
......
......@@ -46,14 +46,19 @@ stress_poppler_qt4_LDADD = $(LDADDS)
if BUILD_POPPLER_QT4TESTS
TESTS = \
check_dateConversion \
check_fonts \
check_metadata \
check_permissions \
check_pagemode \
check_metadata \
check_permissions \
check_pagemode \
check_pagelayout
check_PROGRAMS = $(TESTS)
check_dateConversion_SOURCES = check_dateConversion.cpp
check_dateConversion.$(OBJEXT): check_dateConversion.moc
check_dateConversion_LDADD = $(UT_LDADDS)
check_fonts_SOURCES = check_fonts.cpp
check_fonts.$(OBJEXT): check_fonts.moc
check_fonts_LDADD = $(UT_LDADDS)
......
#include <QtTest/QtTest>
Q_DECLARE_METATYPE(QDate)
Q_DECLARE_METATYPE(QTime)
#define UNSTABLE_POPPLER_QT4
#include <poppler-qt4.h>
class TestDateConv: public QObject
{
Q_OBJECT
private slots:
void checkDates_data();
void checkDates();
};
void TestDateConv::checkDates_data()
{
qRegisterMetaType<QDate>("QDate");
qRegisterMetaType<QTime>("QTime");
QTest::addColumn<QByteArray>("input");
QTest::addColumn<QDate>("day");
QTest::addColumn<QTime>("time");
// This is a typical case - all data provided
QTest::newRow("D:20040101121110")
<< QByteArray("D:20040101121110Z")
<< QDate( 2004, 1, 1)
<< QTime( 12, 11, 10);
// The D: is strongly recommended, but optional
QTest::newRow("20040101121110")
<< QByteArray("20040101121110Z")
<< QDate( 2004, 1, 1)
<< QTime( 12, 11, 10);
// Only the year is actually required
QTest::newRow("D:2006")
<< QByteArray("D:2006")
<< QDate( 2006, 1, 1)
<< QTime( 0, 0, 0);
QTest::newRow("D:200602")
<< QByteArray("D:200602")
<< QDate( 2006, 2, 1)
<< QTime( 0, 0, 0);
QTest::newRow("D:20060304")
<< QByteArray("D:20060304")
<< QDate( 2006, 3, 4)
<< QTime( 0, 0, 0);
QTest::newRow("D:2006030405")
<< QByteArray("D:2006030405")
<< QDate( 2006, 3, 4)
<< QTime( 5, 0, 0);
QTest::newRow("D:200603040512")
<< QByteArray("D:200603040512")
<< QDate( 2006, 3, 4)
<< QTime( 5, 12, 0);
// If the timezone isn't specified, I assume UTC
QTest::newRow("D:20060304051226")
<< QByteArray("D:20060304051226")
<< QDate( 2006, 3, 4)
<< QTime( 5, 12, 26);
// Check for real timezone conversions
QTest::newRow("D:20030131115258-04'00'")
<< QByteArray("D:20030131115258-04'00'")
<< QDate( 2003, 1, 31)
<< QTime( 15, 52, 58);
QTest::newRow("D:20030131115258+05'00'")
<< QByteArray("D:20030131115258+05'00'")
<< QDate( 2003, 1, 31)
<< QTime( 6, 52, 58);
// There are places that have non-hour offsets
// Yep, that means you Adelaide.
QTest::newRow("D:20030131115258+08'30'")
<< QByteArray("D:20030131115258+08'30'")
<< QDate( 2003, 1, 31)
<< QTime( 3, 22, 58);
QTest::newRow("D:20030131115258-08'30'")
<< QByteArray("D:20030131115258-08'30'")
<< QDate( 2003, 1, 31)
<< QTime( 20, 22, 58);
}
void TestDateConv::checkDates()
{
QFETCH(QByteArray, input);
QFETCH(QDate, day);
QFETCH(QTime, time);
QCOMPARE( Poppler::convertDate(input.data()), QDateTime(day, time, Qt::UTC) );
}
QTEST_MAIN(TestDateConv)
#include "check_dateConversion.moc"
......@@ -129,8 +129,8 @@ void TestMetaData::checkDate()
doc = Poppler::Document::load("../../../test/unittestcases/truetype.pdf");
QVERIFY( doc );
QCOMPARE( doc->date("ModDate"), QDateTime(QDate(2005, 12, 5), QTime(20,44,46) ) );
QCOMPARE( doc->date("CreationDate"), QDateTime(QDate(2005, 8, 13), QTime(11,12,11) ) );
QCOMPARE( doc->date("ModDate"), QDateTime(QDate(2005, 12, 5), QTime(9,44,46), Qt::UTC ) );
QCOMPARE( doc->date("CreationDate"), QDateTime(QDate(2005, 8, 13), QTime(1,12,11), Qt::UTC ) );
}
void TestMetaData::checkPageSize()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment