From: Jeremias Maerki Date: Thu, 7 Feb 2008 15:42:03 +0000 (+0000) Subject: Bugfix for date formatting with negative time zones in the PDF's Info object. X-Git-Tag: fop-0_95beta~100 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=b3c8c500256e67344c6b4cc91c045a04e8e65e36;p=xmlgraphics-fop.git Bugfix for date formatting with negative time zones in the PDF's Info object. Update of xmlgraphics-commons-1.3.jar because of a similar bug with formatting dates in XMP. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@619461 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/lib/xmlgraphics-commons-1.3svn.jar b/lib/xmlgraphics-commons-1.3svn.jar index ea00555ef..0abad1c33 100644 Binary files a/lib/xmlgraphics-commons-1.3svn.jar and b/lib/xmlgraphics-commons-1.3svn.jar differ diff --git a/src/java/org/apache/fop/pdf/PDFObject.java b/src/java/org/apache/fop/pdf/PDFObject.java index f791791b7..d43ae71f1 100644 --- a/src/java/org/apache/fop/pdf/PDFObject.java +++ b/src/java/org/apache/fop/pdf/PDFObject.java @@ -26,6 +26,7 @@ import java.io.Writer; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; +import java.util.Locale; import java.util.TimeZone; import org.apache.commons.logging.Log; @@ -327,33 +328,34 @@ public abstract class PDFObject implements PDFWritable { } /** Formatting pattern for PDF date */ - protected static final SimpleDateFormat DATE_FORMAT - = new SimpleDateFormat("'D:'yyyyMMddHHmmss"); + protected static final SimpleDateFormat DATE_FORMAT; + static { + DATE_FORMAT = new SimpleDateFormat("'D:'yyyyMMddHHmmss", Locale.ENGLISH); + DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT")); + } + /** * Formats a date/time according to the PDF specification * (D:YYYYMMDDHHmmSSOHH'mm'). * @param time date/time value to format + * @param tz the time zone * @return the requested String representation */ - protected String formatDateTime(Date time) { - StringBuffer sb = new StringBuffer(); - sb.append(DATE_FORMAT.format(time)); - TimeZone tz = TimeZone.getDefault(); - Calendar cal = Calendar.getInstance(); + protected String formatDateTime(Date time, TimeZone tz) { + Calendar cal = Calendar.getInstance(tz, Locale.ENGLISH); cal.setTime(time); - int era = cal.get(Calendar.ERA); - int year = cal.get(Calendar.YEAR); - int month = cal.get(Calendar.MONTH); - int day = cal.get(Calendar.DAY_OF_MONTH); - int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); - int milliseconds = cal.get(Calendar.HOUR_OF_DAY) * 1000 * 60 * 60; - milliseconds += cal.get(Calendar.MINUTE) * 1000 * 60; - milliseconds += cal.get(Calendar.SECOND) * 1000; - milliseconds += cal.get(Calendar.MILLISECOND); + int offset = cal.get(Calendar.ZONE_OFFSET); + offset += cal.get(Calendar.DST_OFFSET); + + //DateFormat is operating on GMT so adjust for time zone offset + Date dt1 = new Date(time.getTime() + offset); + StringBuffer sb = new StringBuffer(); + sb.append(DATE_FORMAT.format(dt1)); + + offset /= (1000 * 60); //Convert to minutes - int offset = tz.getOffset(era, year, month, day, dayOfWeek, milliseconds); if (offset == 0) { sb.append('Z'); } else { @@ -362,9 +364,8 @@ public abstract class PDFObject implements PDFWritable { } else { sb.append('-'); } - final int HOUR = (1000 * 60 * 60); - int offsetHour = Math.abs(offset / HOUR); - int offsetMinutes = (offset - (offsetHour * HOUR)) / (1000 * 60); + int offsetHour = Math.abs(offset / 60); + int offsetMinutes = Math.abs(offset % 60); if (offsetHour < 10) { sb.append('0'); } @@ -379,4 +380,14 @@ public abstract class PDFObject implements PDFWritable { return sb.toString(); } + /** + * Formats a date/time according to the PDF specification. + * (D:YYYYMMDDHHmmSSOHH'mm'). + * @param time date/time value to format + * @return the requested String representation + */ + protected String formatDateTime(Date time) { + return formatDateTime(time, TimeZone.getDefault()); + } + } diff --git a/status.xml b/status.xml index 49b238a38..3b177b6f6 100644 --- a/status.xml +++ b/status.xml @@ -28,6 +28,9 @@ + + Bugfix for date formatting with negative time zones in the PDF's Info object. + Added an option to disable the default sRGB profile in PDF output for those who don't care about color fidelity, but care about PDF file size. diff --git a/test/java/org/apache/fop/UtilityCodeTestSuite.java b/test/java/org/apache/fop/UtilityCodeTestSuite.java index 679e16ce7..19d7d0266 100644 --- a/test/java/org/apache/fop/UtilityCodeTestSuite.java +++ b/test/java/org/apache/fop/UtilityCodeTestSuite.java @@ -19,6 +19,10 @@ package org.apache.fop; +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.apache.fop.pdf.PDFObjectTestCase; import org.apache.fop.traits.BorderPropsTestCase; import org.apache.fop.traits.TraitColorTestCase; import org.apache.fop.util.DataURIResolverTestCase; @@ -26,9 +30,6 @@ import org.apache.fop.util.ElementListUtilsTestCase; import org.apache.fop.util.PDFNumberTestCase; import org.apache.fop.util.UnitConvTestCase; -import junit.framework.Test; -import junit.framework.TestSuite; - /** * Test suite for FOP's utility classes. */ @@ -43,6 +44,7 @@ public class UtilityCodeTestSuite { "Test suite for FOP's utility classes"); //$JUnit-BEGIN$ suite.addTest(new TestSuite(PDFNumberTestCase.class)); + suite.addTest(new TestSuite(PDFObjectTestCase.class)); suite.addTest(new TestSuite(UnitConvTestCase.class)); suite.addTest(new TestSuite(TraitColorTestCase.class)); suite.addTest(new TestSuite(BorderPropsTestCase.class)); diff --git a/test/java/org/apache/fop/pdf/PDFObjectTestCase.java b/test/java/org/apache/fop/pdf/PDFObjectTestCase.java new file mode 100644 index 000000000..96ac728bd --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFObjectTestCase.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import junit.framework.TestCase; + +/** + * Tests the PDFObject class. + */ +public class PDFObjectTestCase extends TestCase { + + /** + * Tests date/time formatting in PDFObject. + * @throws Exception if an error occurs + */ + public void testDateFormatting() throws Exception { + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.ENGLISH); + cal.set(2008, Calendar.FEBRUARY, 07, 15, 11, 07); + cal.set(Calendar.MILLISECOND, 0); + Date dt = cal.getTime(); + + MyPDFObject obj = new MyPDFObject(); + String s = obj.formatDateTime(dt, TimeZone.getTimeZone("GMT")); + assertEquals("D:20080207151107Z", s); + s = obj.formatDateTime(dt, TimeZone.getTimeZone("GMT+02:00")); + assertEquals("D:20080207171107+02'00'", s); + s = obj.formatDateTime(dt, TimeZone.getTimeZone("GMT+02:30")); + assertEquals("D:20080207174107+02'30'", s); + s = obj.formatDateTime(dt, TimeZone.getTimeZone("GMT-08:00")); + assertEquals("D:20080207071107-08'00'", s); + } + + private class MyPDFObject extends PDFObject { + + } + +}