[NTG-pdftex] Patch CreationDate

Heiko Oberdiek oberdiek@uni-freiburg.de
Thu, 31 Jul 2003 21:45:16 +0200


--Qxx1br4bt0+wmkIi
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: 8bit

On Thu, Jul 31, 2003 at 06:59:04PM +0200, Martin Schroeder wrote:

> On 2003-07-31 17:04:06 +0200, Martin Schröder wrote:
> > I also tried leaving out the tz information in /CreationDate by
> > setting O to Z and leaving out the offset; but AR5 ignores any
> > offset and interprets the time as CEST. :-(
> 
> Thanks to Thomas I think I have a solution (idea borrowed from sendmail):
> 
> void printcreationdate()
> {
>     [...]
>     char time_str[20];

too small.

>     [...]
>     /* get the time zone offset */
>     gmt = *gmtime(&t);
>     off = (lt.tm_hour - gmt.tm_hour) * 60 + lt.tm_min - gmt.tm_min;

Not enough, lt and gmt can be different days.

>     [...]
> }

I found the sources of exim here, where I found a similar method,
but with checking of year and day. So I have attached a new patch.

Yours sincerely
  Heiko <oberdiek@uni-freiburg.de>
-- 
--Qxx1br4bt0+wmkIi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="utils.c.diff"

*** utils.c.org	Wed Jul 30 21:43:08 2003
--- utils.c	Thu Jul 31 21:36:50 2003
***************
*** 473,475 ****
--- 473,575 ----
      convertStringToHexString ((char*)digest, id);
      pdf_printf("/ID [%s %s]\n", id, id);
  }
+ 
+ /* Print the /CreationDate entry.
+ 
+   PDF Reference, third edition says about the expected date format:
+   <blockquote>
+     3.8.2 Dates
+ 
+       PDF defines a standard date format, which closely follows that of
+       the international standard ASN.1 (Abstract Syntax Notation One),
+       defined in ISO/IEC 8824 (see the Bibliography). A date is a string
+       of the form
+ 
+         (D:YYYYMMDDHHmmSSOHH'mm')
+ 
+       where
+ 
+         YYYY is the year
+         MM is the month
+         DD is the day (01-31)
+         HH is the hour (00-23)
+         mm is the minute (00-59)
+         SS is the second (00-59)
+         O is the relationship of local time to Universal Time (UT),
+           denoted by one of the characters +, -, or Z (see below)
+         HH followed by ' is the absolute value of the offset from UT
+           in hours (00-23)
+         mm followed by ' is the absolute value of the offset from UT
+           in minutes (00-59)
+ 
+       The apostrophe character (') after HH and mm is part of the syntax.
+       All elds after the year are optional. (The prefix D:, although also
+       optional, is strongly recommended.) The default values for MM and DD
+       are both 01; all other numerical elds default to zero values.  A plus
+       sign (+) as the value of the O field signifies that local time is
+       later than UT, a minus sign (-) that local time is earlier than UT,
+       and the letter Z that local time is equal to UT. If no UT information
+       is specified, the relationship of the specified time to UT is
+       considered to be unknown. Whether or not the time zone is known, the
+       rest of the date should be specified in local time.
+ 
+       For example, December 23, 1998, at 7:52 PM, U.S. Pacific Standard
+       Time, is represented by the string
+ 
+         D:199812231952-08'00'
+   </blockquote>
+ */
+ void printcreationdate()
+ {
+     time_t t;
+     struct tm lt, gmt;
+     size_t size;
+     /* minimum size for time_str is 22: "YYYYmmddHHMMSS+HH'MM'" */
+     char time_str[40]; /* larger value for safety */
+     int off, off_hours, off_mins;
+ 
+     /* get the time */
+     t = time(NULL);
+     lt = *localtime(&t);
+     size = strftime(time_str, sizeof(time_str), "%Y%m%d%H%M%S", &lt);
+     /* expected format: "YYYYmmddHHMMSS" */
+     if (size != 14) {
+         /* An unexpected result of strftime */
+         pdftex_warn("/CreationDate dropped because of "
+                     "unexpected result of strftime()");
+         return;
+     }
+ 
+     /* correction for seconds: %S can be in range 00..61,
+        the PDF reference expects 00..59,
+        therefore we map "60" and "61" to "59" */
+     if (time_str[12] == '6') {
+         time_str[12] = '5';
+         time_str[13] = '9'; /* we have checked for size above */
+     }
+ 
+     /* get the time zone offset */
+     gmt = *gmtime(&t);
+ 
+     /* this calculation method was found in exim's tod.c */
+     off = 60*(lt.tm_hour - gmt.tm_hour) + lt.tm_min - gmt.tm_min;
+     if (lt.tm_year != gmt.tm_year) {
+         off += (lt.tm_year > gmt.tm_year) ? 1440 : -1440;
+     }
+     else if (lt.tm_yday != gmt.tm_yday) {
+         off += (lt.tm_yday > gmt.tm_yday) ? 1440 : -1440;
+     }
+ 
+     if (off == 0) {
+         time_str[size++] = 'Z';
+         time_str[size] = 0;
+     }
+     else {
+         off_hours = off/60;
+         off_mins = abs(off - off_hours*60);
+         sprintf(&time_str[size], "%+03i'%02d'", off_hours, off_mins);
+     }
+ 
+     /* print result */
+     pdf_printf("/CreationDate (D:%s)\n", time_str);
+ }

--Qxx1br4bt0+wmkIi--