Skip to content

Commit

Permalink
Merge pull request #651 from StefanOltmann/issue_628_fix
Browse files Browse the repository at this point in the history
Fixed wrong date/time when timezone is null
  • Loading branch information
drewnoakes authored Feb 4, 2024
2 parents 57dcbc1 + 130c8b3 commit 6aee7b3
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 110 deletions.
6 changes: 5 additions & 1 deletion Source/com/drew/metadata/Directory.java
Original file line number Diff line number Diff line change
Expand Up @@ -936,10 +936,14 @@ public java.util.Date getDate(int tagType, @Nullable String subsecond, @Nullable
*/
parser.setLenient(false);

/*
* If the metadata has set a time zone we use that, and otherwise
* we assume that computer and image belong to the same geographical area.
*/
if (timeZone != null)
parser.setTimeZone(timeZone);
else
parser.setTimeZone(TimeZone.getTimeZone("GMT")); // don't interpret zone time
parser.setTimeZone(TimeZone.getDefault());

date = parser.parse(dateString);
break;
Expand Down
4 changes: 2 additions & 2 deletions Tests/com/drew/imaging/png/PngMetadataReaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private static Metadata processFile(@NotNull String filePath) throws PngProcessi
@Test
public void testGimpGreyscaleWithManyChunks() throws Exception
{
TimeZone timeZone = TimeZone.getDefault();
TimeZone defaultTimeZone = TimeZone.getDefault();

try {
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
Expand Down Expand Up @@ -111,7 +111,7 @@ public void testGimpGreyscaleWithManyChunks() throws Exception
assertEquals("Comment", pairs.get(0).getKey().toString());
assertEquals("Created with GIMP", pairs.get(0).getValue().toString());
} finally {
TimeZone.setDefault(timeZone);
TimeZone.setDefault(defaultTimeZone);
}
}
}
144 changes: 76 additions & 68 deletions Tests/com/drew/metadata/DirectoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,88 +107,96 @@ public void testUnderlyingInt() throws Exception
@Test
public void testSetStringAndGetDate() throws Exception
{
String date1 = "2002:01:30 23:59:59";
String date2 = "2002:01:30 23:59";
String date3 = "2002-01-30 23:59:59";
String date4 = "2002-01-30 23:59";
String date5 = "2002-01-30T23:59:59.099-08:00";
String date6 = "2002-01-30T23:59:59.099";
String date7 = "2002-01-30T23:59:59-08:00";
String date8 = "2002-01-30T23:59:59";
String date9 = "2002-01-30T23:59-08:00";
String date10 = "2002-01-30T23:59";
String date11 = "2002-01-30";
String date12 = "2002-01";
String date13 = "2002";
_directory.setString(1, date1);
_directory.setString(2, date2);
_directory.setString(3, date3);
_directory.setString(4, date4);
_directory.setString(5, date5);
_directory.setString(6, date6);
_directory.setString(7, date7);
_directory.setString(8, date8);
_directory.setString(9, date9);
_directory.setString(10, date10);
_directory.setString(11, date11);
_directory.setString(12, date12);
_directory.setString(13, date13);
assertEquals(date1, _directory.getString(1));

// Don't use default timezone
TimeZone gmt = TimeZone.getTimeZone("GMT");
GregorianCalendar gc = new GregorianCalendar(gmt);
TimeZone defaultTimeZone = TimeZone.getDefault();

try {

TimeZone.setDefault(TimeZone.getTimeZone("GMT"));

String date1 = "2002:01:30 23:59:59";
String date2 = "2002:01:30 23:59";
String date3 = "2002-01-30 23:59:59";
String date4 = "2002-01-30 23:59";
String date5 = "2002-01-30T23:59:59.099-08:00";
String date6 = "2002-01-30T23:59:59.099";
String date7 = "2002-01-30T23:59:59-08:00";
String date8 = "2002-01-30T23:59:59";
String date9 = "2002-01-30T23:59-08:00";
String date10 = "2002-01-30T23:59";
String date11 = "2002-01-30";
String date12 = "2002-01";
String date13 = "2002";
_directory.setString(1, date1);
_directory.setString(2, date2);
_directory.setString(3, date3);
_directory.setString(4, date4);
_directory.setString(5, date5);
_directory.setString(6, date6);
_directory.setString(7, date7);
_directory.setString(8, date8);
_directory.setString(9, date9);
_directory.setString(10, date10);
_directory.setString(11, date11);
_directory.setString(12, date12);
_directory.setString(13, date13);
assertEquals(date1, _directory.getString(1));

GregorianCalendar gc = new GregorianCalendar();
// clear millis to 0 or test will fail
gc.setTimeInMillis(0);
gc.set(2002, GregorianCalendar.JANUARY, 30, 23, 59, 59);
assertEquals(gc.getTime(), _directory.getDate(1, null));
gc.setTimeInMillis(0);
gc.set(2002, GregorianCalendar.JANUARY, 30, 23, 59, 59);
assertEquals(gc.getTime(), _directory.getDate(1, null));

gc.set(2002, GregorianCalendar.JANUARY, 30, 23, 59, 0);
assertEquals(gc.getTime(), _directory.getDate(2, null));
gc.set(2002, GregorianCalendar.JANUARY, 30, 23, 59, 0);
assertEquals(gc.getTime(), _directory.getDate(2, null));

// Use specific timezone
TimeZone pst = TimeZone.getTimeZone("PST");
gc = new GregorianCalendar(pst);
gc.setTimeInMillis(0);
TimeZone pst = TimeZone.getTimeZone("PST");
gc = new GregorianCalendar(pst);
gc.setTimeInMillis(0);

gc.set(2002, GregorianCalendar.JANUARY, 30, 23, 59, 59);
assertEquals(gc.getTime(), _directory.getDate(3, pst));

gc.set(2002, GregorianCalendar.JANUARY, 30, 23, 59, 59);
assertEquals(gc.getTime(), _directory.getDate(3, pst));
gc.set(2002, GregorianCalendar.JANUARY, 30, 23, 59, 0);
assertEquals(gc.getTime(), _directory.getDate(4, pst));

gc.set(2002, GregorianCalendar.JANUARY, 30, 23, 59, 0);
assertEquals(gc.getTime(), _directory.getDate(4, pst));
gc.set(2002, GregorianCalendar.JANUARY, 30, 23, 59, 59);
gc.set(Calendar.MILLISECOND, 99);
assertEquals(gc.getTime(), _directory.getDate(5, null));
assertEquals(gc.getTime(), _directory.getDate(5, TimeZone.getDefault()));
assertEquals(gc.getTime(), _directory.getDate(6, pst));

gc.set(2002, GregorianCalendar.JANUARY, 30, 23, 59, 59);
gc.set(Calendar.MILLISECOND, 99);
assertEquals(gc.getTime(), _directory.getDate(5, null));
assertEquals(gc.getTime(), _directory.getDate(5, gmt));
assertEquals(gc.getTime(), _directory.getDate(6, pst));
assertEquals(gc.getTime(), _directory.getDate(5, "011", null));
assertEquals(gc.getTime(), _directory.getDate(6, "011", pst));
assertEquals(gc.getTime(), _directory.getDate(7, "099", null));
assertEquals(gc.getTime(), _directory.getDate(8, "099", pst));

assertEquals(gc.getTime(), _directory.getDate(5, "011", null));
assertEquals(gc.getTime(), _directory.getDate(6, "011", pst));
assertEquals(gc.getTime(), _directory.getDate(7, "099", null));
assertEquals(gc.getTime(), _directory.getDate(8, "099", pst));
gc.set(Calendar.MILLISECOND, 0);
assertEquals(gc.getTime(), _directory.getDate(7, null));
assertEquals(gc.getTime(), _directory.getDate(7, TimeZone.getDefault()));
assertEquals(gc.getTime(), _directory.getDate(8, pst));

gc.set(Calendar.MILLISECOND, 0);
assertEquals(gc.getTime(), _directory.getDate(7, null));
assertEquals(gc.getTime(), _directory.getDate(7, gmt));
assertEquals(gc.getTime(), _directory.getDate(8, pst));
gc.set(2002, GregorianCalendar.JANUARY, 30, 23, 59, 0);
assertEquals(gc.getTime(), _directory.getDate(9, null));
assertEquals(gc.getTime(), _directory.getDate(9, TimeZone.getDefault()));
assertEquals(gc.getTime(), _directory.getDate(10, pst));

gc.set(2002, GregorianCalendar.JANUARY, 30, 23, 59, 0);
assertEquals(gc.getTime(), _directory.getDate(9, null));
assertEquals(gc.getTime(), _directory.getDate(9, gmt));
assertEquals(gc.getTime(), _directory.getDate(10, pst));
gc = new GregorianCalendar();
gc.setTimeInMillis(0);

gc = new GregorianCalendar(gmt);
gc.setTimeInMillis(0);
gc.set(2002, GregorianCalendar.JANUARY, 30, 0, 0, 0);
assertEquals(gc.getTime(), _directory.getDate(11, null));

gc.set(2002, GregorianCalendar.JANUARY, 30, 0, 0, 0);
assertEquals(gc.getTime(), _directory.getDate(11, null));
gc.set(2002, GregorianCalendar.JANUARY, 1, 0, 0, 0);
assertEquals(gc.getTime(), _directory.getDate(12, null));

gc.set(2002, GregorianCalendar.JANUARY, 1, 0, 0, 0);
assertEquals(gc.getTime(), _directory.getDate(12, null));
gc.set(2002, GregorianCalendar.JANUARY, 1, 0, 0, 0);
assertEquals(gc.getTime(), _directory.getDate(13, null));

gc.set(2002, GregorianCalendar.JANUARY, 1, 0, 0, 0);
assertEquals(gc.getTime(), _directory.getDate(13, null));
} finally {
TimeZone.setDefault(defaultTimeZone);
}
}

