Hello,
Patch CreationDate
If /CreationDate is not given by \pdfinfo, then a default is
used by computing the string by the current setting of
\year, \month, and \time.
Problem A:
The time zone is not set. See the discussion in
de.comp.text.tex, "[pdftex] Zeitzone von CreationDate"
Valentin Schwamberger observed that his AR/Windows shows then
the time as GMT.
Problem B:
It is easy to fool pdfTeX:
* Setting \year to a number less or greater than 4 digits.
* Setting \year, \month, \date, \time to invalid numbers,
eg.: \month=13
The result are invalid dates.
The following patch tries to solve these problems:
* Time zone detection by glibc's strftime("%z").
* The current time is used, not \year, \month, ...
Patch files based on 2003/07/30 v1.11a:
utils.c.diff for TeX/texk/web2c/pdftexdir/utils.c
pdftex.ch.diff for TeX/texk/web2c/pdftexdir/pdftex.ch
pdftex.defines.diff for TeX/texk/web2c/pdftexdir/pdftex.defines
Yours sincerely
Heiko
On 2003-07-30 22:08:11 +0200, Heiko Oberdiek wrote:
Patch files based on 2003/07/30 v1.11a: utils.c.diff for TeX/texk/web2c/pdftexdir/utils.c pdftex.ch.diff for TeX/texk/web2c/pdftexdir/pdftex.ch pdftex.defines.diff for TeX/texk/web2c/pdftexdir/pdftex.defines
Thanks! [...]
+ <blockquote> + %z The time-zone as hour offset from GMT. Required to + emit RFC822-conformant dates (using "%a, %d %b %Y + %H:%M:%S %z"). (GNU) + </blockquote> + Does this mean that the output of "%z" can have any RFC822-conformant + format?
Probably not. %Z gives names, %z only offsets. date(1) has this: %z RFC-822 style numeric timezone (-0500) (a nonstandard extension) I'll check the sources. Best regards Martin -- Martin Schröder, MS@ArtCom-GmbH.DE ArtCom GmbH, Lise-Meitner-Str 5, 28359 Bremen, Germany Voice +49 421 20419-44 / Fax +49 421 20419-10
On 2003-07-31 00:24:31 +0200, Martin Schröder wrote:
Probably not. %Z gives names, %z only offsets. date(1) has this: %z RFC-822 style numeric timezone (-0500) (a nonstandard extension)
%z is a GNU extension -- Solaris 2.5 doesn't have it. Best regards Martin -- Martin Schröder, MS@ArtCom-GmbH.DE ArtCom GmbH, Lise-Meitner-Str 5, 28359 Bremen, Germany Voice +49 421 20419-44 / Fax +49 421 20419-10
On 2003-07-31 12:11:41 +0200, Martin Schröder wrote:
On 2003-07-31 00:24:31 +0200, Martin Schröder wrote:
Probably not. %Z gives names, %z only offsets. date(1) has this: %z RFC-822 style numeric timezone (-0500) (a nonstandard extension)
%z is a GNU extension -- Solaris 2.5 doesn't have it.
Correction: ISO C99 Best regards Martin -- Martin Schröder, MS@ArtCom-GmbH.DE ArtCom GmbH, Lise-Meitner-Str 5, 28359 Bremen, Germany Voice +49 421 20419-44 / Fax +49 421 20419-10
On Thu, Jul 31, 2003 at 12:50:59PM +0200, Martin Schroeder wrote:
On 2003-07-31 12:11:41 +0200, Martin Schröder wrote:
On 2003-07-31 00:24:31 +0200, Martin Schröder wrote:
Probably not. %Z gives names, %z only offsets. date(1) has this: %z RFC-822 style numeric timezone (-0500) (a nonstandard extension)
%z is a GNU extension -- Solaris 2.5 doesn't have it.
Correction: ISO C99
I have not found, whether %z always results in the sign-four-digit format,
if it is supported. If yes, then most test for RFC-822 time zone
names could be dropped.
In my manual page it was marked as glibc extension, so other
systems without can miss support of %z. How the time zone difference
can be calculated there in a save way? Have to be used the following
procedure or are there better ways?
/* test.c */
#include
On 2003-07-31 14:37:19 +0200, Heiko Oberdiek wrote:
In my manual page it was marked as glibc extension, so other systems without can miss support of %z. How the time zone difference can be calculated there in a save way? Have to be used the following procedure or are there better ways?
There is. :-) <quote src=utils.c#13> The main difficulty is get the time zone offset. strftime() does this in ISO C99 (e.g. newer glibc) with %z, but we have to work with other systems (e.g. Solaris 2.5). So we must use localtime(), which sets the external variable timezone (either int or time_t) to the seconds since UTC. */ void printcreationdate() { time_t t; struct tm *tt; size_t size; char time_str[40]; int hours, minutes; /* get the time */ t = time(NULL); tt = localtime(&t); size = strftime(time_str, sizeof(time_str), "%Y%m%d%H%M%S", tt); /* expected format: "YYYYmmddHHMMSS" */ /* 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[13] != 0) { time_str[12] == '5'; time_str[13] == '9'; } /* get the time zone offset */ hours = ((long int)timezone)/3600; minutes = labs((long int)timezone) - (abs(hours) * 3600L); sprintf (&time_str[size], "%+03i'%02d'", hours, minutes); /* print result */ pdf_printf("/CreationDate (D:%s)\n", time_str); } </quote> The offset is off by one hour on Suse 7.0/7.1, but I regard this as a minor misfeature. :-) Best regards Martin -- Martin Schröder, MS@ArtCom-GmbH.DE ArtCom GmbH, Lise-Meitner-Str 5, 28359 Bremen, Germany Voice +49 421 20419-44 / Fax +49 421 20419-10
On Thu, Jul 31, 2003 at 02:56:52PM +0200, Martin Schroeder wrote:
On 2003-07-31 14:37:19 +0200, Heiko Oberdiek wrote:
In my manual page it was marked as glibc extension, so other systems without can miss support of %z. How the time zone difference can be calculated there in a save way? Have to be used the following procedure or are there better ways?
There is. :-)
<quote src=utils.c#13> The main difficulty is get the time zone offset. strftime() does this in ISO C99 (e.g. newer glibc) with %z, but we have to work with other systems (e.g. Solaris 2.5). So we must use localtime(), which sets the external variable timezone (either int or time_t) to the seconds since UTC. */ void printcreationdate() { time_t t; struct tm *tt; size_t size; char time_str[40]; int hours, minutes;
/* get the time */ t = time(NULL); tt = localtime(&t); size = strftime(time_str, sizeof(time_str), "%Y%m%d%H%M%S", tt); /* expected format: "YYYYmmddHHMMSS" */
/* 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[13] != 0) { time_str[12] == '5'; time_str[13] == '9'; }
/* get the time zone offset */ hours = ((long int)timezone)/3600; minutes = labs((long int)timezone) - (abs(hours) * 3600L); sprintf (&time_str[size], "%+03i'%02d'", hours, minutes);
* Not really, the minutes are seconds ...
* timezone: GMT - Localtime? But wanted is: Localtime - GMT?
/* test.c */
#include
The offset is off by one hour on Suse 7.0/7.1, but I regard this as a minor misfeature. :-)
This is the reason, why I have not used it. The same here (SuSE 7.2),
the test file generates:
+01'00'
But
$ date --rfc-822
Don, 31 Jul 2003 16:00:21 +0200
The same under SunOS Release 5.7:
+01'00'
My man page says:
| The localtime() function converts the calendar time timep
| to broken-time representation, expressed relative to the
| user's specified time zone. The function sets the
| external variables tzname with information about the cur
| rent time zone, timezone with the difference between Coor
| dinated Universal Time (UTC) and local standard time in
| seconds, and daylight to a non-zero value if standard US
| daylight savings time rules apply.
Perhaps we have to take daylight into account in some way:
if (daylight) {
diff_minutes += 60;
}
Yours sincerely
Heiko
On 2003-07-31 16:11:15 +0200, Heiko Oberdiek wrote:
Perhaps we have to take daylight into account in some way:
if (daylight) { diff_minutes += 60; }
Can we be sure that the daylight offset is always and everywhere 60 minutes? Also it conforms to "standard US daylight savings time rules" -- whatever that may be. I experimented with gmtime, mktime and difftime: gtm = gmtime(&tt); gt = mktime(gtm); seconds = (long int) difftime(tt, gt); fprintf(stderr, "\nseconds: %li\n", seconds); hours = seconds/3600; minutes = (labs(seconds) - (abs(hours) * 3600L))/60; sprintf (&time_str[size], "%+03i'%02d'", hours, minutes); But seconds is 3600 while it should be 7200. :-( 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. :-( Best regards Martin -- Martin Schröder, MS@ArtCom-GmbH.DE ArtCom GmbH, Lise-Meitner-Str 5, 28359 Bremen, Germany Voice +49 421 20419-44 / Fax +49 421 20419-10
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() { time_t t; struct tm lt, gmt; size_t size; char time_str[20]; int off, hours, minutes; /* get the time */ t = time(NULL); lt = *localtime(&t); size = strftime(time_str, sizeof(time_str), "%Y%m%d%H%M%S", <); /* expected format: "YYYYmmddHHMMSS" */ /* 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'; } /* get the time zone offset */ gmt = *gmtime(&t); off = (lt.tm_hour - gmt.tm_hour) * 60 + lt.tm_min - gmt.tm_min; #ifdef DEBUG fprintf(stderr, "\noff: %i\n", off); #endif hours = off/60; minutes = (abs(off) - (abs(hours) * 60))/60; sprintf (&time_str[size], "%+03i'%02d'", hours, minutes); /* print result */ pdf_printf("/CreationDate (D:%s)\n", time_str); } off is 120. :-) Best regards Martin -- Martin Schröder, MS@ArtCom-GmbH.DE ArtCom GmbH, Lise-Meitner-Str 5, 28359 Bremen, Germany Voice +49 421 20419-44 / Fax +49 421 20419-10
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
Hello,
it would be nice, if the same time could be used for
initialization of \year, \month, \day, and \time
as for the default /CreationDate.
The initialization of \year, ... is done in function
get_date_and_time() in files "pdf(e)texextra.c" that
are automatically generated in the Makefile from
file "lib/texmfmp.c". That would make such a patch a little
nasty.
The local variable "clock" of get_date_and_time()
could be stored in a global variable that is reused
by printcreationdate() instead of calling time(NULL) again.
Yours sincerely
Heiko
Hi, since we're patching some time thingies, how about: \pdfhours \pdfminutes \pdfseconds \pdfmilliseconds currently the \time has a one minute precission, which in these days of fast machines is too low a resolution Hans ------------------------------------------------------------------------- Hans Hagen | PRAGMA ADE | pragma@wxs.nl Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: +31 (0)38 477 53 69 | fax: +31 (0)38 477 53 74 | www.pragma-ade.com ------------------------------------------------------------------------- information: http://www.pragma-ade.com/roadmap.pdf documentation: http://www.pragma-ade.com/showcase.pdf -------------------------------------------------------------------------
On 2003-08-02 23:30:00 +0200, Hans Hagen wrote:
since we're patching some time thingies, how about:
\pdfhours \pdfminutes \pdfseconds \pdfmilliseconds
currently the \time has a one minute precission, which in these days of fast machines is too low a resolution
Nice to have, but in the next version. 1.11a is _finished_. :-) This also falls into the category of non-pdf extensions, which would best be done with eTeX. If eTeX would evolve, that is. :-( Best regards Martin -- Martin Schröder, MS@ArtCom-GmbH.DE ArtCom GmbH, Lise-Meitner-Str 5, 28359 Bremen, Germany Voice +49 421 20419-44 / Fax +49 421 20419-10
On Mon, Aug 04, 2003 at 09:53:24AM +0200, Martin Schroeder wrote:
On 2003-08-02 23:30:00 +0200, Hans Hagen wrote:
since we're patching some time thingies, how about:
\pdfhours \pdfminutes \pdfseconds \pdfmilliseconds
And some kind of timezone information, for example the difference in minutes to GMT.
currently the \time has a one minute precission, which in these days of fast machines is too low a resolution
Nice to have, but in the next version. 1.11a is _finished_. :-)
This also falls into the category of non-pdf extensions, which would best be done with eTeX. If eTeX would evolve, that is. :-(
Similar problem with \(pdf)shellescape*. We can wait many
years for the best names and solutions or do it know in
the \pdf-namespace.
Yours sincerely
Heiko
On 2003-08-09 20:48:35 +0200, Heiko Oberdiek wrote:
On Mon, Aug 04, 2003 at 09:53:24AM +0200, Martin Schroeder wrote:
This also falls into the category of non-pdf extensions, which would best be done with eTeX. If eTeX would evolve, that is. :-(
Similar problem with \(pdf)shellescape*. We can wait many years for the best names and solutions or do it know in the \pdf-namespace.
I'll ask Peter if there is any chance of progess for eTeX. Best regards Martin -- Martin Schröder, MS@ArtCom-GmbH.DE ArtCom GmbH, Lise-Meitner-Str 5, 28359 Bremen, Germany Voice +49 421 20419-44 / Fax +49 421 20419-10
At 20:48 09/08/2003 +0200, Heiko Oberdiek wrote:
On Mon, Aug 04, 2003 at 09:53:24AM +0200, Martin Schroeder wrote:
On 2003-08-02 23:30:00 +0200, Hans Hagen wrote:
since we're patching some time thingies, how about:
\pdfhours \pdfminutes \pdfseconds \pdfmilliseconds
And some kind of timezone information, for example the difference in minutes to GMT.
currently the \time has a one minute precission, which in these days of fast machines is too low a resolution
Nice to have, but in the next version. 1.11a is _finished_. :-)
This also falls into the category of non-pdf extensions, which would best be done with eTeX. If eTeX would evolve, that is. :-(
Similar problem with \(pdf)shellescape*. We can wait many years for the best names and solutions or do it know in the \pdf-namespace.
indeed, apart from endless discussions -) Hans ------------------------------------------------------------------------- Hans Hagen | PRAGMA ADE | pragma@wxs.nl Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: +31 (0)38 477 53 69 | fax: +31 (0)38 477 53 74 | www.pragma-ade.com ------------------------------------------------------------------------- information: http://www.pragma-ade.com/roadmap.pdf documentation: http://www.pragma-ade.com/showcase.pdf -------------------------------------------------------------------------
On 2003-07-31 21:45:16 +0200, Heiko Oberdiek wrote:
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.
Thanks. It has passed QA and I have found no glaring bugs -- so it's in (#3513). Best regards Martin -- Martin Schröder, MS@ArtCom-GmbH.DE ArtCom GmbH, Lise-Meitner-Str 5, 28359 Bremen, Germany Voice +49 421 20419-44 / Fax +49 421 20419-10
On Wed, Jul 30, 2003 at 10:08:11PM +0200, Heiko Oberdiek wrote:
Patch CreationDate
utils.c.diff for TeX/texk/web2c/pdftexdir/utils.c
First bug fix:
+ if (zone_str[12] == '6' && zone_str[13] != 0) { + zone_str[12] == '5'; + zone_str[13] == '9'; + }
Should read:
+ if (zone_str[12] == '6' && zone_str[13] != 0) {
+ zone_str[12] = '5';
+ zone_str[13] = '9';
+ }
Explanation for "zone_str[13] != 0":
I check here not for '0' and '1' explicitly, but also for
other don't care cases to save one test. ("6X" with all
possible X except '\0').
The string end test is needed for safety, because it
would be overwritten by "zone_str[13] = '9';
Yours sincerely
Heiko
On 2003-07-31 14:15:31 +0200, Heiko Oberdiek wrote:
+ if (zone_str[12] == '6' && zone_str[13] != 0) { + zone_str[12] = '5'; + zone_str[13] = '9'; + }
s/zone_str/time_str/ :-) Best regards Martin -- Martin Schröder, MS@ArtCom-GmbH.DE ArtCom GmbH, Lise-Meitner-Str 5, 28359 Bremen, Germany Voice +49 421 20419-44 / Fax +49 421 20419-10
On Thu, Jul 31, 2003 at 02:54:18PM +0200, Martin Schroeder wrote:
On 2003-07-31 14:15:31 +0200, Heiko Oberdiek wrote:
+ if (zone_str[12] == '6' && zone_str[13] != 0) { + zone_str[12] = '5'; + zone_str[13] = '9'; + }
s/zone_str/time_str/ :-)
Yes, second bug.
Yours sincerely
Heiko
participants (3)
-
Hans Hagen
-
Heiko Oberdiek
-
Martin Schroeder