diff --git a/src/wp-admin/includes/image.php b/src/wp-admin/includes/image.php
index f910809..3265189 100644
--- a/src/wp-admin/includes/image.php
+++ b/src/wp-admin/includes/image.php
@@ -646,18 +646,51 @@ function wp_exif_frac2dec( $str ) {
 }
 
 /**
+ * Convert the exif date format to a datetime object
+ *
+ * @since 5.5.0
+ *
+ * @param string $str
+ * @param string $timezone A timezone or offset string. Default is the WordPress timezone
+ * @return DateTimeImmutable| false Return false if not valid date
+ */
+function wp_exif_datetime( $str, $timezone = null ) {
+	$timezone = ( $offset ) ? new DateTimeZone( $timezone ) : wp_timezone();
+	$datetime = new DateTimeImmutable( $str, $timezone );
+	return $datetime;
+}
+
+
+/**
  * Convert the exif date format to a unix timestamp.
  *
  * @since 2.5.0
+ * @since 5.5.0 Switched to using the wp_exif_datetime function to generate the timestamp for backcompat
  *
  * @param string $str
- * @return int
+ * @return int|false If error return false
  */
 function wp_exif_date2ts( $str ) {
-	list( $date, $time ) = explode( ' ', trim( $str ) );
-	list( $y, $m, $d )   = explode( ':', $date );
+	$datetime = wp_exif_datetime( $str );
+	if( $datetime ) {
+		return $datetime->getTimestamp();
+	}
+	return false;
+}
 
-	return strtotime( "{$y}-{$m}-{$d} {$time}" );
+/**
+ * Combines the EXIF GPSTimeStamp and GPSDateStamp into a DateTime object
+ *
+ * @param string $datestamp
+ * @param array $timestamp
+ * @return DateTimeImmutable|false False if not valid data
+ */
+function wp_exif_gpsdatetime( $datestamp, $timestamp ) {
+	if ( ! is_array( $timestamp ) ) {
+		return false;
+	}
+	return new DateTimeImmutable(
+		sprintf( '%s %02d:%02d:%02d', $datestamp, (int) $timestamp[0], (int) $timestamp[1], (int) $timestamp[2] ), new DateTimeZone( 'UTC' ) );
 }
 
 /**
@@ -813,8 +846,39 @@ function wp_read_image_metadata( $file ) {
 		if ( ! empty( $exif['Model'] ) ) {
 			$meta['camera'] = trim( $exif['Model'] );
 		}
-		if ( empty( $meta['created_timestamp'] ) && ! empty( $exif['DateTimeDigitized'] ) ) {
-			$meta['created_timestamp'] = wp_exif_date2ts( $exif['DateTimeDigitized'] );
+		if ( empty( $meta['created_timestamp'] ) ) {
+			$rawdate = null;
+			$timezone = null;
+			if ( ! empty( $exif['DateTimeOriginal'] ) ) {
+				$rawdate = $exif['DateTimeOriginal'];
+				if ( ! empty( $exif['UndefinedTag:0x9011'] ) ) {
+					$timezone = new DateTimeZone( $exif['UndefinedTag:0x9011'] );
+				}
+			} elseif ( ! empty( $exif['DateTimeDigitized'] ) ) {
+				$rawdate = $exif['DateTimeDigitized'];
+				if ( ! empty( $exif['UndefinedTag:0x9012'] ) ) {
+					$timezone = new DateTimeZone( $exif['UndefinedTag:0x9012'] );
+				}
+			}
+			if ( ! $timezone && $rawdate ) {
+				// Attempt to derive offset from the GPS Timestamp if set as this is set to UTC but may not reflect creation time
+				if ( ! empty( $exif['GPSTimeStamp'] ) && ! empty( $exif['GPSDateStamp'] ) ) {
+					$gps = wp_exif_gpsdatetime( $exif['GPSDateStamp'], $exif['GPSTimeStamp'] );
+					$offsetdatetime = wp_exif_datetime( $rawdate, '+0000' );
+					$seconds = $offsetdatetime->getTimestamp() - $gps->getTimestamp();
+					$timezone = new DateTimeZone( timezone_name_from_abbr( '', $seconds, 0 ) );
+				} else {
+					// If no timezone can be found assume the site timezone
+					$timezone = wp_timezone();
+				}
+			}
+			$datetime = wp_exif_datetime( $rawdate, $timezone );
+
+			// Store as a RFC3339 formatted timestring as this includes both date, time, and timezone
+			$meta['created'] = $datetime->format( DATE_RFC3339 );
+
+			// For backcompat set the timestamp
+			$meta['created_timestamp'] = $datetime->getTimestamp();
 		}
 		if ( ! empty( $exif['FocalLength'] ) ) {
 			$meta['focal_length'] = (string) wp_exif_frac2dec( $exif['FocalLength'] );
