Forum: Compiler & IDEs Andere Formatierung für __DATE__ odere andere Funktion?


von David B. (dave10)


Lesenswert?

Hallo,

ich will gern den Zeitpunkt, wann mein Programm kompiliert wurde in 
meinem Code haben. Dafür gibt es die Funktion _DATE_, welche folgendes 
Format verwendet:
Feb 12 1996 - siehe auch 
http://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html

Gibt es ein Makro, welches das Datum im reinen Dezimalwert ausgibt, z.B. 
das heutige Datum 21.11.2013 als 20131121 oder am Besten 131121.

Vielen Dank
David

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Da du ja schon auf der passenden Handbuchseite warst, siehst du, dass
es sowas nicht gibt.

Muss man sich halt im Buildsystem zusammenbauen, bspw. im Makefile
mit:
1
CFLAGS += -DDATESTAMP=$$(date +%Y%m%d)

von David B. (dave10)


Lesenswert?

Vielen Dank für den Hinweis.

Kannst du das mit dem Makefile etwas mehr erläutern oder mir paar Links 
für gute Erklärungen geben.
Danke.

David

von Peter (Gast)


Lesenswert?

Blöd nur, dass das nicht unter Windows geht. Ich suche auch schon länger 
nach einer Lösung für das Problem. Es würde reichen, wenn man einfach 
einen Timestamp einfügen konnte. Kann man aber nicht,  zumindest habe 
ich in der Anleitung dazu nichts gefunden. Nur das für Mikrocontroller 
unnötig aufgeblähte _DATE_. Ein echtes Manko in avr-gcc, finde ich.

von Karl H. (kbuchegg)


Lesenswert?

Wenn deine IDE es erlaubt ein Kommando auszuführen, bevor ein File 
compiliert wird (meist nennt sich das ein Prebuild Step), dann ist das 
ja dann auch wieder kein Problem.

Dann schreibt man sich eben ein Programm für den PC, welches die 
gewünschte Formatierung in ein File schreibt und includet das in den 
Source an den bewussten Stellen.

von Peter II (Gast)


Lesenswert?

Peter schrieb:
> Blöd nur, dass das nicht unter Windows geht

date gibt es auch für Windows.

von Karl H. (kbuchegg)


Lesenswert?

David B. schrieb:
> Vielen Dank für den Hinweis.
>
> Kannst du das mit dem Makefile etwas mehr erläutern oder mir paar Links
> für gute Erklärungen geben.

Benutzt du überhaupt ein Makefile?


An und für sich ist die Sache einfach.
Das von Jörg angesprochene 'make' stellt offenbar das Datum zur 
Verfügung.
Die Compilerflags werden daher so erweitert, dass dem Compiler beim 
Aufruf ein Makro untergejubelt wird, DATESTAMP, welches dann das 
gewünschte enthält.

Du kannst dann im Programm dieses Makro ganz normal benutzen
1
....
2
3
char Date[] = DATESTAMP;

Das ist also wie ein
1
#define DATESTAMP  "abc...xyz"
nur dass nicht du dieses Makro definierst, sondern dass dem Compiler das 
Makro von aussen
1
    .... -DDATESTAMP="abc...xyz"
beim Compileraufruf mitgegeben wird. Und trickreicherweise wird der 
Ersatztext des Makros durch die in 'make' vorhandenen Datumsfunktionen 
zusammengesetzt.
1
   .... -DDATESTAMP=$$(date +%Y%m%d)

von Karl H. (kbuchegg)


Lesenswert?

Peter II schrieb:
> Peter schrieb:
>> Blöd nur, dass das nicht unter Windows geht
>
> date gibt es auch für Windows.

Eben.
Das ganze ist also mehr eine Frage dessen, waas die jeweilige IDE kann 
oder nicht kann und nicht so sehr eine Frage dessen, was der gcc kann.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter schrieb:
> Blöd nur, dass das nicht unter Windows geht.

Dann installiere eine Scriptsprache deiner Wahl.  Hier der Ersatz
für obiges "date +%Y%m%d":
1
$ python -c 'from time import *; print strftime("%Y%m%d", localtime(time()))'
2
20131122
3
$ perl -e '@t = localtime(); printf("%4d%02d%02d\n", $t[5]+1900, $t[4]+1, $t[3]);'
4
20131122

von Stefan (Gast)


Lesenswert?