@Test
Expand Down
74 changes: 42 additions & 32 deletions Tests/com/drew/metadata/exif/ExifDirectoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,38 +63,48 @@ public void testGetDirectoryName() throws Exception
@Test
public void testDateTime() throws JpegProcessingException, IOException, MetadataException
{
Metadata metadata = ExifReaderTest.processBytes("Tests/Data/nikonMakernoteType2a.jpg.app1");

ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
ExifSubIFDDirectory exifSubIFDDirectory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);

assertNotNull(exifIFD0Directory);
assertNotNull(exifSubIFDDirectory);

assertEquals("2003:10:15 10:37:08", exifIFD0Directory.getString(ExifIFD0Directory.TAG_DATETIME));
assertEquals("80", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_SUBSECOND_TIME));
assertEquals("2003:10:15 10:37:08", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL));
assertEquals("80", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_SUBSECOND_TIME_ORIGINAL));
assertEquals("2003:10:15 10:37:08", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_DATETIME_DIGITIZED));
assertEquals("80", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_SUBSECOND_TIME_DIGITIZED));

assertEquals(1066214228800L, exifIFD0Directory.getDate(
ExifIFD0Directory.TAG_DATETIME,
exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_SUBSECOND_TIME),
null
).getTime());
assertEquals(1066210628800L, exifIFD0Directory.getDate(
ExifIFD0Directory.TAG_DATETIME,
exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_SUBSECOND_TIME),
TimeZone.getTimeZone("GMT+0100")
).getTime());

