How does “changed” do not mean “modified”? When we are talking about Linux file timestamps. In this post, we will explain how the system updates them, and how to alter them yourself. By following this post you will get to know more about Linux File Timestamps.

The Difference Between Linux File Timestamps: atime, mtime, and ctime

Every Linux file has three timestamps: First is the access timestamp (atime), the second is modified timestamp (mtime), and the third is changed timestamp (ctime).

The access timestamp is the last time when a file was read. This means someone used a program to display the contents of the file or else read some values from it. Nothing was edited or added to the file and the data was only referenced but unchanged.

A modified timestamp signifies the last time the contents of a file were changed. A program or process either edited or simply manipulated the file. Here “Modified” means something inside the file was amended or deleted, or new data was added.

Changed timestamps aren’t referring to the modification made to the contents of a file. Rather, it’s the time at which the metadata related to the file was changed. File permission changes, for example, will update the changed timestamp too.

The standard ext4 Linux file system also allocates space for a file-creation timestamp in its internal file system structures. However, this hasn’t been implemented yet. Sometimes, this timestamp is populated, however, you can’t depend on the values in it.

The Anatomy of a Timestamp

Linux timestamps usually hold a number rather than a date and time. This number is the number of seconds since the Unix epoch, which was midnight (00:00:00) on January 1, 1970, in Coordinated Universal Time (UTC). Leap seconds are simply ignored in Linux timestamps, so they aren’t analogous to real-time.

When Linux needs to display a timestamp, it usually translates the number of seconds into a date and time. This also makes it easier for humans to understand.

The location and time zone the computer viewing the file is in guides the conversion of the number of seconds to a date and time. It also makes sure that the month is in the correct language.

So, how many seconds can be stored in a timestamp? A lot—2,147,483,647, to be more precise. That’s a big number, however, is it enough? In case you add that to the Unix epoch and then translate it to a date and time then, you get Tuesday, January 19, 2038, at 03:14:07 a.m.

We’ll need a different scheme for timestamps before then, though.

Viewing Timestamps

While you use the -l (long listing) option with ls, as shown below, you can see the modified timestamp:

ls -l dp.c

In case you want to see the access timestamp then, use the -lu (access time) option like so:

ls -lu dp.c

And finally, to see the change timestamp, you can also use the -lc (change time) option; type the following:

ls -lc dp.c

The timestamps above show the file’s contents were last modified on April 21, 2019. The access and changed timestamps are identical because the file was copied from another computer to this one on January 20, 2020, and both timestamps were updated at that time only.

Related:  How to Fix Google Assistant crashing on Some Android devices

To see all timestamps simultaneously, use the stat command as follows:

stat dp.c

The time zones are listed at the bottom of the display. As you can see, they have a very accurate, fractional seconds component. At the end of each timestamp, you also see a -0500 or -0400.

These are time zone offsets. The file system records the timestamps in UTC and generally converts them to the local time zone when displayed by stat. The computer we are using to research this article is configured as if it were in the Eastern Standard Time (EST) zone of the U.S.

That time zone is five hours behind UTC when EST is in force. But, it’s four hours behind UTC when Eastern Daylight Time (EDT) is in force. In April 2019, when the modified timestamp was changed, EDT was in effect.

That is the reason why two of the timestamps have a five-hour offset, but the modified has a four-hour offset.

The offsets and time zones aren’t simply stored anywhere. There’s neither an inode nor a file system space devoted to holding these values.

You have to calculate these on the fly using the timestamp – which is always in UTC time, the local time zone of the computer displaying the file, and whether DST was in effect.

You will also see a “Birth” timestamp, which is reserved for the creation date of the file. This is not implemented, and you will see a hyphen “-” instead of timestamp.

Changing Timestamps

In case you want, you can change the timestamps on a file. Then you can use the touch command to change the access or modified timestamps, or both:

touch -a dp.c

To set a new access timestamp, just use the -a (access time) option. This command sets the access timestamp to the computer’s current time:

stat dp.c

The access timestamp changed, as expected. But, the changed timestamp was updated as well; this is normal.

