Is there an equivalent of __DATE__
and __TIME__
in C#?
Basically what I'm trying to do is place some build timestamping in a C# application.
One possibility I saw on Microsoft's website was to do the following:
Assembly assem = Assembly.GetExecutingAssembly();
Version vers = assem.GetName().Version;
DateTime buildDate = new DateTime(2000, 1, 1).AddDays(vers.Build).AddSeconds(vers.Revision * 2);
Console.WriteLine(vers.ToString());
Console.WriteLine(buildDate.ToString());
However, this only works if your version in AssemblyInfo.cs is "1.0..", which ours won't be.
__FILE__ This macro expands to the name of the current input file, in the form of a C string constant. This is the path by which the preprocessor opened the file, not the short name specified in ' #include ' or as the input file name argument. For example, "/usr/local/include/myheader.
__LINE__ is a preprocessor macro that expands to current line number in the source file, as an integer. __LINE__ is useful when generating log statements, error messages intended for programmers, when throwing exceptions, or when writing debugging code.
Predefined Macros in C99 standard:It is used to test whether a header is compiled by a C compiler or a C++ compiler. This macro gives value similar to __STDC_VERSION__, in that it expands to a version number. Values hold by __cplusplus.
This is called token pasting or token concatenation. The '##' pre-processing operator performs token pasting. When a macro is expanded, the two tokens on either side of each '##' operator are combined into a single token, which then replaces the '##' and the two original tokens in the macro expansion.
I recommend customising your build script to write the date time into the file. The MSBuild Community Tasks project has a Time task that can be used for exactly this.
Short answer: NO. There is no equivalent. They left it out. Too bad. Joke's on you.
There are some near-equivalent work-arounds, all based on the program examining itself. None is rational, elegant, or sturdy.
Some solutions pick up the compile date+time from "AssemblyVersion", a structure of four UInt16 fields ("Major Version", "Minor Version", "Build Number", and "Revision") that are not guaranteed to contain the date and time at all, much less in a specific format. If you set AssemblyVersion to "a.b.*" (and no one changes it), then the compiler overrides it to a.b.c.d, where c == days and d*2 == seconds since Jan. 1, 2000 at 00:00 (local time, but disregards daylight saving time), at the moment it parses AssemblyInfo.cs. These get compiled into the program, where they can be accessed via System.Reflection.Assembly.GetExecutingAssembly().GetName().Version .
Other solutions have the executable file reach into the file system to pick up its "last-modified" date+time from its own metadata, which is easily changed or damaged by transfer via FAT, CDFS, or FTP with DST or time-zone changes, lazy FTP servers that discard metadata outright, or file utilities that change metadata on request. Pathetic.
Where is the compile-time constant (or constants), maybe called #NOW (or #YEAR, #MONTH, #DAY, etc.), that can be used in expressions or assigned to a const or a readonly? CodeWarrior C, GCC, MS C, and MS C++ give the standard predefined macros __DATE__
and __TIME__
, which can be used like compile-time string constants. It seems like a glaring omission from C#, driving everyone to waste person-years asking about and setting up work-arounds. New language, new code, pathetic rickety design. C# doesn't have macros. C#'s #define only has "defined" or "undefined". SO WHAT? I see no excuse for deleting significant compile-time constants. How about putting it into C#'s fake pro-processor?
17 years into "Simple Managed C" / "C-like Object Oriented Language", CIL, and CLR, and this is what it is? A million ways to write code that doesn't do what it says (implementation of threading)? Libraries that expose every flaw of "the underlying method"? You have to target one (or both) of two separate virtual machines: a 32-bit VM for 32-bit hardware (or emulator) and a 64-bit VM for 64-bit hardware (only) - what's virtual about that? Java compiles once, for only one virtual machine, which of course has separate implementations for each platform (32 or 64).
If you are trying to autogenerate your build and revision numbers, I would look into the following project on CodePlex:
http://autobuildversion.codeplex.com/
You could look at customizing the projects .csproj file. This is just an ordinary msbuild file and you can hook into the BeforeBuild target to generate or update a file, perhaps storing this value in a custom assembly level attribute.
I'd imagine the msbuild community tasks would be useful here as they have several helpful tasks for things like token replacement within a file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With