karlgoethebier has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,

i need to set CreateDate and ModifyDate of a many PDFs to the mtime of each particular file.

I must preserve the timestamp of the files.

I tried this:

#!/usr/bin/env perl use strict; use warnings; use POSIX qw (strftime); use Path::Iterator::Rule; use Image::ExifTool; my $dir = q(./pdf); my $tz = strftime( "%z", localtime() ); # my $tz = strftime( "%z", gmtime() ); $tz =~ s/(\d{2})$/':$1'/; my $rule = Path::Iterator::Rule->new; # $rule->file('*.pdf'); # :-( $rule->file->name(qr/.+\.pdf/); $rule->max_depth(1); my $next = $rule->iter($dir); while ( defined( my $file = $next->() ) ) { my $mtime = ( stat($file) )[9]; my $atime = ( stat($file) )[8]; my ( $m_sec, $m_min, $m_hour, $m_day, $m_month, $m_year ) = ( localtime($mtime) )[ 0, 1, 2, 3, 4, 5 ]; # ( gmtime($mtime) )[ 0, 1, 2, 3, 4, 5 ]; $m_year += 1900; my $m_timestamp = sprintf( "%4d:%02d:%02d %02d:%02d:%02d", $m_year, $m_month, $m_day, $m_hour, $m_min, $m_sec ); $m_timestamp .= $tz; my $exifTool = Image::ExifTool->new(); $exifTool->SetNewValue( "ModifyDate", $m_timestamp ); $exifTool->SetNewValue( "CreateDate", $m_timestamp ); $exifTool->WriteInfo($file); utime $atime, $mtime, $file; } __END__

This ends so:

karls-mac-mini:monks karl$ perl -MImage::ExifTool=:Public -E 'say Imag +eInfo("./pdf/a.pdf")->{CreateDate};' 2015:01:07 14:46:51 karls-mac-mini:monks karl$ ls -hl ./pdf/a.pdf -rw-r--r-- 1 karl karl 48K 7 Feb 14:46 ./pdf/a.pdf

I guess this is one month off target.

What do i miss?

Update: Reset state to [UNSOLVED]

Update 2: It seems like this works:

#!/usr/bin/env perl use strict; use warnings; use POSIX qw (strftime); use Path::Iterator::Rule; use Image::ExifTool; my $dir = q(./pdf); my $rule = Path::Iterator::Rule->new; # $rule->file('*.pdf'); # :-( $rule->file->name(qr/.+\.pdf/); $rule->max_depth(1); my $next = $rule->iter($dir); while ( defined( my $file = $next->() ) ) { my $mtime = ( stat($file) )[9]; my $atime = ( stat($file) )[8]; my $m_timestamp = strftime( "%Y:%m:%d %H:%M:%S%z", localtime($mtim +e) ); my $exifTool = Image::ExifTool->new(); + $exifTool->SetNewValue( "ModifyDate", $m_timestamp ); $exifTool->SetNewValue( "CreateDate", $m_timestamp ); $exifTool->WriteInfo($file); utime $atime, $mtime, $file; } __END__

Edit: Fixed wrong rules.

Update 3: Set state to SOLVED again.

Thank you very much for any hint and best regards, Karl

«The Crux of the Biscuit is the Apostrophe»

Replies are listed 'Best First'.
Re: How To Modify PDF Metadata
by hippo (Archbishop) on Jun 13, 2015 at 14:42 UTC

    The months returned from localtime are in the range 0-11, so where you add 1900 to the year you should also add 1 to the month.

      Thank you very much hippo for advice.

      For my rehabilitation i would like to say that i was a bit confused about this issue. I observed different behavior of my code on Win, Linux and Mac. And the various timestamp formats that one can pass to PDFs are a mess and put me over the edge. Perhaps i didn't see the basic problem and jumped to some wrong conclusions ;-).

      For completeness:

      "$mday is the day of the month and $mon the month in the range 0..11..."
      karls-mac-mini:monks karl$ perl -E '$day=(localtime)[3]; say $day;' 13 karls-mac-mini:monks karl$ perl -E '$month=(localtime)[4]; say $month; +' 5 karls-mac-mini:monks karl$ perl -E '$month=(localtime)[4]; say ++$mont +h;' 6 karls-mac-mini:monks karl$ date +%m 06

      D'oh!

      Update: I just run my modified code on a PDF created on Win:

      CreationDate was 06.06.2015 16:12 and now it is 06.06.2015 18:12.

      This crap drives me insane.

      Edit: Minor changes. Ain't no fun no more.

      Best regards, Karl

      «The Crux of the Biscuit is the Apostrophe»

        Hmm, not sure to understand exactly your problem, but this two-hours difference may be the difference between localtime (time in the local time zone) and gmtime (UTC time), which is two hours in the time zone where both you and I live.

        Or did I miss the point?

      "...add 1 to the month."

      Update:

      Well, i say $m_month += 1; but i still get 2015:01:07 14:46:51

      karls-mac-mini:monks karl$ perl -MImage::ExifTool=:Public -E 'say Imag +eInfo("./pdf/a.pdf")->{CreateDate};' 2015:02:07 14:46:51 karls-mac-mini:monks karl$ ls ./pdf/a.pdf -rw-r--r--@ 1 karl karl 48K 7 Feb 14:46 ./pdf/a.pdf

      Best regards, Karl

      «The Crux of the Biscuit is the Apostrophe»

        "...what you want to use for date math..."

        Yes and no.

        Despite my annoying mistake: I used Date::Calc until someone told me it's API is inferior and that the new kid on the block is much cooler.

        So i crucify myself with the manpage.

        And why should i use .45 if .22 does the job less expensive:

        karls-mac-mini:monks karl$ perl -MPOSIX=strftime -E 'say strftime("%Y +:%m:%d %H:%M:%S%z", localtime() );' 2015:06:14 19:42:10+0200

        Best regards, Karl

        «The Crux of the Biscuit is the Apostrophe»