4

I have a c++ project that has to print a revision string. The revision string is company wise specified and the protocol includes the build time as yyyy/mm/dd.

I use to specify this as macro from the build system, but this is no longer an option because messes up the precompiled headers (in incremental build when the day changes).

I am trying to implement this with obtaining the build date from the compiler but __DATE__ and __TIMESTAMP__ give the month in Mmm.

Any ideas how I can take the month as number?


based on the answer below the version I finish with is:

#define __MONTH__ (\
  __DATE__ [2] == 'n' ? (__DATE__ [1] == 'a' ? "01" : "06") \
: __DATE__ [2] == 'b' ? "02" \
: __DATE__ [2] == 'r' ? (__DATE__ [0] == 'M' ? "03" : "04") \
: __DATE__ [2] == 'y' ? "05" \
: __DATE__ [2] == 'l' ? "07" \
: __DATE__ [2] == 'g' ? "08" \
: __DATE__ [2] == 'p' ? "09" \
: __DATE__ [2] == 't' ? "10" \
: __DATE__ [2] == 'v' ? "11" \
: "12")

...

std::string udate = __DATE__;
std::string date = udate.substr(7, 4) + "/" + __MONTH__ + "/" + udate.substr(4, 2);
boost::replace_all(date, " ", "0");

thanks

gsf
  • 6,612
  • 7
  • 35
  • 64
  • What platform are you building on? Are you using MAKE? – Alan Nov 04 '13 at 01:10
  • Are you happy to obtain the string programmatically, or do you require a macro-only implementation? – paddy Nov 04 '13 at 01:12
  • Do you use a version control system? – Ed Heal Nov 04 '13 at 01:15
  • It is multi-platform. Programmatically is ok, but it has to be the compile date, not the date of the execution of the program. Yes, I am using version control - what this has to do with the problem? – gsf Nov 04 '13 at 01:19
  • Without more details, we can't answer this question. The simplest way is to define your own macro on the compile command line. – Alan Nov 04 '13 at 01:24
  • 1
    Leave your question as it was, don't add the solution. – Yu Hao Nov 04 '13 at 01:48

2 Answers2

7

I think the below macro matches your requirements. Here we are working on the 3rd letter of the month, since it is unique for most of the months (except Jan/Jun, March/April), hence easier for comparison.

#define MONTH (\
  __DATE__ [2] == 'n' ? (__DATE__ [1] == 'a' ? 1 : 6) \
: __DATE__ [2] == 'b' ? 2 \
: __DATE__ [2] == 'r' ? (__DATE__ [0] == 'M' ? 3 : 4) \
: __DATE__ [2] == 'y' ? 5 \
: __DATE__ [2] == 'l' ? 7 \
: __DATE__ [2] == 'g' ? 8 \
: __DATE__ [2] == 'p' ? 9 \
: __DATE__ [2] == 't' ? 10 \
: __DATE__ [2] == 'v' ? 11 \
: 12)
lolando
  • 1,721
  • 1
  • 18
  • 22
  • 2
    that's cool, do you know is the `__DATE__` always in English? – gsf Nov 04 '13 at 01:33
  • @gsf, very good point, i will have to check. Thx for giving your feedback with fine-tuned logic :) – lolando Nov 04 '13 at 01:42
  • I recommend to use a `constexpr` function for this in `c++11`. You can nest ?: operator with a single return. At least better than a macro. – Germán Diago Nov 04 '13 at 03:05
  • It may appear like a good idea to check for the _most _ unique letter, but it's actually a bad idea. It means you're doing a linear check. If you'd check `__DATE__[0]=='j'` you have either 3 or 9 months left to check. Checking `[0]==m` and `[0]==a` takes out another 4 months, leaving only 5. Checking `[1]==e` distinguishes between feb, sep, dec and oct, nov. – MSalters Nov 04 '13 at 08:02
  • @KrzysztofSz. thx for the notification. I corrrected and upvoted your answer – lolando Jun 04 '14 at 06:10
1

It is similar, but correct resolve Jun and Jan

#define __MONTH__ (\
    __DATE__[2] == 'n' ? (__DATE__[1] == 'a' ? "01" : "06") \
    : __DATE__[2] == 'b' ? "02" \
    : __DATE__[2] == 'r' ? (__DATE__[0] == 'M' ? "03" : "04") \
    : __DATE__[2] == 'y' ? "05" \
    : __DATE__[2] == 'l' ? "07" \
    : __DATE__[2] == 'g' ? "08" \
    : __DATE__[2] == 'p' ? "09" \
    : __DATE__[2] == 't' ? "10" \
    : __DATE__[2] == 'v' ? "11" \
    : "12")

If You find bug in my solution IMPROVE me.

Krzysztof Szewczyk
  • 1,752
  • 1
  • 21
  • 25