exiv2 '-T' sets incorrect time when timezone is with daylight saving time in effect
Added by Anonymous Poster over 10 years ago
Recently I've observed a problem with exiv2 '-T' option in case of
daylight saving time. I'm using it for couple of years but saw this just
now. When time in exif data is read, one hour is added to the time when
daylight saving time is in effect.
The logic is in src/actions.cpp:
'int str2Tm(const std::string& timeStr, struct tm* tm)' converts the string
of the date to broken down struct tm. It is then converted to time_t with
timegm(struct tm tm). The resulted time_t variable is checked with -1 and
converted back to struct tm with gmtime_r or std::gmtime(time_t *t),
tm_isdst is modified by gmtime variant and set from -1 to 0 (no dst for GMT).
'int Timestamp::read(struct tm tm)' is called from ::run() to convert
struct tm to time_t value using mktime, which normalizes it. When the time
zone is with daylight saving time in effect it will set tm_isdst to 1.
Additionally it will increment tm_hour with 1, which is the reason for the
observed difference with 1 hour.
As I see there are two ways to fix this problem:
1) in 'int str2Tm(const std::string& timeStr, struct tm* tm)' - add
temporary struct tm variable and execute localtime to get the correct
tm_isdst flag, copy tm_isdt to the original tm, decrement tm_hour if
tm_isdst is set to compensate later conversion with mktime. If tm_hour is
0 make it 23, and so on for tm_mday and the other affected struct tm
members.
2) In 'int Timestamp::read(struct tm* tm)' - add check if tm_isdst=1 to
substract 3600 seconds from 't' to compensate mktime.
Variant 1) is better if there are many callers which use mktime or similar
timezone dependent function.
Variant 2) is a lot simpler and enough for this particular option of exiv2.
--- exiv2-0.21.1/src/actions.cpp 2011-02-13 16:39:15.000000000 0200
++ exiv2-0.21.1/src/actions.cpp 2011-04-24 02:33:16.199983003 0300@ -1742,6 +1742,8
@ namespace {
time_t t = mktime(tm);
if (t != (time_t)-1) {
rc = 0;
if (tm->tm_isdst && t >= 3600)
+ t -= 3600;
actime_ = t;
modtime_ = t;
}
Regards,
Boyan
Replies (4)
RE: exiv2 '-T' sets incorrect time when timezone is with daylight saving time in effect - Added by Andreas Huggel over 10 years ago
Thanks for the detailed report, Boyan. I've committed a fix with r2475.
RE: exiv2 '-T' sets incorrect time when timezone is with daylight saving time in effect - Added by Norbert Pätzold over 10 years ago
Thanks a lot for the quick fix!
I've been tampering around with the '-t' (lower case letter) option, which was also affected by the 1 hour time offset. As the problem is of the same nature as the with the '-T' option, Boyan's patch did it's magic there as well! :)
Please get the fix into an official version asop. Photographers living in DST-areas will be more than thankful ;-)
Regards,
Norbert.
RE: exiv2 '-T' sets incorrect time when timezone is with daylight saving time in effect - Added by Andreas Huggel over 10 years ago
Norbert, thanks for your feedback. Did you test with the trunk version or did you apply the patch from Boyan yourself?
(The fix in the trunk is different from the patch, I'd like to know if your report can be considered an additional test of my fix.)
Andreas
RE: exiv2 '-T' sets incorrect time when timezone is with daylight saving time in effect - Added by Norbert Pätzold over 10 years ago
Hi Andreas,
I checked out the svn-trunk three days ago last friday.
From there, I just ran
make config ./configure make make install
I tested both the '-t' and the '-T' options and they worked as described in the manpage. :)
On a side note, the '-r' option seems to be quite positional.
Observe:
$ exiv2 -v -r'%Y-%m-%d_%H-%M-%S' -t rename DSC_0001.NEF File 1/1: DSC_0001.NEF Filename format yields empty filename for the file DSC_0001.NEF
$ exiv2 -v -t -r'%Y-%m-%d_%H-%M-%S' rename DSC_0001.NEF File 1/1: DSC_0001.NEF Renaming file to ./2011-05-12_23-03-19.NEF, updating timestamp