5

Recently, I downloaded a large number of photos from a cloud service to my local machine (Ubuntu 23.10). As is expected, the creation/birth date of those files was set to the actual download date. Now, after uploading the photos to a new cloud provider I noticed that my photos are sorted by creation date only (no support for image metadata apparently), which is, of course, pretty useless.

So far, so bad, it certainly isn't a problem of Ubuntu. However, the first (and presumably simplest) solution that came to my mind is to change the files' creation dates according to the respective metadata. Unfortunately, it turns out that changing a files creation date on Linux is not easily done. I don't understand all the details, but it seems to have something to do with the creation date being maintained by the filesystem itself and not usually being exposed to the user. Note: While changing the modification date was no problem using the touch command, it did not solve my problem.

Long story short: The only solution that seems to work is the following:

  1. Read the metadata timestamp from the image, e.g. exiftool -T -DateTimeOriginal <file>
  2. Use timedatectl set-time to adjust the system time
  3. Copy the image file and delete the old one

I've tried it for individual files and it seems to work flawlessly. However, I'm a bit concerned with actually trying it for a significant number of files automatically. Are there any problems (with performance, precision or otherwise) I should be aware of?

EDIT: After @FedKad's comment I noticed that the files are, in fact, sorted by upload date, not the file creation date. I apologize for not noticing before. Still, I'm going to keep the question, because I believe it is a problem others may find interesting (without the context).

junjios
  • 152
  • What is this strange "cloud provider" that uses the creation date of the source file being uploaded? This is certainly not a normal behavior. – FedKad Jun 02 '24 at 08:36
  • 1
    @FedKad pCloud – at least that is what I thought. But your comment made me think again. Apparently, they're really sort by upload date (which really is kind of worse from my pov). I did not notice before, because the download date (and thus creation date) and upload date was actually the same. I guess that means the problem is virtually unsolvable short of pCloud fixing this idiotic behaviour. Thank you, anyway. – junjios Jun 02 '24 at 10:04
  • 1
    You can give more information about the cloud provider and how you upload your files. You can try rclone if it supports your provider. – FedKad Jun 02 '24 at 10:07
  • 2
    Cumbersome, but possible with debugfs. – marcelm Jun 02 '24 at 12:47
  • 1
    Something else I tried: Use faketime -f <date> cp <old-file> <new-file>. Perhaps unsurprisingly though, it did not work. I suppose that must be because cp itself doesn't set the file birth time. – junjios Jun 02 '24 at 15:10
  • 1
    Correct, faketime, datefudge, and similar tools won’t work for this because they only change the userspace perception of time, not the kernel’s understanding of the current time, and the kernel is what sets the btime on newly created inodes. For similar reasons, a time namespace won’t work either. – Austin Hemmelgarn Jun 02 '24 at 21:50

2 Answers2

5

