I think there are better methods to keep track of the modification time of the file: e.g. ls -l
on the directory will tell you exactly what you are asking: the time that the file was last modified. Even better, keep it under source control and then you'll know every change, as well as when that change was made. THe point is that the modification time is metadata and should be treated as such. If you put the timestamp in the file, then it's part of the data that the file stores. IMO, that's the wrong place for it.
Be that as it may, if you still insist of keeping a time stamp in the file, you can use before-save-hook
to run an arbitrary function just before the file is saved. The function can e.g. check that this is an Org mode file and replace every occurrence of some placeholder with the current time and date. What I'm implementing here is sort-of
what the old RCS system did: it looked for lines of the form
$foo: bar$
where foo
is an RCS keyword
and it would replace the RHS (the part after the colon with some calculated value. Initially, you could just say $foo$
and RCS would expand the keyword with a value as above. Then the value would change, depending on what RCS calculated for it.
So the idea here is to have a keyword TS
in your Org mode file:
* foo
$TS$
and when the file gets saved, the keyword is expanded to:
* foo
$TS: Sat May 8 19:26:46 2021$
Here's the implementation:
(defvar ndk/ts-placeholder-re "$TS:?[^$]*\\$")
(defun ndk/ts-placeholder-replace ()
(when (eq major-mode 'org-mode)
(let ((ts (current-time-string)))
(replace-regexp ndk/ts-placeholder-re (format "$TS: %s$" ts) nil (point-min) (point-max)))))
(add-hook 'before-save-hook #'ndk/ts-placeholder-replace)
The regexp matches $TS$
as well as the expanded form $TS: Sat May 8 19:26:46 2021$
, so the keyword is expanded in either case.
The function checks that this is an Org mode file (you can check for other modes or delete the check altogether, depending on your needs). It then looks for the regexp and replaces every occurrence with the result of calling the function current-time-string
. You can replace that with a different function that returns a string of the timestamp in your preferred format. For example
(format-time-string "%Y-%m-%dT%H:%M:%S" (current-time)) => "2021-05-08T19:41:22"
See the doc string of format-time-string
for the gory details: C-h f format-time-string
.
EDIT: A better answer to this question is given by @Tyler at https://emacs.stackexchange.com/a/64789/14825