irgendwann mal irgendwo im internet gefunden .....
1
#define COMPILE_HOUR          (((__TIME__[0]-'0')*10) + (__TIME__[1]-'0'))
2
#define COMPILE_MINUTE        (((__TIME__[3]-'0')*10) + (__TIME__[4]-'0'))
3
#define COMPILE_SECOND        (((__TIME__[6]-'0')*10) + (__TIME__[7]-'0'))
4
#define COMPILE_YEAR          ((((__DATE__ [7]-'0')*10+(__DATE__[8]-'0'))*10+(__DATE__ [9]-'0'))*10+(__DATE__ [10]-'0'))
5
#define COMPILE_MONTH         ((  __DATE__ [2] == 'n' ? (__DATE__ [1] == 'a' ? 0 : 5)   \
6
                                : __DATE__ [2] == 'b' ? 1                               \
7
                                : __DATE__ [2] == 'r' ? (__DATE__ [0] == 'M' ?  2 : 3)  \
8
                                : __DATE__ [2] == 'y' ? 4                               \
9
                                : __DATE__ [2] == 'l' ? 6                               \
10
                                : __DATE__ [2] == 'g' ? 7                               \
11
                                : __DATE__ [2] == 'p' ? 8                               \
12
                                : __DATE__ [2] == 't' ? 9                               \
13
                                : __DATE__ [2] == 'v' ? 10 : 11) +1)
14
#define COMPILE_DAY           ((__DATE__ [4]==' ' ? 0 : __DATE__  [4]-'0')*10+(__DATE__[5]-'0'))

von Mehmet K. (mkmk)


Lesenswert?

Dasselbe bei mir: irgendwann irgendwo im Internet gefunden .....
1
#define DIGIT(s, no) ((s)[no] - '0')
2
3
const int hours = (10 * DIGIT(__TIME__, 0) + DIGIT(__TIME__, 1));
4
const int minutes = (10 * DIGIT(__TIME__, 3) + DIGIT(__TIME__, 4));
5
//const int seconds = (10 * DIGIT(__TIME__, 6) + DIGIT(__TIME__, 7));
6
const int year = ( 1000 * DIGIT(__DATE__, 7) + 100 * DIGIT(__DATE__, 8) + 10 * DIGIT(__DATE__, 9) + DIGIT(__DATE__, 10));
7
const int months = (__DATE__[2] == 'b' ? 2 :
8
(__DATE__[2] == 'y' ? 5 :
9
(__DATE__[2] == 'l' ? 7 :
10
(__DATE__[2] == 'g' ? 8 :
11
(__DATE__[2] == 'p' ? 9 :
12
(__DATE__[2] == 't' ? 10 :
13
(__DATE__[2] == 'v' ? 11 :
14
(__DATE__[2] == 'c' ? 12 :
15
(__DATE__[2] == 'n' ?
16
(__DATE__[1] == 'a' ? 1 : 6) :
17
/* Implicit "r" */
18
(__DATE__[1] == 'a' ? 3 : 4))))))))));
19
const int day = ( 10 * (__DATE__[4] == ' ' ? 0 : DIGIT(__DATE__, 4)) + DIGIT(__DATE__, 5));
20
21
//==============================
22
// GetVersion
23
//==============================
24
void GetVersion( char *ptr )
25
{
26
  sprintf(ptr, "%d|%d.%0.2d|%4d%0.2d%0.2d %0.2d:%0.2d", BOARD_VERSION, PRG_VERS /100, PRG_VERS %100, year, months, day, hours, minutes);
27
}

von David B. (dave10)


Lesenswert?

Hallo,

vielen vielen Dank für die vielen hilfreichen Antworten.

Ich habe es jetzt mit einem Script (Batch-Datei) und date gelöst 
(Vorschlag von Peter II).
Ich habe mich dazu entschlossen, weil ich auch noch die SVN-Version 
haben möchte.
Für Date habe ich folgendes Script angepasst: 
http://www.pcwelt.de/forum/showthread.php?478432-Batch-file-um-Text-A-durch-Text-B-zu-ersetzen

und für SVN habe ich folgendes genutzt:
1
for /f "tokens=5" %%i in ('SubWCRev WorkingCopyPath^|find "Last committed at revision"') do set version=%%i  
2
echo %version%
von 
http://stackoverflow.com/questions/3179649/getting-the-current-revision-number-on-command-line-via-tortoisesvn.

Trotzdem vielen Dank an alle.

David

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.