Related:  How To Enable Grayscale Mode On Your Android Device

To change the modified timestamp, use the -m (modified time) option:

touch -m dp.c
stat dp.c

This time, the modified and changed timestamps were updated.

You can use the -d (date) option in case you want to change both the access and modified timestamps simultaneously. You can also specify a time and date—you’re not restricted to changing the timestamps to the present.

We’ll use the following command to set the access and modified timestamps to 10:30:45 on January 15, 2020:

touch -d "2020-01-15 10:30:45" dp.c
stat dp.c

We’ve now set the access and modified timestamps to a date in the past. The changed timestamp was also updated to the current time of the computer.

You can also use the -r (reference) option, as shown below in case you want to set the timestamps of one file to the timestamp values of another:

touch dp.c -r dice_words.sl3
stat dp.c

And then, we’re quite much back where we started, with a mixture of -0400 and -0500 timestamps.

Let’s do something that affects the changed timestamp only. We’ll use just the chmod command to give an executable file execute permissions for all users:

chmod +x dp
stat dp

The changed timestamp was the only one that got updated. This is due to the file itself wasn’t changed—it was neither accessed nor modified. But, the metadata about the file was changed.

How the File System Updates Timestamps

When a file system is mounted, there are options you can use to specify how that file system should operate or should be treated. These are stored in the /etc/fstab file, which is read and processed at boot time. You can set options to dictate the scheme they should use to update the access timestamp too.

The following are some of the most common options:

strict time (strict time): This option generally updates the access timestamp of files every time they’re accessed. There’s an overhead attached to this approach. however, some servers can benefit from this scheme. It has little merit on a desktop or laptop computer.

  1. noatime (no time): This option usually fully disables the access timestamps for files and directories from updating. The modified timestamps, however, will still update.

2. nodiratime (no dir atime): This option enables access timestamps for files to update, however, disables it for directories.

3. relatime (relative atime): This option updates basically the access timestamp only if it was more than 24-hours old, or the previous one was older than the current modified or changed timestamps.

This strikes a good balance between access timestamps updating too frequently or not updating at all.

Related:  How To Overclock Your Android Device For Enhanced Performance

Let’s look at the /etc/fstab file for this computer and see which options are set:

less /etc/fstab

The /etc/fstab file is displayed for us, as shown below.

Here’s the content of the file without the wrap-around:

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
# / was on /dev/sda1 during installation
UUID=4a143d08-8695-475b-8243-b13b56050fc2 / ext4 errors=remount-ro 0 1
/swapfile none swap sw 0 0

There are only two entries, and one of them is a swap file, which we can simply ignore. The other is being mounted at the root of the filesystem ( / ) and was on device /dev/sda1 at the time of installation. That’s the first partition on the first hard drive, and it happens to contain an ext4 file system.

The only option passed to it is errors=remount-ro, which will tell about the operating system to remount this file system as read-only if there are errors when trying to mount it as a read and write file system.

So, there’s no mention of how the access timestamp will be handled. Let’s dig deeper and check out what /proc/mounts can tell us. We’ll pipe the output from /proc/mounts through grep. Our search string will be “sda”, the hard drive identifier.

We type the following:

cat /proc/mounts | grep "sda"

Now we see the following options:

rw: The file system will be mounted as a read and write file system.

relatime: The file system will use the “relative atime” scheme to update the access timestamps.

Where did that come from? Well, the relatime scheme is used in the following situations:

When the defaults /etc/fstab option is used.

While in the relatime /etc/fstab option is used.

When no access timestamp options are used in /etc/fstab, and you’re using Linux kernel 2.6.30 or newer.

Our /etc/fstab entry for the ext4 file system didn’t specify any access timestamp update options, so Linux made the sensible choice and used realtime.

Timestamps Are Important

Timestamps really give us an easy way to see when we simply access, change or modify a file. However, more importantly, they provide a way to back up and synch software to determine which files need to be backed up.

The ability to manipulate timestamps will prove useful whenever you need to forcibly convince a program to include or ignore a file, or set of files.