Skip to content

fix: Photo date wrong #19288

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open

Conversation

dongziyudongziyu
Copy link

@dongziyudongziyu dongziyudongziyu commented Jun 19, 2025

Photos taken with my iPhone can be uploaded normally, but the photos I downloaded show the download time in my album, but after uploading, it shows the upload time.
changelog: The logic should be that the exif time is first, then the filecreateAt time, and finally the fs time.

Some issues such as:
#17892
#17708

Copy link
Contributor

github-actions bot commented Jun 19, 2025

Label error. Requires exactly 1 of: changelog:.*. Found: 🗄️server. A maintainer will add the required label.

@dongziyudongziyu dongziyudongziyu changed the title Photo date wrong fix: Photo date wrong Jun 19, 2025
@dongziyudongziyu dongziyudongziyu changed the title fix: Photo date wrong fix: Photo date wrong label:bug Jun 19, 2025
@dongziyudongziyu dongziyudongziyu changed the title fix: Photo date wrong label:bug fix: Photo date wrong Jun 19, 2025
@jackbentley
Copy link

Can confirm this fixes the issue for me (as explained in #17708 (comment))

I was looking to see if it was possible to fix broken dates on photos but it looks like the correct data is gone "forever" from the server's perspective. It would essentially require a re-upload of the photo/metadata.

It looks like when the mobile app uploads an image it sends along the fileCreateAt date. This is then stored in the database correctly.

The system then extracts the metadata for the photo. In this process it uses this getDates method. The resulting dateTimeOriginal is then used to update the fileCreateAt column in the database.

When a photo doesn't have the create date in it's exif and the system doesn't have/support birth/creation time, the method falls back to the modified date. This means the original creation date is overwritten with the modified date.

Comment on lines +811 to +814
if (asset.fileCreatedAt.getTime() < Date.now()) {
// not zero time, use asset.fileCreatedAt
dateTimeOriginal = localDateTime = asset.fileCreatedAt;
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason you're thinking this is a good idea? I don't think fileCreatedAt should be used, that's prone to be wrong in many cases.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's only used when create date is not in the exif metadata. In which case this is the closest to being correct as it's what's been provided on upload

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, this can solve the time error problem, because the file creation time on the server is the upload time, which is inconsistent with the time of my mobile phone album.

Copy link
Member

@danieldietzler danieldietzler Jul 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still confused. Wouldn't the actual fix be to set the birth time on the file here https://github.com/immich-app/immich/blob/main/server/src/services/asset-media.service.ts#L428 to fileCreatedAt?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that would fix it... if you can find a way to do it (and the FS supports birthtime - I'm confused if most do or don't).

utime only lets you set atime and mtime: https://nodejs.org/api/fs.html#filehandleutimesatime-mtime

Related:
nodejs/node-v0.x-archive#8252
https://linux.die.net/man/2/utime
denoland/deno#23993

Copy link
Member

@danieldietzler danieldietzler Jul 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm that's true. Maybe this is the best fix after all then, we probably shouldn't add more fs limitations than we already have

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't check where asset.fileCreatedAt comes from, but on Windows, the Date Created is the date when the file was last WRITTEN to the disk. And Last Modified usually matches the Date Taken in exif

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't check where asset.fileCreatedAt comes from, but on Windows, the Date Created is the date when the file was last WRITTEN to the disk. And Last Modified usually matches the Date Taken in exif

This code just prevents the situation where there is no exif

Copy link

@jondycz jondycz Jul 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am aware. And I have pictures with no exif and the "Last Modified" being the more correct date than "Date Created". So the Modified attribute should probably be preferred over date created.

Copy link

@jackbentley jackbentley Jul 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should still use the modified date providing when uploaded no created at date was sent in the request. The asset.fileCreatedAt is from the database.

I'm not entirely sure what happens when it's omitted from the request or if the asset is uploaded through other means. I would assume the column would be null and thus this code change would still ignore and continue using the file modified or birth date (whichever is lowest, line 815 - const earliestDate).

It does raise a question of when running extract metadata for a second time on an asset if it should consider changes to the fs or not. Currently in this PR it will ignore them and use the current DB value but it will happily update any changes if it's in EXIF data.

I suppose you could choose the lowest of the 3 - db value, fs birthtime, fs modified time. However you would then only be able to make the date older not newer (on subsequent metadata refresh). Then again, should it even consider any FS dates after first extraction?

Might be useful:

v1 and others added 2 commits July 2, 2025 17:53
Co-authored-by: Jack Bentley <jackbentley@iname.com>
Copy link
Member

@danieldietzler danieldietzler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are still unrelated changes. Please check the "Files changed" view and make sure to revert everything that's not part of this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants