diff --git a/src/actions.cpp b/src/actions.cpp index 28bdff1f..5e578351 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -100,12 +100,12 @@ namespace { // returns 0 if successful int str2Tm(const std::string& timeStr, struct tm* tm); - // Convert a string "YYYY:MM:DD HH:MI:SS" to a UTC time, -1 on error - time_t str2Time(const std::string& timeStr); - // Convert a UTC time to a string "YYYY:MM:DD HH:MI:SS", "" on error std::string time2Str(time_t time); + // Convert a tm structure to a string "YYYY:MM:DD HH:MI:SS", "" on error + std::string tm2Str(struct tm* tm); + /*! @brief Copy metadata from source to target according to Params::copyXyz @@ -1428,7 +1428,10 @@ namespace Action { int Adjust::run(const std::string& path) try { - adjustment_ = Params::instance().adjustment_; + adjustment_ = Params::instance().adjustment_; + yearAdjustment_ = Params::instance().yodAdjust_[Params::yodYear].adjustment_; + monthAdjustment_ = Params::instance().yodAdjust_[Params::yodMonth].adjustment_; + dayAdjustment_ = Params::instance().yodAdjust_[Params::yodDay].adjustment_; if (!Exiv2::fileExists(path, true)) { std::cerr << path @@ -1491,21 +1494,69 @@ namespace Action { << ek << "' " << _("not set\n"); return 1; } - time_t time = str2Time(timeStr); - if (time == (time_t)-1) { - std::cerr << path << ": " << _("Failed to parse or convert timestamp") << " `" + if (Params::instance().verbose_) { + bool comma = false; + std::cout << _("Adjusting") << " `" << ek << "' " << _("by"); + if (yearAdjustment_ != 0) { + std::cout << (yearAdjustment_ < 0 ? " " : " +") << yearAdjustment_ << " "; + if (yearAdjustment_ < -1 || yearAdjustment_ > 1) { + std::cout << _("years"); + } + else { + std::cout << _("year"); + } + comma = true; + } + if (monthAdjustment_ != 0) { + if (comma) std::cout << ","; + std::cout << (monthAdjustment_ < 0 ? " " : " +") << monthAdjustment_ << " "; + if (monthAdjustment_ < -1 || monthAdjustment_ > 1) { + std::cout << _("months"); + } + else { + std::cout << _("month"); + } + comma = true; + } + if (dayAdjustment_ != 0) { + if (comma) std::cout << ","; + std::cout << (dayAdjustment_ < 0 ? " " : " +") << dayAdjustment_ << " "; + if (dayAdjustment_ < -1 || dayAdjustment_ > 1) { + std::cout << _("days"); + } + else { + std::cout << _("day"); + } + comma = true; + } + if (adjustment_ != 0) { + if (comma) std::cout << ","; + std::cout << " " << adjustment_ << _("s"); + } + } + struct tm tm; + if (str2Tm(timeStr, &tm) != 0) { + if (Params::instance().verbose_) std::cout << std::endl; + std::cerr << path << ": " << _("Failed to parse timestamp") << " `" << timeStr << "'\n"; return 1; } - if (Params::instance().verbose_) { - std::cout << _("Adjusting") << " `" << ek << "' " << _("by") - << (adjustment_ < 0 ? " " : " +") - << adjustment_ << _(" s to "); + const long monOverflow = (tm.tm_mon + monthAdjustment_) / 12; + tm.tm_mon = (tm.tm_mon + monthAdjustment_) % 12; + tm.tm_year += yearAdjustment_ + monOverflow; + // Let's not create files with non-4-digit years, we can't read them. + if (tm.tm_year > 9999 - 1900 || tm.tm_year < 1000 - 1900) { + if (Params::instance().verbose_) std::cout << std::endl; + std::cerr << path << ": " << _("Can't adjust timestamp by") << " " + << yearAdjustment_ + monOverflow + << " " << _("years") << "\n"; + return 1; } - time += adjustment_; + time_t time = timegm(&tm); + time += adjustment_ + dayAdjustment_ * 86400; timeStr = time2Str(time); if (Params::instance().verbose_) { - std::cout << timeStr << std::endl; + std::cout << " " << _("to") << " " << timeStr << std::endl; } md->setValue(timeStr); return 0; @@ -1659,17 +1710,14 @@ namespace { return 0; } // str2Tm - time_t str2Time(const std::string& timeStr) - { - struct tm tm; - if (str2Tm(timeStr, &tm) != 0) return (time_t)-1; - time_t t = timegm(&tm); - return t; - } - std::string time2Str(time_t time) { struct tm* tm = gmtime(&time); + return tm2Str(tm); + } // time2Str + + std::string tm2Str(struct tm* tm) + { if (0 == tm) return ""; std::ostringstream os; @@ -1682,7 +1730,7 @@ namespace { << std::setw(2) << tm->tm_sec; return os.str(); - } // time2Str + } // tm2Str int metacopy(const std::string& source, const std::string& target, diff --git a/src/actions.hpp b/src/actions.hpp index 1eb10c88..835ff1e7 100644 --- a/src/actions.hpp +++ b/src/actions.hpp @@ -218,6 +218,10 @@ namespace Action { const std::string& path) const; long adjustment_; + long yearAdjustment_; + long monthAdjustment_; + long dayAdjustment_; + }; // class Adjust /*! diff --git a/src/exiv2.1 b/src/exiv2.1 index ec09e0e2..0e7e1e4f 100644 --- a/src/exiv2.1 +++ b/src/exiv2.1 @@ -3,7 +3,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH EXIV2 1 "December 12th, 2007" +.TH EXIV2 1 "December 23rd, 2007" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -57,8 +57,9 @@ different formats. Modification commands can be applied on-the-fly. Delete image metadata from the files. .TP .B ad | adjust -Adjust Exif timestamps by the given time. Requires option \fB\-a\fP -\fItime\fP. +Adjust Exif timestamps by the given time. Requires at least one of the +options \fB\-a\fP \fItime\fP, \fB\-Y\fP \fIyrs\fP, \fB\-O\fP +\fImon\fP or \fB\-D\fP \fIday\fP. .TP .B mo | modify Apply commands to modify (add, set, delete) the Exif, IPTC and XMP @@ -122,6 +123,18 @@ Time adjustment in the format [\-]HH[:MM[:SS]]. This option is only used with the 'adjust' action. Examples: 1 adds one hour, 1:01 adds one hour and one minute, \-0:00:30 subtracts 30 seconds. .TP +.B \-Y \fIyrs\fP +Time adjustment by a positive or negative number of years, for +the 'adjust' action. +.TP +.B \-O \fImon\fP +Time adjustment by a positive or negative number of months, for +the 'adjust' action. +.TP +.B \-D \fIday\fP +Time adjustment by a positive or negative number of days, for +the 'adjust' action. +.TP .B \-p \fImode\fP Print mode for the 'print' action. Possible modes are: .br diff --git a/src/exiv2.cpp b/src/exiv2.cpp index 91784abe..c9f850ac 100644 --- a/src/exiv2.cpp +++ b/src/exiv2.cpp @@ -165,6 +165,12 @@ int main(int argc, char* const argv[]) // class Params Params* Params::instance_ = 0; +const Params::YodAdjust Params::emptyYodAdjust_[] = { + { false, "-Y", 0 }, + { false, "-O", 0 }, + { false, "-D", 0 }, +}; + Params& Params::instance() { if (0 == instance_) { @@ -211,8 +217,8 @@ void Params::help(std::ostream& os) const { usage(os); os << _("\nActions:\n") - << _(" ad | adjust Adjust Exif timestamps by the given time. This\n" - " action requires the option -a time.\n") + << _(" ad | adjust Adjust Exif timestamps by the given time. This action\n" + " requires at least one of the -a, -Y, -O or -D options.\n") << _(" pr | print Print image metadata.\n") << _(" rm | delete Delete image metadata from the files.\n") << _(" in | insert Insert metadata from corresponding *.exv files.\n" @@ -240,6 +246,9 @@ void Params::help(std::ostream& os) const << _(" -F Do not prompt before renaming files (Force).\n") << _(" -a time Time adjustment in the format [-]HH[:MM[:SS]]. This option\n" " is only used with the 'adjust' action.\n") + << _(" -Y yrs Year adjustment with the 'adjust' action.\n") + << _(" -O mon Month adjustment with the 'adjust' action.\n") + << _(" -D day Day adjustment with the 'adjust' action.\n") << _(" -p mode Print mode for the 'print' action. Possible modes are:\n") << _(" s : print a summary of the Exif metadata (the default)\n") << _(" t : interpreted (translated) Exif data (shortcut for -Pkyct)\n") @@ -307,6 +316,9 @@ int Params::option(int opt, const std::string& optarg, int optopt) case 't': rc = evalRename(opt, optarg); break; case 'T': rc = evalRename(opt, optarg); break; case 'a': rc = evalAdjust(optarg); break; + case 'Y': rc = evalYodAdjust(yodYear, optarg); break; + case 'O': rc = evalYodAdjust(yodMonth, optarg); break; + case 'D': rc = evalYodAdjust(yodDay, optarg); break; case 'p': rc = evalPrint(optarg); break; case 'P': rc = evalPrintCols(optarg); break; case 'd': rc = evalDelete(optarg); break; @@ -377,6 +389,12 @@ int Params::evalAdjust(const std::string& optarg) int rc = 0; switch (action_) { case Action::none: + case Action::adjust: + if (adjust_) { + std::cerr << progname() + << ": " << _("Ignoring surplus option -a") << " " << optarg << "\n"; + break; + } action_ = Action::adjust; adjust_ = parseTime(optarg, adjustment_); if (!adjust_) { @@ -385,10 +403,6 @@ int Params::evalAdjust(const std::string& optarg) rc = 1; } break; - case Action::adjust: - std::cerr << progname() - << ": " << _("Ignoring surplus option -a") << " " << optarg << "\n"; - break; default: std::cerr << progname() << ": " << _("Option -a is not compatible with a previous option\n"); @@ -398,6 +412,38 @@ int Params::evalAdjust(const std::string& optarg) return rc; } // Params::evalAdjust +int Params::evalYodAdjust(const Yod& yod, const std::string& optarg) +{ + int rc = 0; + switch (action_) { + case Action::none: // fall-through + case Action::adjust: + if (yodAdjust_[yod].flag_) { + std::cerr << progname() + << ": " << _("Ignoring surplus option") << " " + << yodAdjust_[yod].option_ << " " << optarg << "\n"; + break; + } + action_ = Action::adjust; + yodAdjust_[yod].flag_ = true; + if (!Util::strtol(optarg.c_str(), yodAdjust_[yod].adjustment_)) { + std::cerr << progname() << ": " << _("Error parsing") << " " + << yodAdjust_[yod].option_ << " " + << _("option argument") << " `" << optarg << "'\n"; + rc = 1; + } + break; + default: + std::cerr << progname() + << ": " << _("Option") << " " + << yodAdjust_[yod].option_ << " " + << _("is not compatible with a previous option\n"); + rc = 1; + break; + } + return rc; +} // Params::evalYodAdjust + int Params::evalPrint(const std::string& optarg) { int rc = 0; @@ -683,9 +729,13 @@ int Params::getopt(int argc, char* const argv[]) std::cerr << progname() << ": " << _("An action must be specified\n"); rc = 1; } - if (action_ == Action::adjust && !adjust_) { + if ( action_ == Action::adjust + && !adjust_ + && !yodAdjust_[yodYear].flag_ + && !yodAdjust_[yodMonth].flag_ + && !yodAdjust_[yodDay].flag_) { std::cerr << progname() << ": " - << _("Adjust action requires option -a time\n"); + << _("Adjust action requires at least one -a, -Y, -O or -D option\n"); rc = 1; } if ( action_ == Action::modify diff --git a/src/exiv2.hpp b/src/exiv2.hpp index bce57ddb..b284d6a5 100644 --- a/src/exiv2.hpp +++ b/src/exiv2.hpp @@ -145,6 +145,16 @@ public: //! Enumerates the policies to handle existing files in rename action enum FileExistsPolicy { overwritePolicy, renamePolicy, askPolicy }; + //! Enumerates year, month and day adjustments. + enum Yod { yodYear, yodMonth, yodDay }; + + //! Structure for year, month and day adjustment command line arguments. + struct YodAdjust { + bool flag_; //!< Adjustment flag. + const char* option_; //!< Adjustment option string. + long adjustment_; //!< Adjustment value. + }; + bool help_; //!< Help option flag. bool version_; //!< Version option flag. bool verbose_; //!< Verbose (talkative) option flag. @@ -163,6 +173,7 @@ public: int target_; //!< What common target to process. long adjustment_; //!< Adjustment in seconds. + YodAdjust yodAdjust_[3]; //!< Year, month and day adjustment info. std::string format_; //!< Filename format (-r option arg). bool formatSet_; //!< Whether the format is set with -r CmdFiles cmdFiles_; //!< Names of the modification command files @@ -173,12 +184,20 @@ public: std::string suffix_; //!< File extension of the file to insert Files files_; //!< List of non-option arguments. +private: + //! Pointer to the global Params object. + static Params* instance_; + //! Initializer for year, month and day adjustment info. + static const YodAdjust emptyYodAdjust_[]; + + bool first_; + private: /*! @brief Default constructor. Note that optstring_ is initialized here. The c'tor is private to force instantiation through instance(). */ - Params() : optstring_(":hVvfbuktTFa:r:p:P:d:e:i:c:m:M:l:S:"), + Params() : optstring_(":hVvfbuktTFa:Y:O:D:r:p:P:d:e:i:c:m:M:l:S:"), help_(false), version_(false), verbose_(false), @@ -197,7 +216,12 @@ private: adjustment_(0), format_("%Y%m%d_%H%M%S"), formatSet_(false), - first_(true) {} + first_(true) + { + yodAdjust_[yodYear] = emptyYodAdjust_[yodYear]; + yodAdjust_[yodMonth] = emptyYodAdjust_[yodMonth]; + yodAdjust_[yodDay] = emptyYodAdjust_[yodDay]; + } //! Prevent copy-construction: not implemented. Params(const Params& rhs); @@ -206,6 +230,7 @@ private: //@{ int evalRename(int opt, const std::string& optarg); int evalAdjust(const std::string& optarg); + int evalYodAdjust(const Yod& yod, const std::string& optarg); int evalPrint(const std::string& optarg); int evalPrintCols(const std::string& optarg); int evalDelete(const std::string& optarg); @@ -214,11 +239,6 @@ private: int evalModify(int opt, const std::string& optarg); //@} - //! Pointer to the global Params object. - static Params* instance_; - - bool first_; - public: /*! @brief Call Getopt::getopt() with optstring, to inititate command line diff --git a/test/data/exiv2-test.out b/test/data/exiv2-test.out index fc4abe5f..6464a078 100644 --- a/test/data/exiv2-test.out +++ b/test/data/exiv2-test.out @@ -27,8 +27,8 @@ Usage: exiv2 [ options ] [ action ] file ... Manipulate the Exif metadata of images. Actions: - ad | adjust Adjust Exif timestamps by the given time. This - action requires the option -a time. + ad | adjust Adjust Exif timestamps by the given time. This action + requires at least one of the -a, -Y, -O or -D options. pr | print Print image metadata. rm | delete Delete image metadata from the files. in | insert Insert metadata from corresponding *.exv files. @@ -57,6 +57,9 @@ Options: -F Do not prompt before renaming files (Force). -a time Time adjustment in the format [-]HH[:MM[:SS]]. This option is only used with the 'adjust' action. + -Y yrs Year adjustment with the 'adjust' action. + -O mon Month adjustment with the 'adjust' action. + -D day Day adjustment with the 'adjust' action. -p mode Print mode for the 'print' action. Possible modes are: s : print a summary of the Exif metadata (the default) t : interpreted (translated) Exif data (shortcut for -Pkyct) @@ -111,60 +114,60 @@ Adjust ------------------------------------------------------------------- File 1/15: exiv2-empty.jpg exiv2-empty.jpg: No Exif data found in the file File 2/15: exiv2-canon-powershot-s40.jpg -Adjusting `Exif.Image.DateTime' by -43261 s to 2003:12:14 00:00:43 -Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2003:12:14 00:00:43 -Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2003:12:14 00:00:43 +Adjusting `Exif.Image.DateTime' by -43261s to 2003:12:14 00:00:43 +Adjusting `Exif.Photo.DateTimeOriginal' by -43261s to 2003:12:14 00:00:43 +Adjusting `Exif.Photo.DateTimeDigitized' by -43261s to 2003:12:14 00:00:43 File 3/15: exiv2-nikon-e990.jpg -Adjusting `Exif.Image.DateTime' by -43261 s to 2000:05:06 02:05:44 -Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2000:05:06 02:05:44 -Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2000:05:06 02:05:44 +Adjusting `Exif.Image.DateTime' by -43261s to 2000:05:06 02:05:44 +Adjusting `Exif.Photo.DateTimeOriginal' by -43261s to 2000:05:06 02:05:44 +Adjusting `Exif.Photo.DateTimeDigitized' by -43261s to 2000:05:06 02:05:44 File 4/15: exiv2-nikon-d70.jpg -Adjusting `Exif.Image.DateTime' by -43261 s to 2004:03:29 22:42:45 -Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2004:03:29 22:42:45 -Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2004:03:29 22:42:45 +Adjusting `Exif.Image.DateTime' by -43261s to 2004:03:29 22:42:45 +Adjusting `Exif.Photo.DateTimeOriginal' by -43261s to 2004:03:29 22:42:45 +Adjusting `Exif.Photo.DateTimeDigitized' by -43261s to 2004:03:29 22:42:45 File 5/15: exiv2-nikon-e950.jpg -Adjusting `Exif.Image.DateTime' by -43261 s to 2001:04:05 23:50:39 -Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2001:04:05 23:50:39 -Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2001:04:05 23:50:39 +Adjusting `Exif.Image.DateTime' by -43261s to 2001:04:05 23:50:39 +Adjusting `Exif.Photo.DateTimeOriginal' by -43261s to 2001:04:05 23:50:39 +Adjusting `Exif.Photo.DateTimeDigitized' by -43261s to 2001:04:05 23:50:39 File 6/15: exiv2-canon-eos-300d.jpg -Adjusting `Exif.Image.DateTime' by -43261 s to 2003:09:25 20:18:50 -Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2003:09:25 20:18:50 -Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2003:09:25 20:18:50 +Adjusting `Exif.Image.DateTime' by -43261s to 2003:09:25 20:18:50 +Adjusting `Exif.Photo.DateTimeOriginal' by -43261s to 2003:09:25 20:18:50 +Adjusting `Exif.Photo.DateTimeDigitized' by -43261s to 2003:09:25 20:18:50 File 7/15: exiv2-kodak-dc210.jpg -Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2000:10:26 04:45:50 +Adjusting `Exif.Photo.DateTimeOriginal' by -43261s to 2000:10:26 04:45:50 File 8/15: exiv2-fujifilm-finepix-s2pro.jpg -Adjusting `Exif.Image.DateTime' by -43261 s to 2003:09:26 11:15:35 -Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2003:09:26 11:15:35 -Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2003:09:26 11:15:35 +Adjusting `Exif.Image.DateTime' by -43261s to 2003:09:26 11:15:35 +Adjusting `Exif.Photo.DateTimeOriginal' by -43261s to 2003:09:26 11:15:35 +Adjusting `Exif.Photo.DateTimeDigitized' by -43261s to 2003:09:26 11:15:35 File 9/15: exiv2-sigma-d10.jpg -Adjusting `Exif.Image.DateTime' by -43261 s to 2004:03:18 11:39:25 -Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2004:03:16 07:51:37 -Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2004:03:18 11:39:25 +Adjusting `Exif.Image.DateTime' by -43261s to 2004:03:18 11:39:25 +Adjusting `Exif.Photo.DateTimeOriginal' by -43261s to 2004:03:16 07:51:37 +Adjusting `Exif.Photo.DateTimeDigitized' by -43261s to 2004:03:18 11:39:25 File 10/15: exiv2-olympus-c8080wz.jpg -Adjusting `Exif.Image.DateTime' by -43261 s to 2004:02:08 09:37:44 -Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2004:02:08 09:37:44 -Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2004:02:08 09:37:44 +Adjusting `Exif.Image.DateTime' by -43261s to 2004:02:08 09:37:44 +Adjusting `Exif.Photo.DateTimeOriginal' by -43261s to 2004:02:08 09:37:44 +Adjusting `Exif.Photo.DateTimeDigitized' by -43261s to 2004:02:08 09:37:44 File 11/15: exiv2-panasonic-dmc-fz5.jpg -Adjusting `Exif.Image.DateTime' by -43261 s to 2005:02:18 21:20:16 -Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2005:02:18 21:20:16 -Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2005:02:18 21:20:16 +Adjusting `Exif.Image.DateTime' by -43261s to 2005:02:18 21:20:16 +Adjusting `Exif.Photo.DateTimeOriginal' by -43261s to 2005:02:18 21:20:16 +Adjusting `Exif.Photo.DateTimeDigitized' by -43261s to 2005:02:18 21:20:16 File 12/15: exiv2-sony-dsc-w7.jpg -Adjusting `Exif.Image.DateTime' by -43261 s to 2005:05:27 05:18:33 -Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2005:05:27 05:18:33 -Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2005:05:27 05:18:33 +Adjusting `Exif.Image.DateTime' by -43261s to 2005:05:27 05:18:33 +Adjusting `Exif.Photo.DateTimeOriginal' by -43261s to 2005:05:27 05:18:33 +Adjusting `Exif.Photo.DateTimeDigitized' by -43261s to 2005:05:27 05:18:33 File 13/15: exiv2-canon-eos-20d.jpg Warning: Makernote: Pointer to next IFD is out of bounds; ignored. -Adjusting `Exif.Image.DateTime' by -43261 s to 2006:08:02 09:52:00 -Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2006:08:02 09:52:00 -Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2006:08:02 09:52:00 +Adjusting `Exif.Image.DateTime' by -43261s to 2006:08:02 09:52:00 +Adjusting `Exif.Photo.DateTimeOriginal' by -43261s to 2006:08:02 09:52:00 +Adjusting `Exif.Photo.DateTimeDigitized' by -43261s to 2006:08:02 09:52:00 File 14/15: exiv2-canon-eos-d30.jpg -Adjusting `Exif.Image.DateTime' by -43261 s to 2000:10:04 01:54:04 -Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2000:10:04 01:54:04 -Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2000:10:04 01:54:04 +Adjusting `Exif.Image.DateTime' by -43261s to 2000:10:04 01:54:04 +Adjusting `Exif.Photo.DateTimeOriginal' by -43261s to 2000:10:04 01:54:04 +Adjusting `Exif.Photo.DateTimeDigitized' by -43261s to 2000:10:04 01:54:04 File 15/15: exiv2-canon-powershot-a520.jpg -Adjusting `Exif.Image.DateTime' by -43261 s to 2006:01:27 22:50:27 -Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2006:01:27 22:50:27 -Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2006:01:27 22:50:27 +Adjusting `Exif.Image.DateTime' by -43261s to 2006:01:27 22:50:27 +Adjusting `Exif.Photo.DateTimeOriginal' by -43261s to 2006:01:27 22:50:27 +Adjusting `Exif.Photo.DateTimeDigitized' by -43261s to 2006:01:27 22:50:27 Rename ------------------------------------------------------------------- File 1/15: exiv2-empty.jpg