C++ __日期_宏的不同格式

C++ __日期_宏的不同格式,c++,c,macros,C++,C,Macros,C有一个预定义的宏\uuuuuuuuuuuuuuuuuuuuuu,它显示编译的源文件的日期。 日期以“Mmm dd yyyy”格式显示 是否有任何方法可以使用宏格式化此日期? 此格式为“yyyy Mmm dd” 而不是: 2013年7月19日 应该是: 2013年7月19日 在C语言中,可以有一个宏,它可以动态地生成一个复合文字,其顺序与您喜欢的顺序类似,比如 #define FDATE (char const[]){ __DATE__[7], __DATE__[8], ..., ' ', ..

C有一个预定义的宏
\uuuuuuuuuuuuuuuuuuuuuu
,它显示编译的源文件的日期。
日期以“Mmm dd yyyy”格式显示

是否有任何方法可以使用宏格式化此日期?
此格式为“yyyy Mmm dd”

而不是:

2013年7月19日

应该是:

2013年7月19日


在C语言中,可以有一个宏,它可以动态地生成一个复合文字,其顺序与您喜欢的顺序类似,比如

#define FDATE (char const[]){ __DATE__[7], __DATE__[8], ..., ' ', ... , '\0' }
在所有重要的地方,您的优化器都应该能够有效地处理此问题。

这里有一个真正的问题:

union {
    const char DOUBLE_DATE[18];
    const char PAD[19];
} DATE_HELPER = { __DATE__ " " __DATE__ };

const char *MY_DATE = DATE_HELPER.DOUBLE_DATE + 7;

我希望在C++程序中以ISO格式编译日期,所以我提出了:

constexpr unsigned int compileYear = (__DATE__[7] - '0') * 1000 + (__DATE__[8] - '0') * 100 + (__DATE__[9] - '0') * 10 + (__DATE__[10] - '0');
constexpr unsigned int compileMonth = (__DATE__[0] == 'J') ? ((__DATE__[1] == 'a') ? 1 : ((__DATE__[2] == 'n') ? 6 : 7))    // Jan, Jun or Jul
                                    : (__DATE__[0] == 'F') ? 2                                                              // Feb
                                    : (__DATE__[0] == 'M') ? ((__DATE__[2] == 'r') ? 3 : 5)                                 // Mar or May
                                    : (__DATE__[0] == 'A') ? ((__DATE__[2] == 'p') ? 4 : 8)                                 // Apr or Aug
                                    : (__DATE__[0] == 'S') ? 9                                                              // Sep
                                    : (__DATE__[0] == 'O') ? 10                                                             // Oct
                                    : (__DATE__[0] == 'N') ? 11                                                             // Nov
                                    : (__DATE__[0] == 'D') ? 12                                                             // Dec
                                    : 0;
constexpr unsigned int compileDay = (__DATE__[4] == ' ') ? (__DATE__[5] - '0') : (__DATE__[4] - '0') * 10 + (__DATE__[5] - '0');

constexpr char IsoDate[] =
{   compileYear/1000 + '0', (compileYear % 1000)/100 + '0', (compileYear % 100)/10 + '0', compileYear % 10 + '0',
    '-',  compileMonth/10 + '0', compileMonth%10 + '0',
    '-',  compileDay/10 + '0', compileDay%10 + '0',
    0
};

// Test that it gets it right today
#include <cstring>
static_assert(strcmp(IsoDate, "2020-11-06") == 0);
constexpr unsigned int compileYear=(\uuuu-DATE\uuuuu7]-'0')*1000+(\uuuu-DATE\uuu8]-'0')*100+(\uuuuu-DATE\uuuu9]-'0')*10+(\uuuu-DATE\uu8]-'0');
constexpr unsigned int compileMonth=(\uuuu DATE\uuuu[0]=='J')?(日期)1:(日期)6:7)//一月,六月或七月
:(\uuuu日期\uuuuu[0]=“F”)?二月二日
:(\uuuu日期\uuuuu[0]=“M”)?(日期:3:5)//3月或5月
:(\uuuu日期\uuuuu[0]=“A”)?((日期)(2)(p))(4:8)//4月或8月
:(\uuuu日期\uuuuu[0]=='S')?9月9日
:(\uuuu日期\uuuuu[0]=“O”)?10月10日
:(\uuuu日期\uuuuu[0]=“N”)?11月11日
:(\uuuu日期\uuuu[0]=“D”)?12//12月
: 0;
constexpr unsigned int compileDay=(\uuuuu DATE\uuuuu[4]=“”)?(“日期”[5]-“0”):(“日期”[4]-“0”)*10+(“日期”[5]-“0”);
constexpr char IsoDate[]=
{compileYear/1000+'0',(compileYear%1000)/100+'0',(compileYear%100)/10+'0',compileYear%10+'0',
“-”,compileMonth/10+“0”,compileMonth%10+“0”,
“-”,编译日期/10+“0”,编译日期%10+“0”,
0
};
//测试它今天是否正确
#包括
静态断言(strcmp(IsoDate,“2020-11-06”)==0);

我认为没有办法。你必须务实地去做。@chrisc11标准<代码>6.10.8.1强制宏1以下宏名称应由实现定义:u_日期u_u_u预处理翻译单元的翻译日期:格式为“Mmm dd yyyy”的字符串文字,其中月份名称与asctime函数生成的名称相同,如果值小于10,则dd的第一个字符为空格字符。如果翻译日期不可用,则应提供实施定义的有效日期@JoachimIsaksson,你一定是在开玩笑。我搜索了
\uuuuu DATE\uuuuu
,没有空格。删除以前错误的膨胀。@ MARGARCIA 16.81[CPP.Prime],你可能会考虑在回答问题时给出的技术?或者,你可能不会。注意,这在C++中是不起作用的,因为ISO C++禁止复合文字。@ Rapptz,C++应该有可能立即创建类似的临时对象。我不确定你是否能实现像C中的这个一样优化的东西。C++11使用的初始化列表几乎是相同的。例如,
自动日期{{uuuuuuuuuu日期{[7],{uuuuu日期{[8],…
@Rapptz:即使对于C++03,也可以说
(std::string()++uuuuuu日期{[7]+\uuuuuuu日期{[8]+
后者似乎缺少了
const
限定,以及静态分配的可能性,这是C结构所允许的。+1让我编译以测试…并工作。但是太接近UB了,我无法信任每一个编译器:)这一个在第二个“dd”之后没有正确的终止.@JensGustedt:你是什么意思?@JoachimIsaksson:我提到过这是一个黑客吗?;-)@JensGustedt不得不查一下:)标准不是非常清楚,但是C11 3.6.2说
任何初始值设定项都不能试图为未包含在被初始化实体中的对象提供值。
,这会使初始值设定项无效(UB?)即使保证了零初始化。但是在gcc的特定情况下,它会生成警告、截断并给出正确的输出。这很好。但是有一个小错误:(\uu-DATE\uuu[0]='M')?((\uu-DATE\uuu[1]='r')?3:5)//Mar或May:(\uu-DATE\uuuu[0]='a')?(\uuu-DATE\uuuU[1]='p'))?4:8)//四月或八月