Manav Rathi
2024-07-22 21:30:44 +05:30
committed by GitHub

View File

@@ -52,7 +52,7 @@ export const updateExifIfNeededAndPossible = async (
} catch (e) {
log.error(`Failed to modify Exif date for ${fileName}`, e);
// We used the file's extension to determine if this was a JPEG, but
// this is not a guarantee. Misnamed files, while rare, do exist. So in
// this is not a guarantee. Misnamed files, while rare, do exist. So if
// that is the error thrown by the underlying library, fallback to the
// original instead of causing the entire download or export to fail.
if (
@@ -125,39 +125,53 @@ const dataURLToBlob = (dataURI: string) =>
*
* [Note: Exif dates]
*
* Summary:
*
* DateTimeOriginal is in local time, not UTC. Which local time? The
* OffsetTimeOriginal specifies the time zone. But support for it is limited.
*
* Details:
*
* Common Exif date time tags, an in particular "DateTimeOriginal", are
* specified in the form:
*
* yyyy:MM:DD HH:mm:ss
*
* These values thus do not have an associated UTC offset or TZ. The common
* convention (based on my current understanding) is that these times are
* interpreted to be the local time where the photo was taken.
* These values thus do not have an associated UTC offset or TZ.
*
* Recently, there seems to be increasing support for the (newly standardized)
* "OffsetTimeOriginal" and related fields, which specifies time zone for
* The common convention is that these times are interpreted to be the local
* time where the photo was taken.
*
* > The reason (I assume) for this omission is because (prior to smartphones),
* > cameras did not have a good way of being aware of their time zone.
*
* Recently, there seems to be increasing support for the newly standardized
* "OffsetTimeOriginal" and siblings, which specify time zone for
* "DateTimeOriginal" (and related fields).
*
* However, when the offset time tag is not present (a frequent occurrence, not
* just for older photos but also for screenshots generated by OSes as of 2024),
* we don't really know, and stick with the common convention:
* However, support is still not universal, and there will anyways be older
* photos. So when the offset is missing, we stick with the common convention:
*
* - When reading, assume that the Exif date is in the local TZ when deriving
* a UTC timestamp from it.
*
* - When writing, convert the UTC timestamp to local time.
*
* These assumptions are fallible, because the local time where we're uploading
* or downloading the photo is not necessarily the same as the local time where
* the photo was taken.
*/
const convertToExifDateFormat = (date: Date) => {
// TODO: Exif - Handle offsettime if present
const yyyy = date.getFullYear();
const MM = zeroPad2(date.getMonth() + 1);
const dd = zeroPad2(date.getDate());
const HH = zeroPad2(date.getHours());
const mm = zeroPad2(date.getMinutes());
const ss = zeroPad2(date.getSeconds());
const MM = zeroPad(date.getMonth() + 1, 2);
const dd = zeroPad(date.getDate(), 2);
const HH = zeroPad(date.getHours(), 2);
const mm = zeroPad(date.getMinutes(), 2);
const ss = zeroPad(date.getSeconds(), 2);
return `${yyyy}:${MM}:${dd} ${HH}:${mm}:${ss}`;
};
/** Zero pad the given number to 2 digits. */
const zeroPad2 = (n: number) => (n < 10 ? `0${n}` : `${n}`);
/** Zero pad the given number to {@link d} digits. */
const zeroPad = (n: number, d: number) => n.toString().padStart(d, "0");