assertEquals(1066214228800L, exifSubIFDDirectory.getDateModified().getTime());
assertEquals(1066210628800L, exifSubIFDDirectory.getDateModified(TimeZone.getTimeZone("GMT+0100")).getTime());
assertEquals(1066214228800L, exifSubIFDDirectory.getDateOriginal().getTime());
assertEquals(1066210628800L, exifSubIFDDirectory.getDateOriginal(TimeZone.getTimeZone("GMT+0100")).getTime());
assertEquals(1066214228800L, exifSubIFDDirectory.getDateDigitized().getTime());
assertEquals(1066210628800L, exifSubIFDDirectory.getDateDigitized(TimeZone.getTimeZone("GMT+0100")).getTime());
TimeZone defaultTimeZone = TimeZone.getDefault();

try {

TimeZone.setDefault(TimeZone.getTimeZone("GMT"));

Metadata metadata = ExifReaderTest.processBytes("Tests/Data/nikonMakernoteType2a.jpg.app1");

ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
ExifSubIFDDirectory exifSubIFDDirectory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);

assertNotNull(exifIFD0Directory);
assertNotNull(exifSubIFDDirectory);

assertEquals("2003:10:15 10:37:08", exifIFD0Directory.getString(ExifIFD0Directory.TAG_DATETIME));
assertEquals("80", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_SUBSECOND_TIME));
assertEquals("2003:10:15 10:37:08", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL));
assertEquals("80", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_SUBSECOND_TIME_ORIGINAL));
assertEquals("2003:10:15 10:37:08", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_DATETIME_DIGITIZED));
assertEquals("80", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_SUBSECOND_TIME_DIGITIZED));

