diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..62f495dfe
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/lightcrafts/src/main/java/com/lightcrafts/image/libs/LibRaw.java b/lightcrafts/src/main/java/com/lightcrafts/image/libs/LibRaw.java
index a61468878..d508b8611 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/image/libs/LibRaw.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/image/libs/LibRaw.java
@@ -10,8 +10,8 @@
import java.awt.*;
import java.awt.image.*;
import java.io.File;
+import java.time.*;
import java.util.Arrays;
-import java.util.Date;
public class LibRaw extends RawDecoder {
final String filePath;
@@ -215,8 +215,9 @@ public float getAperture() {
return aperture;
}
- public Date getCaptureDateTime() {
- return new Date(1000 * timestamp);
+ public ZonedDateTime getCaptureDateTime() {
+ // TODO: Is the libraw timestamp in UTC?
+ return ZonedDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneOffset.UTC);
}
public float getFocalLength() {
@@ -455,7 +456,13 @@ public static void main(String[] args) {
LibRaw libRaw = new LibRaw("/Stuff/Pictures/New Raw Support/Canon 450D/IMG_1598.CR2");
- System.out.println("LibRaw (p:" + libRaw.progress_flags + ", w:" + libRaw.process_warnings + ") - make: " + libRaw.make + ", model: " + libRaw.model + ", timestamp: " + new Date(1000 * libRaw.timestamp));
+ System.out.println(
+ "LibRaw (p:" + libRaw.progress_flags
+ + ", w:" + libRaw.process_warnings
+ + ") - make: " + libRaw.make
+ + ", model: " + libRaw.model
+ + ", timestamp: " + libRaw.timestamp + " (" + libRaw.getCaptureDateTime() + ")"
+ );
System.out.println("Filter pattern: " + libRaw.filter_pattern);
for (int i = 0; i < 4; i++)
diff --git a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/CIFFDirectory.java b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/CIFFDirectory.java
index 3b98527a3..2b5adf72c 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/CIFFDirectory.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/CIFFDirectory.java
@@ -2,9 +2,9 @@
package com.lightcrafts.image.metadata;
+import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.Map;
-import java.util.Date;
import java.util.ResourceBundle;
import com.lightcrafts.image.metadata.values.DateMetaValue;
@@ -130,7 +130,7 @@ public String getCameraModel() {
* {@inheritDoc}
*/
@Override
- public Date getCaptureDateTime() {
+ public ZonedDateTime getCaptureDateTime() {
final ImageMetaValue value = getValue( CIFF_CAPTURED_TIME );
return value instanceof DateMetaValue ?
((DateMetaValue)value).getDateValue() : null;
diff --git a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/CoreDirectory.java b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/CoreDirectory.java
index 3b5384b4a..e98e0c3da 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/CoreDirectory.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/CoreDirectory.java
@@ -19,6 +19,7 @@
import java.awt.*;
import java.awt.color.ICC_Profile;
import java.io.File;
+import java.time.ZonedDateTime;
import java.util.*;
import static com.lightcrafts.image.metadata.CoreTags.*;
@@ -26,6 +27,7 @@
import static com.lightcrafts.image.metadata.ImageOrientation.ORIENTATION_LANDSCAPE;
import static com.lightcrafts.image.metadata.ImageOrientation.ORIENTATION_UNKNOWN;
import static com.lightcrafts.image.metadata.XMPConstants.*;
+import static java.time.format.DateTimeFormatter.*;
/**
* A CoreDirectory
is-an {@link ImageMetadataDirectory} for
@@ -162,7 +164,7 @@ public String getCaption() {
* {@inheritDoc}
*/
@Override
- public Date getCaptureDateTime() {
+ public ZonedDateTime getCaptureDateTime() {
final ImageMetaValue value = getValue( CORE_CAPTURE_DATE_TIME );
return value != null ? ((DateMetaValue)value).getDateValue() : null;
}
@@ -189,7 +191,7 @@ public String getCopyright() {
* {@inheritDoc}
*/
@Override
- public Date getFileDateTime() {
+ public ZonedDateTime getFileDateTime() {
final ImageMetaValue value = getValue( CORE_FILE_DATE_TIME );
return value != null ? ((DateMetaValue)value).getDateValue() : null;
}
@@ -489,9 +491,7 @@ protected Collection toXMP( Document xmpDoc, String nsURI,
);
XMLUtil.setTextContentOf(
createDateElement,
- TextUtil.dateFormat(
- ISO_8601_DATE_FORMAT, captureDateValue.getDateValue()
- )
+ captureDateValue.getDateValue().format(ISO_LOCAL_DATE_TIME)
);
xapRDFDescElement.appendChild( createDateElement );
}
@@ -509,13 +509,13 @@ protected Collection toXMP( Document xmpDoc, String nsURI,
////////// MetadataDate & ModifyDate
- final Date now = new Date();
+ final var now = ZonedDateTime.now();
final Element metadataDateElement = xmpDoc.createElementNS(
XMP_XAP_NS, XMP_XAP_PREFIX + ":MetadataDate"
);
XMLUtil.setTextContentOf(
metadataDateElement,
- TextUtil.dateFormat( ISO_8601_DATE_FORMAT, now )
+ now.format(ISO_OFFSET_DATE_TIME)
);
xapRDFDescElement.appendChild( metadataDateElement );
final Element modifyDateElement = xmpDoc.createElementNS(
@@ -523,7 +523,7 @@ protected Collection toXMP( Document xmpDoc, String nsURI,
);
XMLUtil.setTextContentOf(
modifyDateElement,
- TextUtil.dateFormat( ISO_8601_DATE_FORMAT, now )
+ now.format(ISO_OFFSET_DATE_TIME)
);
xapRDFDescElement.appendChild( modifyDateElement );
@@ -675,7 +675,7 @@ private void addCaption( ImageMetadata metadata ) {
*/
private void addCaptureDateTime( ImageInfo imageInfo ) {
removeValue( CORE_CAPTURE_DATE_TIME );
- final Date date = imageInfo.getCurrentMetadata().getCaptureDateTime();
+ final var date = imageInfo.getCurrentMetadata().getCaptureDateTime();
if ( date != null )
putValue( CORE_CAPTURE_DATE_TIME, new DateMetaValue( date ) );
}
@@ -741,8 +741,7 @@ private void addFileInfo( ImageInfo imageInfo ) {
putValue( CORE_DIR_NAME , new StringMetaValue( parentDir ) );
putValue( CORE_FILE_NAME, new StringMetaValue( file.getName() ) );
putValue( CORE_FILE_SIZE, new UnsignedLongMetaValue( file.length() ) );
- final Date date = new Date( file.lastModified() );
- putValue( CORE_FILE_DATE_TIME, new DateMetaValue( date ) );
+ putValue( CORE_FILE_DATE_TIME, new DateMetaValue(file.lastModified()) );
removeValue( CORE_ORIGINAL_IMAGE_HEIGHT );
removeValue( CORE_ORIGINAL_IMAGE_WIDTH );
diff --git a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/DCRawMetadataReader.java b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/DCRawMetadataReader.java
index b8c075322..0db18bd75 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/DCRawMetadataReader.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/DCRawMetadataReader.java
@@ -2,16 +2,14 @@
package com.lightcrafts.image.metadata;
-import java.io.IOException;
-import java.util.Date;
-import java.util.stream.Stream;
-
import com.lightcrafts.image.ImageInfo;
import com.lightcrafts.image.metadata.values.*;
import com.lightcrafts.image.types.RawImageInfo;
import com.lightcrafts.utils.LightCraftsException;
import com.lightcrafts.utils.raw.RawDecoder;
+import java.io.IOException;
+
import static com.lightcrafts.image.metadata.EXIFTags.*;
/**
@@ -61,7 +59,7 @@ protected void readAllDirectories() throws IOException {
new UnsignedRationalMetaValue( (int)(aperture * 10), 10 )
);
- final Date captureDateTime = dcraw.getCaptureDateTime();
+ final var captureDateTime = dcraw.getCaptureDateTime();
if ( captureDateTime != null )
exifDir.putValue(
EXIF_DATE_TIME, new DateMetaValue( captureDateTime )
diff --git a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/EXIFDirectory.java b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/EXIFDirectory.java
index 161b20084..042faef3c 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/EXIFDirectory.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/EXIFDirectory.java
@@ -9,6 +9,7 @@
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import java.time.ZonedDateTime;
import java.util.*;
import java.util.stream.Stream;
@@ -106,7 +107,7 @@ public String getCaption() {
* {@inheritDoc}
*/
@Override
- public Date getCaptureDateTime() {
+ public ZonedDateTime getCaptureDateTime() {
ImageMetaValue value = getValue( EXIF_DATE_TIME_ORIGINAL );
if ( value == null )
value = getValue( EXIF_DATE_TIME_DIGITIZED );
diff --git a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/IPTCDirectory.java b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/IPTCDirectory.java
index 7393ebe19..eee00fa56 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/IPTCDirectory.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/IPTCDirectory.java
@@ -1,8 +1,10 @@
/* Copyright (C) 2005-2011 Fabio Riccardi */
+/* Copyright (C) 2023- Masahiro Kitagawa */
package com.lightcrafts.image.metadata;
import java.io.UnsupportedEncodingException;
+import java.time.ZonedDateTime;
import java.util.*;
import java.nio.ByteBuffer;
@@ -71,7 +73,7 @@ public String getArtist() {
* {@inheritDoc}
*/
@Override
- public Date getCaptureDateTime() {
+ public ZonedDateTime getCaptureDateTime() {
final ImageMetaValue value = getValue( IPTC_DATE_CREATED );
return value instanceof DateMetaValue ?
((DateMetaValue)value).getDateValue() : null;
@@ -636,6 +638,8 @@ private static void encodeTag( ByteBuffer buf, int tagID ) {
* {@link DateMetaValue} plus the time.
*/
private ImageMetaValue mergeDateTime( ImageMetaValue date, int timeTagID ) {
+ // TODO: There might be a better way to do this with ZonedDateTime.
+
final ImageMetaValue timeValue = getValue( timeTagID );
if ( timeValue == null )
return date;
@@ -674,12 +678,10 @@ private ImageMetaValue mergeDateTime( ImageMetaValue date, int timeTagID ) {
return date;
}
- final int delta = ((hh+zh) * 60 * 60 + (mm+zm) * 60 + ss) * 1000;
+ final int deltaSeconds = (hh+zh) * 60 * 60 + (mm+zm) * 60 + ss;
- final DateMetaValue newDateValue = (DateMetaValue)date.clone();
- final Date newDate = newDateValue.getDateValue();
- newDate.setTime( newDate.getTime() + delta );
- return newDateValue;
+ final var newDate = ((DateMetaValue)date).getDateValue().plusSeconds(deltaSeconds);
+ return new DateMetaValue(newDate);
}
catch ( NumberFormatException e ) {
return date;
diff --git a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/ImageMetadata.java b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/ImageMetadata.java
index 9666f4ce0..3caf6e530 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/ImageMetadata.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/ImageMetadata.java
@@ -1,4 +1,5 @@
/* Copyright (C) 2005-2011 Fabio Riccardi */
+/* Copyright (C) 2023- Masahiro Kitagawa */
package com.lightcrafts.image.metadata;
@@ -16,6 +17,7 @@
import org.w3c.dom.Element;
import java.io.*;
+import java.time.ZonedDateTime;
import java.util.*;
import static com.lightcrafts.image.metadata.CoreTags.*;
@@ -255,11 +257,11 @@ public String getCaption() {
/**
* {@inheritDoc}
*/
- public Date getCaptureDateTime() {
+ public ZonedDateTime getCaptureDateTime() {
final Collection dirs =
findProvidersOf( CaptureDateTimeProvider.class );
for ( ImageMetadataDirectory dir : dirs ) {
- final Date date =
+ final var date =
((CaptureDateTimeProvider)dir).getCaptureDateTime();
if ( date != null )
return date;
@@ -364,7 +366,8 @@ public File getFile() {
/**
* {@inheritDoc}
*/
- public Date getFileDateTime() {
+ @Override
+ public ZonedDateTime getFileDateTime() {
final CoreDirectory dir =
(CoreDirectory)getDirectoryFor( CoreDirectory.class );
return dir != null ? dir.getFileDateTime() : null;
diff --git a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/TIFFDirectory.java b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/TIFFDirectory.java
index a46b3866d..ac4df85dd 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/TIFFDirectory.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/TIFFDirectory.java
@@ -1,4 +1,5 @@
/* Copyright (C) 2005-2011 Fabio Riccardi */
+/* Copyright (C) 2023- Masahiro Kitagawa */
package com.lightcrafts.image.metadata;
@@ -15,6 +16,7 @@
import java.awt.image.RenderedImage;
import java.io.IOException;
+import java.time.ZonedDateTime;
import java.util.*;
import static com.lightcrafts.image.metadata.ImageMetaType.*;
@@ -87,7 +89,7 @@ public String getCaption() {
/**
* {@inheritDoc}
*/
- public Date getCaptureDateTime() {
+ public ZonedDateTime getCaptureDateTime() {
final ImageMetaValue value = getValue( TIFF_DATE_TIME );
return value instanceof DateMetaValue ?
((DateMetaValue)value).getDateValue() : null;
diff --git a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/XMPConstants.java b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/XMPConstants.java
index 7557f9593..652971143 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/XMPConstants.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/XMPConstants.java
@@ -1,11 +1,10 @@
/* Copyright (C) 2005-2011 Fabio Riccardi */
+/* Copyright (C) 2023- Masahiro Kitagawa */
package com.lightcrafts.image.metadata;
import com.lightcrafts.app.Application;
-import java.text.SimpleDateFormat;
-
/**
* XMPConstants
defines constants for XMP.
*
@@ -13,10 +12,6 @@
*/
public interface XMPConstants {
- /** This is the date format required by XMP. */
- SimpleDateFormat ISO_8601_DATE_FORMAT =
- new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss" );
-
/** The Dublin Core namespace URI. */
String XMP_DC_NS = "http://purl.org/dc/elements/1.1/";
diff --git a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/makernotes/PentaxDirectory.java b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/makernotes/PentaxDirectory.java
index 44b9788ae..c77407e42 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/makernotes/PentaxDirectory.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/makernotes/PentaxDirectory.java
@@ -1,4 +1,5 @@
/* Copyright (C) 2005-2011 Fabio Riccardi */
+/* Copyright (C) 2023- Masahiro Kitagawa */
package com.lightcrafts.image.metadata.makernotes;
@@ -17,6 +18,8 @@
import java.awt.image.RenderedImage;
import java.io.IOException;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
import java.util.*;
import java.util.regex.Pattern;
@@ -52,7 +55,7 @@ public float getAperture() {
* {@inheritDoc}
*/
@Override
- public Date getCaptureDateTime() {
+ public ZonedDateTime getCaptureDateTime() {
final ImageMetaValue value = getValue( PENTAX_DATE );
return value instanceof DateMetaValue ?
((DateMetaValue)value).getDateValue() : null;
@@ -277,11 +280,11 @@ public void putValue( Integer tagID, ImageMetaValue value ) {
return;
final byte[] buf =
((UndefinedMetaValue)value).getUndefinedValue();
- final Calendar cal = new GregorianCalendar(
- ((int)buf[0] & 0xFF) << 8 | (int)buf[1] & 0xFF,
- buf[2] - 1, buf[3]
- );
- value = new DateMetaValue( cal.getTime() );
+ final int year = ((int)buf[0] & 0xFF) << 8 | (int)buf[1] & 0xFF;
+ final int month = buf[2];
+ final int day = buf[3];
+ final var dateTime = ZonedDateTime.of(year, month, day, 0, 0, 0, 0, ZoneId.systemDefault());
+ value = new DateMetaValue(dateTime);
break;
}
case PENTAX_TIME: {
@@ -296,13 +299,14 @@ public void putValue( Integer tagID, ImageMetaValue value ) {
if (dateValue == null) {
return;
}
- final Date date = ((DateMetaValue)dateValue).getDateValue();
+ final var date = ((DateMetaValue)dateValue).getDateValue();
final byte[] buf =
((UndefinedMetaValue)value).getUndefinedValue();
- date.setTime(
- date.getTime() +
- (buf[0] * 60 * 60 + buf[1] * 60 + buf[2]) * 1000
- );
+ final var dateTime = date
+ .withHour(buf[0])
+ .withMinute(buf[1])
+ .withSecond(buf[2]);
+ super.putValue(PENTAX_DATE, new DateMetaValue(dateTime));
return;
}
case PENTAX_IMAGE_SIZE:
diff --git a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/providers/CaptureDateTimeProvider.java b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/providers/CaptureDateTimeProvider.java
index 6b11d8bf4..22e2651a7 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/providers/CaptureDateTimeProvider.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/providers/CaptureDateTimeProvider.java
@@ -1,8 +1,9 @@
/* Copyright (C) 2005-2011 Fabio Riccardi */
+/* Copyright (C) 2023- Masahiro Kitagawa */
package com.lightcrafts.image.metadata.providers;
-import java.util.Date;
+import java.time.ZonedDateTime;
/**
* A CaptureDateTimeProvider
provides the capture date/time of an
@@ -18,7 +19,7 @@ public interface CaptureDateTimeProvider extends ImageMetadataProvider {
* @return Returns the date/time or null
if no date/time is
* available.
*/
- Date getCaptureDateTime();
+ ZonedDateTime getCaptureDateTime();
}
/* vim:set et sw=4 ts=4: */
diff --git a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/providers/FileDateTimeProvider.java b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/providers/FileDateTimeProvider.java
index fd9f8d38d..59fba669a 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/providers/FileDateTimeProvider.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/providers/FileDateTimeProvider.java
@@ -1,8 +1,9 @@
/* Copyright (C) 2005-2011 Fabio Riccardi */
+/* Copyright (C) 2023- Masahiro Kitagawa */
package com.lightcrafts.image.metadata.providers;
-import java.util.Date;
+import java.time.ZonedDateTime;
/**
* A FileDateTimeProvider
provides the last modified date/time of
@@ -18,7 +19,7 @@ public interface FileDateTimeProvider extends ImageMetadataProvider {
* @return Returns the date/time or null
if no date/time is
* available.
*/
- Date getFileDateTime();
+ ZonedDateTime getFileDateTime();
}
/* vim:set et sw=4 ts=4: */
diff --git a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/values/DateMetaValue.java b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/values/DateMetaValue.java
index dd14a6d65..2c7b7d2a2 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/image/metadata/values/DateMetaValue.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/image/metadata/values/DateMetaValue.java
@@ -1,21 +1,24 @@
/* Copyright (C) 2005-2011 Fabio Riccardi */
+/* Copyright (C) 2023- Masahiro Kitagawa */
package com.lightcrafts.image.metadata.values;
+import com.lightcrafts.image.metadata.ImageMetaType;
+import com.lightcrafts.utils.xml.XMLUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
import java.util.Arrays;
-import java.util.Date;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import com.lightcrafts.image.metadata.ImageMetaType;
-import com.lightcrafts.utils.TextUtil;
-import com.lightcrafts.utils.xml.XMLUtil;
+import java.util.List;
+import java.util.stream.Collectors;
import static com.lightcrafts.image.metadata.ImageMetaType.META_DATE;
import static com.lightcrafts.image.metadata.XMPConstants.*;
@@ -43,7 +46,7 @@ public DateMetaValue() {
*
* @param values The array of values.
*/
- public DateMetaValue( Date... values ) {
+ public DateMetaValue(ZonedDateTime... values) {
m_value = values;
}
@@ -52,8 +55,8 @@ public DateMetaValue( Date... values ) {
*
* @param value The number of milliseconds since epoch.
*/
- public DateMetaValue( long value ) {
- this( new Date( value ) );
+ public DateMetaValue(long value) {
+ this(zonedDateTimeFromEpochMillis(value));
}
/**
@@ -80,48 +83,48 @@ public DateMetaValue clone() {
* {@inheritDoc}
*/
public int compareTo( Object o ) {
- if ( o instanceof DateMetaValue ) {
- final DateMetaValue rightVal = (DateMetaValue)o;
- final Date leftDate = getDateValue();
- final Date rightDate = rightVal.getDateValue();
+ if (o instanceof DateMetaValue rightVal) {
+ final var leftDate = getDateValue();
+ final var rightDate = rightVal.getDateValue();
return leftDate.compareTo( rightDate );
}
return super.compareTo( o );
}
/**
- * Get the first native {@link Date} array value.
+ * Get the first native {@link ZonedDateTime} array value.
*
* @return Returns said value.
*/
- public Date getDateValue() {
+ public ZonedDateTime getDateValue() {
return getDateValueAt(0);
}
/**
- * Gets the {@link Date} value at the given index.
+ * Gets the {@link ZonedDateTime} value at the given index.
*
* @param index The index of the value to get.
* @return Returns said value.
*/
- public Date getDateValueAt( int index ) {
+ public ZonedDateTime getDateValueAt( int index ) {
return m_value[ index ];
}
/**
- * Get the native {@link Date} array value.
+ * Get the native {@link ZonedDateTime} array value.
*
* @return Returns said array.
*/
- public Date[] getDateValues() {
+ public ZonedDateTime[] getDateValues() {
return m_value;
}
/**
* {@inheritDoc}
*/
+ @Override
public long getLongValueAt(int index) {
- return getDateValueAt(index).getTime();
+ return getDateValueAt(index).toInstant().toEpochMilli();
}
/**
@@ -154,15 +157,15 @@ public boolean isLegalValue( String value ) {
}
/**
- * Sets the {@link Date} value at the given index.
+ * Sets the {@link ZonedDateTime} value at the given index.
*
* @param newValue The new value.
* @param index The index to set the value of.
*/
- public synchronized void setDateValueAt( Date newValue, int index ) {
+ public synchronized void setDateValueAt(ZonedDateTime newValue, int index) {
checkIsEditable();
if ( m_value == null )
- m_value = new Date[ index + 1 ];
+ m_value = new ZonedDateTime[index + 1];
else if ( index >= m_value.length )
m_value = Arrays.copyOf(m_value, index + 1);
m_value[ index ] = newValue;
@@ -173,7 +176,7 @@ else if ( index >= m_value.length )
* {@inheritDoc}
*/
public void setLongValue( long newValue ) {
- setDateValueAt( new Date( newValue ), 0 );
+ setDateValueAt(zonedDateTimeFromEpochMillis(newValue), 0);
}
/**
@@ -183,27 +186,22 @@ public Element toXMP( Document xmpDoc, String nsURI, String prefix ) {
final String tagName = getTagName();
if ( tagName == null )
return null;
+ final var formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
final Element tagElement =
xmpDoc.createElementNS( nsURI, prefix + ':' + tagName );
- final Date[] values = getDateValues();
- if ( values.length == 1 )
- XMLUtil.setTextContentOf(
- tagElement,
- TextUtil.dateFormat( ISO_8601_DATE_FORMAT, m_value[0] )
- );
- else {
+ final ZonedDateTime[] values = getDateValues();
+ if (values.length == 1) {
+ XMLUtil.setTextContentOf(tagElement, m_value[0].format(formatter));
+ } else {
final Element seqElement = XMLUtil.addElementChildTo(
- tagElement, XMP_RDF_NS, XMP_RDF_PREFIX + ":Seq"
+ tagElement, XMP_RDF_NS, XMP_RDF_PREFIX + ":Seq"
);
- for ( Date value : values ) {
+ Arrays.stream(values).forEachOrdered(value -> {
final Element listItem = XMLUtil.addElementChildTo(
- seqElement, XMP_RDF_NS, XMP_RDF_PREFIX + ":li"
- );
- XMLUtil.setTextContentOf(
- listItem,
- TextUtil.dateFormat( ISO_8601_DATE_FORMAT, value )
+ seqElement, XMP_RDF_NS, XMP_RDF_PREFIX + ":li"
);
- }
+ XMLUtil.setTextContentOf(listItem, value.format(formatter));
+ });
}
return tagElement;
}
@@ -213,9 +211,10 @@ public Element toXMP( Document xmpDoc, String nsURI, String prefix ) {
*/
public void readExternal( ObjectInput in ) throws IOException {
final int length = readHeader( in );
- m_value = new Date[ length ];
- for ( int i = 0; i < length; ++i )
- m_value[i] = new Date( in.readLong() );
+ m_value = new ZonedDateTime[length];
+ for (int i = 0; i < length; i++) {
+ m_value[i] = zonedDateTimeFromEpochMillis(in.readLong());
+ }
}
/**
@@ -225,8 +224,8 @@ public void readExternal( ObjectInput in ) throws IOException {
*/
public void writeExternal( ObjectOutput out ) throws IOException {
writeHeader( out );
- for ( Date value : m_value )
- out.writeLong( value.getTime() );
+ for ( ZonedDateTime value : m_value )
+ out.writeLong( value.toInstant().toEpochMilli() );
}
////////// protected //////////////////////////////////////////////////////
@@ -239,12 +238,13 @@ public void writeExternal( ObjectOutput out ) throws IOException {
* a parsable date.
*/
protected void appendValueImpl( String newValue ) {
- final Date newDate = parseValue( newValue );
+ // TODO: This will be simplified if we declare the m_value as a non-null list.
+ final ZonedDateTime newDateTime = parseValue( newValue );
if ( m_value == null )
- m_value = new Date[] { newDate };
+ m_value = new ZonedDateTime[] { newDateTime };
else {
m_value = Arrays.copyOf( m_value, m_value.length + 1 );
- m_value[ m_value.length - 1 ] = newDate;
+ m_value[ m_value.length - 1 ] = newDateTime;
}
}
@@ -256,10 +256,9 @@ protected void appendValueImpl( String newValue ) {
protected String[] getValuesImpl() {
if ( m_value == null )
return null;
- final String[] value = new String[ m_value.length ];
- for ( int i = 0; i < m_value.length; ++i )
- value[i] = TextUtil.dateFormat( m_canonicalDateFormat, m_value[i] );
- return value;
+ return Arrays.stream(m_value)
+ .map(v -> v.format(m_canonicalDateFormatter))
+ .toArray(String[]::new);
}
/**
@@ -271,7 +270,7 @@ protected String[] getValuesImpl() {
*/
protected void setValuesImpl( String[] newValue ) {
if ( m_value == null || m_value.length != newValue.length )
- m_value = new Date[ newValue.length ];
+ m_value = new ZonedDateTime[ newValue.length ];
for ( int i = 0; i < newValue.length; ++i )
m_value[i] = parseValue( newValue[i] );
}
@@ -285,18 +284,9 @@ protected void setValuesImpl( String[] newValue ) {
protected String toStringImpl() {
if ( m_value == null )
return null;
- final StringBuilder sb = new StringBuilder();
- boolean comma = false;
- for ( Date value : m_value ) {
- if ( !comma )
- comma = true;
- else
- sb.append( ',' );
- sb.append(
- TextUtil.dateFormat( m_canonicalDateFormat, value ).trim()
- );
- }
- return sb.toString();
+ return Arrays.stream(m_value)
+ .map(v -> v.format(m_canonicalDateFormatter).trim())
+ .collect(Collectors.joining(","));
}
////////// private ////////////////////////////////////////////////////////
@@ -305,22 +295,22 @@ protected String toStringImpl() {
* Parse a date from a {@link String}.
*
* @param value The {@link String} to parse.
- * @return Returns a {link Date}.
+ * @return Returns a {link ZonedDateTime}.
* @throws IllegalArgumentException if the {@link String} does not contain
* a parsable date.
*/
- private static Date parseValue( String value ) {
+ private static ZonedDateTime parseValue( String value ) {
//
// Try parsing the value using all the expected date formats until one
// parses successfully.
//
- for ( SimpleDateFormat format : m_dateFormats )
+ for (final var formatter : m_dateFormatters) {
try {
- return format.parse( value );
- }
- catch ( ParseException e ) {
+ return ZonedDateTime.parse(value, formatter);
+ } catch (DateTimeParseException e) {
// ignore
}
+ }
throw new IllegalArgumentException();
}
@@ -328,25 +318,29 @@ private static Date parseValue( String value ) {
* The date format to use by default because this is apparently the
* format that cameras use for their date metadata.
*/
- private static final SimpleDateFormat m_canonicalDateFormat =
- new SimpleDateFormat( "yyyy:MM:dd HH:mm:ss" );
+ private static final DateTimeFormatter m_canonicalDateFormatter =
+ DateTimeFormatter.ofPattern("yyyy:MM:dd HH:mm:ss");
+
+ private static ZonedDateTime zonedDateTimeFromEpochMillis(long epochMillis) {
+ final var instant = Instant.ofEpochSecond(epochMillis);
+ return ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
+ }
/**
* Date formats to be able to parse.
*/
- private static final SimpleDateFormat[] m_dateFormats = {
- ISO_8601_DATE_FORMAT,
- m_canonicalDateFormat,
- new SimpleDateFormat( "EEE MMM dd HH:mm:ss zzz yyyy" ),
- new SimpleDateFormat( "yyyyMMdd" ), // IPTC date format
- new SimpleDateFormat( "yyyy-MM-dd" ),
- new SimpleDateFormat( "yyyy/MM/dd" ),
- new SimpleDateFormat( "dd-MMM-yyyy" ),
- new SimpleDateFormat( "dd/MMM/yyyy" ),
- new SimpleDateFormat( "MMM dd, yyyy" )
-
- };
-
- private Date[] m_value;
+ private static final List m_dateFormatters = Arrays.asList(
+ DateTimeFormatter.ISO_LOCAL_DATE_TIME,
+ m_canonicalDateFormatter,
+ DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy"),
+ DateTimeFormatter.BASIC_ISO_DATE, // IPTC date format
+ DateTimeFormatter.ISO_LOCAL_DATE,
+ DateTimeFormatter.ofPattern("yyyy/MM/dd"),
+ DateTimeFormatter.ofPattern("dd-MMM-yyyy"),
+ DateTimeFormatter.ofPattern("dd/MMM/yyyy"),
+ DateTimeFormatter.ofPattern("MMM dd, yyyy")
+ );
+
+ private ZonedDateTime[] m_value;
}
/* vim:set et sw=4 ts=4: */
diff --git a/lightcrafts/src/main/java/com/lightcrafts/image/types/RawImageCache.java b/lightcrafts/src/main/java/com/lightcrafts/image/types/RawImageCache.java
index 96cf6e49d..6732f4bfe 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/image/types/RawImageCache.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/image/types/RawImageCache.java
@@ -1,27 +1,26 @@
/* Copyright (C) 2005-2011 Fabio Riccardi */
+/* Copyright (C) 2023- Masahiro Kitagawa */
package com.lightcrafts.image.types;
-import java.awt.image.RenderedImage;
-import java.io.File;
-import java.io.IOException;
-import java.util.Date;
-
-import javax.media.jai.PlanarImage;
-
-import com.lightcrafts.utils.filecache.FileCache;
-import com.lightcrafts.utils.filecache.FileCacheFactory;
-import com.lightcrafts.utils.UserCanceledException;
-import com.lightcrafts.utils.thread.ProgressThread;
-import com.lightcrafts.image.libs.LCTIFFWriter;
+import com.lightcrafts.image.BadImageFileException;
+import com.lightcrafts.image.ImageInfo;
+import com.lightcrafts.image.UnknownImageTypeException;
import com.lightcrafts.image.libs.LCImageLibException;
import com.lightcrafts.image.libs.LCTIFFReader;
-import com.lightcrafts.image.metadata.TIFFTags;
+import com.lightcrafts.image.libs.LCTIFFWriter;
import com.lightcrafts.image.metadata.ImageMetadata;
-import com.lightcrafts.image.ImageInfo;
-import com.lightcrafts.image.BadImageFileException;
-import com.lightcrafts.image.UnknownImageTypeException;
+import com.lightcrafts.image.metadata.TIFFTags;
import com.lightcrafts.jai.JAIContext;
+import com.lightcrafts.utils.UserCanceledException;
+import com.lightcrafts.utils.filecache.FileCache;
+import com.lightcrafts.utils.filecache.FileCacheFactory;
+import com.lightcrafts.utils.thread.ProgressThread;
+
+import javax.media.jai.PlanarImage;
+import java.awt.image.RenderedImage;
+import java.io.File;
+import java.io.IOException;
/**
* TODO.
@@ -67,14 +66,14 @@ static String getCacheKeyFor( ImageInfo imageInfo )
throws BadImageFileException, IOException, UnknownImageTypeException
{
final ImageMetadata metadata = imageInfo.getMetadata();
- Date captureDate = metadata.getCaptureDateTime();
+ var captureDate = metadata.getCaptureDateTime();
if ( captureDate == null ) {
final RawImageInfo rawInfo = (RawImageInfo)imageInfo.getAuxiliaryInfo();
final var dcRaw = rawInfo.getRawDecoder();
captureDate = dcRaw.getCaptureDateTime();
}
if ( captureDate != null ) {
- final long time = captureDate.getTime();
+ final long time = captureDate.toInstant().toEpochMilli();
return imageInfo.getFile().getName() + time + version;
}
return null;
diff --git a/lightcrafts/src/main/java/com/lightcrafts/ui/metadata2/CaptureTimeMetadataEntry.java b/lightcrafts/src/main/java/com/lightcrafts/ui/metadata2/CaptureTimeMetadataEntry.java
index e390a3aac..c8ec4d5a2 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/ui/metadata2/CaptureTimeMetadataEntry.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/ui/metadata2/CaptureTimeMetadataEntry.java
@@ -1,4 +1,5 @@
/* Copyright (C) 2005-2011 Fabio Riccardi */
+/* Copyright (C) 2023- Masahiro Kitagawa */
package com.lightcrafts.ui.metadata2;
@@ -6,14 +7,15 @@
import com.lightcrafts.image.metadata.ImageMetadata;
import com.lightcrafts.image.metadata.CoreDirectory;
import com.lightcrafts.image.metadata.CoreTags;
-import com.lightcrafts.utils.TextUtil;
-import java.util.Date;
-import java.text.DateFormat;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
class CaptureTimeMetadataEntry extends SimpleMetadataEntry {
- private final static DateFormat Format = DateFormat.getDateTimeInstance();
+ private final static DateTimeFormatter formatter =
+ DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
+ .withLocale(java.util.Locale.getDefault());
CaptureTimeMetadataEntry() {
super(CoreDirectory.class, CoreTags.CORE_CAPTURE_DATE_TIME);
@@ -26,9 +28,9 @@ public String getLabel(ImageMetadata meta) {
public String getValue(ImageMetadata meta) {
final CoreDirectory dir = (CoreDirectory) meta.getDirectoryFor(clazz);
if (dir != null) {
- final Date date = dir.getCaptureDateTime();
+ final var date = dir.getCaptureDateTime();
if (date != null) {
- return TextUtil.dateFormat( Format, date );
+ return date.format(formatter);
}
}
return "";
diff --git a/lightcrafts/src/main/java/com/lightcrafts/ui/metadata2/FileTimeMetadataEntry.java b/lightcrafts/src/main/java/com/lightcrafts/ui/metadata2/FileTimeMetadataEntry.java
index 8f6e6d676..a9e47c964 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/ui/metadata2/FileTimeMetadataEntry.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/ui/metadata2/FileTimeMetadataEntry.java
@@ -1,4 +1,5 @@
/* Copyright (C) 2005-2011 Fabio Riccardi */
+/* Copyright (C) 2023- Masahiro Kitagawa */
package com.lightcrafts.ui.metadata2;
@@ -6,14 +7,15 @@
import com.lightcrafts.image.metadata.CoreDirectory;
import com.lightcrafts.image.metadata.CoreTags;
import com.lightcrafts.image.metadata.ImageMetadata;
-import com.lightcrafts.utils.TextUtil;
-import java.util.Date;
-import java.text.DateFormat;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
class FileTimeMetadataEntry extends SimpleMetadataEntry {
- private final static DateFormat Format = DateFormat.getDateTimeInstance();
+ private final static DateTimeFormatter formatter =
+ DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
+ .withLocale(java.util.Locale.getDefault());
FileTimeMetadataEntry() {
super(CoreDirectory.class, CoreTags.CORE_FILE_DATE_TIME);
@@ -26,9 +28,9 @@ public String getLabel(ImageMetadata meta) {
public String getValue(ImageMetadata meta) {
final CoreDirectory dir = (CoreDirectory) meta.getDirectoryFor(clazz);
if (dir != null) {
- final Date date = dir.getFileDateTime();
+ final var date = dir.getFileDateTime();
if (date != null) {
- return TextUtil.dateFormat( Format, date );
+ return date.format(formatter);
}
}
return "";
diff --git a/lightcrafts/src/main/java/com/lightcrafts/utils/TerseLoggingHandler.java b/lightcrafts/src/main/java/com/lightcrafts/utils/TerseLoggingHandler.java
index a3b61eb47..5cb8dc85f 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/utils/TerseLoggingHandler.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/utils/TerseLoggingHandler.java
@@ -1,13 +1,15 @@
/* Copyright (C) 2005-2011 Fabio Riccardi */
+/* Copyright (C) 2023- Masahiro Kitagawa */
package com.lightcrafts.utils;
-import java.text.MessageFormat;
-import java.util.Date;
+import java.io.OutputStream;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
import java.util.logging.StreamHandler;
-import java.io.OutputStream;
public class TerseLoggingHandler extends StreamHandler {
@@ -27,47 +29,39 @@ public void close() {
class TerseLoggingFormatter extends Formatter {
- private Date date = new Date();
private final static String format = "{0,date} {0,time}";
- private MessageFormat formatter;
-
- private Object[] args = new Object[1];
+ private final static DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
- private static String LineSeparator = System.getProperty("line.separator");
+ private static final String LineSeparator = System.getProperty("line.separator");
+ @Override
public synchronized String format(LogRecord record) {
- StringBuffer sb = new StringBuffer();
- // Minimize memory allocations here.
- date.setTime(record.getMillis());
- args[0] = date;
- StringBuffer text = new StringBuffer();
- if (formatter == null) {
- formatter = new MessageFormat(format);
- }
- formatter.format(args, text, null);
- sb.append(text);
+ final StringBuilder sb = new StringBuilder();
+ final var dateTime = ZonedDateTime.ofInstant(record.getInstant(), ZoneId.systemDefault());
+ sb.append(dateTime.format(formatter));
sb.append(" ");
- if (record.getSourceClassName() != null) {
- sb.append(record.getSourceClassName());
- }
- else {
- sb.append(record.getLoggerName());
+ String name = record.getSourceClassName();
+ if (name == null) {
+ name = record.getLoggerName();
}
- if (record.getSourceMethodName() != null) {
+ sb.append(name);
+ final String method = record.getSourceMethodName();
+ if (method != null) {
sb.append(" ");
- sb.append(record.getSourceMethodName());
+ sb.append(method);
}
sb.append(LineSeparator);
- String message = formatMessage(record);
+ final String message = formatMessage(record);
sb.append(record.getLevel().getLocalizedName());
sb.append(": ");
sb.append(message);
- Throwable thrown = record.getThrown();
+ final Throwable thrown = record.getThrown();
if (thrown != null) {
sb.append(thrown.getClass().getName());
- if (thrown.getMessage() != null) {
+ final String thrownMessage = thrown.getMessage();
+ if (thrownMessage != null) {
sb.append(": ");
- sb.append(thrown.getMessage());
+ sb.append(thrownMessage);
}
}
sb.append(LineSeparator);
diff --git a/lightcrafts/src/main/java/com/lightcrafts/utils/TextUtil.java b/lightcrafts/src/main/java/com/lightcrafts/utils/TextUtil.java
index 93812bcb6..79e885a45 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/utils/TextUtil.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/utils/TextUtil.java
@@ -3,8 +3,6 @@
package com.lightcrafts.utils;
import java.text.Normalizer;
-import java.util.Date;
-import java.text.DateFormat;
/**
* A TextUtil
is a set of utility functions for text.
@@ -24,25 +22,6 @@ public final class TextUtil {
/** The number of bytes in 1 gigabyte. */
public static final long GB = MB * K;
- /**
- * Formats a {@link Date} into a date/time string. The reason this method
- * is necessary is because date formats are not thread-safe. From the
- * {@link DateFormat} Javadoc:
- *
- * Date formats are not synchronized. It is recommended to create separate
- * format instances for each thread. If multiple threads access a format
- * concurrently, it must be synchronized externally.
- *
- * @param f The {@link DateFormat} to use.
- * @param d The {@link Date} to be formatted.
- * @return Returns the formatted string.
- */
- public static String dateFormat( DateFormat f, Date d ) {
- synchronized ( f ) {
- return f.format( d );
- }
- }
-
/**
* Convert the byte
array to a string of hexadecimal digits.
*
diff --git a/lightcrafts/src/main/java/com/lightcrafts/utils/Version.java b/lightcrafts/src/main/java/com/lightcrafts/utils/Version.java
index e29bbc24d..c378a537f 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/utils/Version.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/utils/Version.java
@@ -10,17 +10,10 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
import java.net.URL;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
-import java.util.regex.Pattern;
/** A container and accessor for static version data, either configured in
* properties or added to resources at compile time.
diff --git a/lightcrafts/src/main/java/com/lightcrafts/utils/raw/DCRaw.java b/lightcrafts/src/main/java/com/lightcrafts/utils/raw/DCRaw.java
index af640e494..39782ca1d 100644
--- a/lightcrafts/src/main/java/com/lightcrafts/utils/raw/DCRaw.java
+++ b/lightcrafts/src/main/java/com/lightcrafts/utils/raw/DCRaw.java
@@ -13,6 +13,9 @@
import com.lightcrafts.utils.LRUHashMap;
import com.lightcrafts.utils.UserCanceledException;
import com.lightcrafts.utils.bytebuffer.ByteBufferUtil;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.experimental.Accessors;
import java.awt.*;
import java.awt.color.ColorSpace;
@@ -21,13 +24,13 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeParseException;
import java.util.*;
-import lombok.Getter;
-import lombok.NonNull;
-import lombok.experimental.Accessors;
+import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME;
/**
* Get raw image data by inrerfacing with dcraw as a coprocess.
@@ -112,9 +115,11 @@ public float[][] getCameraXYZ() {
* {@inheritDoc}
*/
@Override
- public Date getCaptureDateTime() {
- return m_captureDateTime > 0 ?
- new Date( m_captureDateTime * 1000 ) : null;
+ public ZonedDateTime getCaptureDateTime() {
+ if (m_captureDateTime <= 0)
+ return null;
+ final var instant = Instant.ofEpochMilli(m_captureDateTime);
+ return ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
}
public float[] getDaylightMultipliers() {
@@ -245,8 +250,10 @@ private void parseDCRawInfo(String line, boolean secondary) {
if (line.startsWith(search = TIMESTAMP)) {
final var timestamp = line.substring(search.length());
try {
- m_captureDateTime = new SimpleDateFormat().parse(timestamp).getTime();
- } catch (ParseException e) {
+ m_captureDateTime = ZonedDateTime.parse(timestamp, ISO_LOCAL_DATE_TIME)
+ .toInstant()
+ .toEpochMilli();
+ } catch (DateTimeParseException e) {
m_captureDateTime = 0;
}
} else if (line.startsWith(search = CAMERA)) {
diff --git a/lightcrafts/src/test/java/com/lightcrafts/image/metadata/makernotes/PentaxDirectoryTest.java b/lightcrafts/src/test/java/com/lightcrafts/image/metadata/makernotes/PentaxDirectoryTest.java
index e3287d761..aeffba0d0 100644
--- a/lightcrafts/src/test/java/com/lightcrafts/image/metadata/makernotes/PentaxDirectoryTest.java
+++ b/lightcrafts/src/test/java/com/lightcrafts/image/metadata/makernotes/PentaxDirectoryTest.java
@@ -10,7 +10,7 @@
import java.io.File;
import java.io.IOException;
-import java.text.SimpleDateFormat;
+import java.time.format.DateTimeFormatter;
import static com.lightcrafts.image.metadata.makernotes.PentaxTags.PENTAX_DATE;
import static com.lightcrafts.image.metadata.makernotes.PentaxTags.PENTAX_TIME;
@@ -37,7 +37,7 @@ void setUp() throws UnknownImageTypeException, IOException, BadImageFileExceptio
void putValue() {
// Given
final var pattern = "yyyy-MM-dd HH:mm:ss";
- final var formatter = new SimpleDateFormat(pattern);
+ final var formatter = DateTimeFormatter.ofPattern(pattern);
// When put a PENTAX_DATE value
final byte[] yymd = { 0x07, (byte) 0xE5, 9, 21 };
@@ -47,7 +47,7 @@ void putValue() {
// Then captureDateTime should be set
final var dateTime = dir.getCaptureDateTime();
final var dateStr = "2021-09-21 00:00:00";
- assertThat(formatter.format(dateTime))
+ assertThat(dateTime.format(formatter))
.isEqualTo(dateStr);
// When put PENTAX_TIME
@@ -58,7 +58,7 @@ void putValue() {
// Then captureDateTime should increase
final var modifiedDateTime = dir.getCaptureDateTime();
final var modifiedDateStr = "2021-09-21 06:12:34";
- assertThat(formatter.format(modifiedDateTime))
+ assertThat(modifiedDateTime.format(formatter))
.isEqualTo(modifiedDateStr);
// TODO: Add tests for other tags