Date compiler macros in Swift

Hello all,

As everyone reading this hopefully knows, Swift has a couple of compiler macros, also known as “Magic Identifiers” in the code, those being;

  • #file: Returns the name of the file being compiled
  • #line: Returns the current line being compiled, as an integer
  • #function: Returns the function signature of the function from which the code is being compiled

I propose that a new magic identifier be added, called #date, returning the current date that the file is being compiled as a String, in the format mmmm dd yy (for example, May 28 2022), which is also the same format used by the __DATE__ preprocessor macro in C(++).

Please let me know your thoughts on this :smile:


Macros like __DATE__ and __TIME__ make compilation an impure compilation, invalidating or complicating build system optimisations like caching and distribution. While they may seem convenient, it’s better to generate a file with the required content as part of your build process.


Why would this complicate compiler optimizations? Wouldn’t this literally just be the same as #file but instead of giving the filename, the compiler gives the current date instead?

Right now you can use a plugin to generate a source file containing let compilationDate = ....

Unlike the other # tokens, #date would be basically static for a particular build and thus never meaningfully used more than once in a project.

Still wouldn’t see the issue with it, though

I was not objecting, only noting a distinct difference between this and the existing ones.


If adding this, would argue to use ISO8601 instead of adhering to us-centric historical date displays. More inline with using eg. Unicode instead of ASCII. ISO8601 is basically most-significant-datetime-component first.


Build system optimisations, not compiler optimisations.

Because unlike #file, #date would change each time the compiler is invoked, and would make compilation result caching impossible.


Hm, I see

@jayton @Jean-Daniel But about caching, wouldn’t the only file that would need to be recompiled just the one using #date? Because as pointed out, it’s likely just going to be used once in a project

Yeah why not, but please use the format yyyy-MM-dd instead because this is parsable and easier to sort by since it's a big endian format.


Probably, but it will requires all build systems to learn about that, and find a way to define which file is using #date and which one isn't (ie marking the file as dirty even if it didn't change).

Another drawback of #date is that its usage must be prohibited in any code base that requires reproducible build, forcing such project to update their guidelines, and implement tools to detect its usage.


I see, I thought the caching would be automatic, this is interesting

The issue is that a file containing date should be recompiled every time - so the compiler needs to know that the file contains that magic symbol somehow…. Usually you could check timestamp when the file last was modified but that would break here.

1 Like

To address the mentioned compilation impurity, the date could be the source file modification date instead of a build date. Alternatively depending upon how this feature is going to be used it can be, say, md5 checksum instead of a date. In one of the projects I remember incorporating the git commit hash (the script extracted the current commit hash and placed into a version.swift file, that file was part of the project and it was ignored from git to not cause a change).


All of these are perfectly reasonable options for different purposes, and none of them should be compiler features.


I see, it seems too unrelated to the code being written for it to be a magic identifier unlike the other ones such as #file & #line

I've spent way too much of the last few months implementing a datetime data type and trying to write unit tests against it.

From the point of view of a testing environment, as soon as you have something generating a value related to current date or time, you have turned your assertions into having to be not only dynamically generated but generated using a different mechanism to the thing being tested.

You have to ensure that both the first and second methods of date generation have the same logic with regards to timezones. I had one test failure that only happened within midnight - 8am, because I'm in GMT+8.

It generates a LOT of noise.

You can already run build scripts in separate languages that put a datetime into a file or macro, this doesn't need to be in a compiler.


Playing devils advocate... #file gives you one piece of file metadata (its name) and it won't be unreasonable to have yet another piece of metadata available as #fileModificationDate.

1 Like

What's the problem you're trying to solve, here? Alone, this feels kind of like an attempt at identifying a particular time the object code got built -- but that's almost never the question one asks of a program. In my experience, one is much more likely to wonder things like what source code generated the program, or what toolchain compiled the source.