First of all, pCloud does support the modification date of the file. These are some files that I uploaded today to my pCloud account. I tested with the "pCloud drive" software (ver. 1.14.5) for Linux and also from the Web Interface using Firefox (https://my.pcloud.com/). The Linux touch -t works perfectly even on already uploaded files:

enter image description here

However, it seems that dates before the epoch are not supported.


Now the real part of your question:

How can I set the birth date of a file in an Ubuntu system to the time I want?

I never recommend changing system time for any purpose at all!

You can use the debugfs tool from the e2fsprogs package to change a specific file's creation (=birth) date and time. Since this tool can be dangerous and would need to un-mount the file system containing your files, I would recommend creating a test filesystem:

$ cd /tmp
$ truncate --size 100m test100m
$ mkfs.ext4 test100m
mke2fs 1.47.0 (5-Feb-2023)
[...]
Writing superblocks and filesystem accounting information: done

$ mkdir /tmp/tmount $ sudo mount /tmp/test100m /tmp/tmount

$ cd /tmp/tmount $ sudo mkdir testdir $ sudo chown myuser:myuser testdir

$ cd testdir $ touch testfile $ stat testfile File: testfile Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 7,21 Inode: 13 Links: 1 Access: (0664/-rw-rw-r--) Uid: ( 1000/ myuser) Gid: ( 1000/ myuser) Access: 2024-06-02 16:09:44.095324795 +0300 Modify: 2024-06-02 16:09:44.095324795 +0300 Change: 2024-06-02 16:09:44.095324795 +0300 Birth: 2024-06-02 16:09:44.095324795 +0300

$ touch -t 193811100905 testfile $ stat testfile File: testfile Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 7,21 Inode: 13 Links: 1 Access: (0664/-rw-rw-r--) Uid: ( 1000/ myuser) Gid: ( 1000/ myuser) Access: 1938-11-10 09:05:00.000000000 +0200 Modify: 1938-11-10 09:05:00.000000000 +0200 Change: 2024-06-02 16:12:28.703865067 +0300 Birth: 2024-06-02 16:09:44.095324795 +0300

Note that only the access and modification times have changed!

Now remount the file system with debugfs:

$ sudo umount /tmp/tmount

$ sudo debugfs -w /tmp/test100m debugfs 1.47.0 (5-Feb-2023) debugfs: cd testdir debugfs: stat testfile

Inode: 13 Type: regular Mode: 0664 Flags: 0x80000 Generation: 3688309895 Version: 0x00000000:00000005 User: 1000 Group: 1000 Project: 0 Size: 0 File ACL: 0 Links: 1 Blockcount: 0 Fragment: Address: 0 Number: 0 Size: 0 ctime: 0x665c6fbc:a7d083ac -- Sun Jun 2 16:12:28 2024 atime: 0xc56c0d1c:00000000 -- Thu Nov 10 09:05:00 1938 mtime: 0xc56c0d1c:00000000 -- Thu Nov 10 09:05:00 1938 crtime: 0x665c6f18:16ba29ec -- Sun Jun 2 16:09:44 2024 Size of extra inode fields: 32 Inode checksum: 0x2b0c4f97 EXTENTS: (END)

debugfs: set_inode_field <13> crtime 192310292030 debugfs: quit

$ sudo mount /tmp/test100m /tmp/tmount $ cd /tmp/tmount/testdir $ stat testfile File: testfile Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 7,21 Inode: 13 Links: 1 Access: (0664/-rw-rw-r--) Uid: ( 1000/ myuser) Gid: ( 1000/ myuser) Access: 1938-11-10 09:05:00.000000000 +0200 Modify: 1938-11-10 09:05:00.000000000 +0200 Change: 2024-06-02 16:12:28.703865067 +0300 Birth: 1923-10-30 22:30:00.004807757 +0200

The set_inode_field command of debugfs can change the birth date and time which is stored in the inode of the file. The inode number (<13> in the above example) was obtained from the first line of the stat command above. The date specified here in debugfs is in UTC.

FedKad
  • 13,900
  • Thank you for this very interesting answer. While more dangerous, it is certainly a more precise method than the one I presented in my question. Regarding pCloud: In fact, I was aware that pCloud itself does support the modification dates. There is, however, a relatively new feature to pCloud's android app that is supposed to show me photos taken exactly n years ago. Unfortunately, this feature completely ignores the image metadata and the modification date, making it unusable for me. Originally, I didn't want to go into all these details, which is the reason my question was rather abstract. – junjios Jun 02 '24 at 15:05
1

touch -t YYYYMMDDHHMM.SS filename should set timestamp for filename without changing system time.

See man touch for full description of touch command.

ChanganAuto
  • 1,544
Soren A
  • 7,190
  • 5
    "photos are sorted by creation date only" - "changing the modification date [...] using the touch command [...] did not solve my problem" - They need to change the creation's date, not the access / modification's date. – kos Jun 02 '24 at 06:07
  • 3
    touch cannot modify the birth time or creation date of a file, that timestamp is (mostly) only set when the inode is first created and is almost impossible to modify after the fact without editing the raw filesystem data. – Austin Hemmelgarn Jun 02 '24 at 21:47