assertEquals(1066214228800L, exifIFD0Directory.getDate(
ExifIFD0Directory.TAG_DATETIME,
exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_SUBSECOND_TIME),
null
).getTime());
assertEquals(1066210628800L, exifIFD0Directory.getDate(
ExifIFD0Directory.TAG_DATETIME,
exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_SUBSECOND_TIME),
TimeZone.getTimeZone("GMT+0100")
).getTime());

assertEquals(1066214228800L, exifSubIFDDirectory.getDateModified().getTime());
assertEquals(1066210628800L, exifSubIFDDirectory.getDateModified(TimeZone.getTimeZone("GMT+0100")).getTime());
assertEquals(1066214228800L, exifSubIFDDirectory.getDateOriginal().getTime());
assertEquals(1066210628800L, exifSubIFDDirectory.getDateOriginal(TimeZone.getTimeZone("GMT+0100")).getTime());
assertEquals(1066214228800L, exifSubIFDDirectory.getDateDigitized().getTime());
assertEquals(1066210628800L, exifSubIFDDirectory.getDateDigitized(TimeZone.getTimeZone("GMT+0100")).getTime());

} finally {
TimeZone.setDefault(defaultTimeZone);
}
}

@Test
Expand Down
26 changes: 19 additions & 7 deletions Tests/com/drew/metadata/icc/IccReaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.junit.Test;

import java.util.Arrays;
import java.util.TimeZone;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
Expand Down Expand Up @@ -73,15 +74,26 @@ public void testReadJpegSegments_InvalidData() throws Exception
@Test
public void testExtract_ProfileDateTime() throws Exception
{
byte[] app2Bytes = FileUtil.readBytes("Tests/Data/withExifAndIptc.jpg.app2");

Metadata metadata = new Metadata();
new IccReader().readJpegSegments(Arrays.asList(app2Bytes), metadata, JpegSegmentType.APP2);
TimeZone defaultTimeZone = TimeZone.getDefault();

IccDirectory directory = metadata.getFirstDirectoryOfType(IccDirectory.class);
try {

assertNotNull(directory);
assertEquals("1998:02:09 06:49:00", directory.getString(IccDirectory.TAG_PROFILE_DATETIME));
assertEquals(887006940000L, directory.getDate(IccDirectory.TAG_PROFILE_DATETIME).getTime());
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));

byte[] app2Bytes = FileUtil.readBytes("Tests/Data/withExifAndIptc.jpg.app2");

Metadata metadata = new Metadata();
new IccReader().readJpegSegments(Arrays.asList(app2Bytes), metadata, JpegSegmentType.APP2);

IccDirectory directory = metadata.getFirstDirectoryOfType(IccDirectory.class);

assertNotNull(directory);
assertEquals("1998:02:09 06:49:00", directory.getString(IccDirectory.TAG_PROFILE_DATETIME));
assertEquals(887006940000L, directory.getDate(IccDirectory.TAG_PROFILE_DATETIME).getTime());

} finally {
TimeZone.setDefault(defaultTimeZone);
}
}
}

0 comments on commit 6aee7b3

Please sign in to comment.