Wie man im Beispiel sieht, ergibt die \dyntime - Abfrage immer den aktuellen Wert. Wie kann ich die älteren Werte konservieren, damit immer nur die jüngste Abfrage der \@date\ \currenttime- Abfrage entspricht?

Open in writeLaTeX
\documentclass[a4paper]{article}
\usepackage[ngerman]{babel}
\usepackage[utf8]{inputenc}
\usepackage{datetime}
\makeatletter
\newcommand{\dyntime}{\@date\ \currenttime}
\makeatother
\begin{document}
\dyntime

\dyntime
\end{document}

Anhang: Beispiel 2

Open in writeLaTeX
\documentclass[a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage{longtable}
%Umformungen aus \the\time

\newcount\hour
\newcount\hours
\newcount\minutes
\hour=\time \divide\hour by 60 
\minutes=\time
\hours=\hour \multiply\hours by 60 
\advance \minutes by -\hours
\def\curdate{\the\day.\the\month.\the\year\ }
\def\curday{\the\day}
\def\curmonth{\the\month}
\def\curyear{\the\year}
 \def\curtime{\ifnum\hour<10 0\fi \the\hour:\ifnum\the\minutes<10
 0\the\minutes \else \the\minutes \fi}
 \def\curhour{\the\hour}
 \def\curminute{\ifnum\the\minutes<10
 0\the\minutes \else \the\minutes \fi}
 \def\curtime{\ifnum\hour<10 0\fi \the\hour:\ifnum\the\minutes<10
 0\the\minutes \else \the\minutes \fi}
 \def\curminute{\ifnum\the\minutes<10
 0\the\minutes \else \the\minutes \fi}
\begin{document}
\begin{longtable}{p{6cm}p{6cm}}\caption{Beispiel}\\
\textbf{Timestamp}&\textbf{Eintrag}\\ \hline\endhead
\curdate \curtime& Dieser Eintrag ist  gestern um 12:35 entstanden  \\\hline
\curdate \curtime& Dieser Eintrag ist heute um 14:35 entstanden  \\\hline
\curdate \curtime& Dieser Eintrag ist heute um 16:35 entstanden  \\\hline
& Dieser Eintrag ist heute um 12:35 entstanden  \\\hline
\end{longtable}

\end{document}

gefragt 26 Okt '14, 23:44

ctansearch's gravatar image

ctansearch
(ausgesetzt)
Akzeptiert-Rate: 18%

bearbeitet 29 Okt '14, 10:53

gast3's gravatar image

gast3
(ausgesetzt)

Vorsicht bei Verwendung von \@date. Das ist genau genommen ein internes Makro der Klasse zur ausschließlichen Verwendung in \maketitle. Bei article ist es auch nach \maketitle nicht mehr gültig. Du willst vermutlich \today. So habe ich das bei der Antwort jedenfalls aufgefasst und gehandhabt.

(27 Okt '14, 12:41) gast3

Erster Ansatz:

Das Paket datetime definiert \today nicht expandierbar um. Ebenso ist \currenttime nicht expandierbar. Solange man dieses Paket verwendet, kann man also das aktuelle Datum und die aktuelle Zeit nicht expandiert in eine Datei schreiben, um es für spätere LaTeX-Läufe zu konservieren.

Wenn man allerdings auf das Paket verzichtet, dann geht:

Open in writeLaTeX
\documentclass[a4paper]{article}
\usepackage[ngerman]{babel}
\usepackage[utf8]{inputenc}
\makeatletter
\@tempcnta\time\divide\@tempcnta60\multiply\@tempcnta60
\@tempcntb\time\advance\@tempcntb-\@tempcnta
\divide\@tempcnta60
\edef\thisruntime{%
  \ifnum\@tempcnta<10 0\fi\the\@tempcnta:%
  \ifnum\@tempcntb<10 0\fi\the\@tempcntb:%
  00%
}
\AtBeginDocument{%
  \immediate\write\@auxout{%
    \string\gdef\string\firstrundatetime{\firstrundatetime}%
  }%
}
\makeatother
\newcommand*{\dyntime}{\today\ \thisruntime}
\newcommand*{\firstrundatetime}{\dyntime}
\begin{document}
\dyntime

\firstrundatetime
\end{document}

Die Definition von \thisruntime habe ich mir dabei aus de Paket scrtime abgeschaut.

Wie funktioniert das ganze?

Beim ersten LaTeX-Lauf wird \firstrundatetime zunächst als das aktuellen Datum und die Expansion der aktuellen Uhrzeit definiert. Während \begin{document} wird in die aux-Datei eine Neudefinition von \firstrundatetime geschrieben, deren Inhalt genau der (beim Schreiben expandierte) aktuelle Inhalt von \firstrundatetime ist. Das genaue Ergebnis der Expansion beim Schreiben kann man sich in der aux-Datei nach dem ersten Lauf anschauen.

Bei jedem weiteren LaTeX-Lauf wird zwar zunächst ebenfalls \firstrundatetime als das aktuelle Datum und die Expansion der aktuellen Uhrzeit definiert, allerdings wird dann die aux-Datei gelesen und somit \firstrundatetime auf den Wert aus der aux-Datei gesetzt. Erst dann wird die Neudefinition von \firstrundatetime wieder in die aux-Datei geschrieben. Damit steht in der aux-Datei unabhängig davon, ob das nun der zweite, dritte oder 100. LaTex-Lauf ist, immer Datum und Uhrzeit des ersten LaTeX-Laufs. Um das Ganze zurück zu setzen, löscht man einfach die aux-Datei. Das bedeutet natürlich auch, dass man die aux-Datei nicht löschen darf, solange das Datum erhalten bleiben soll.

Statt der aux-Datei könnte man natürlich auch eine eigene Datei verwenden. Diese müsste dann ebenfalls per \AtBeginDocument zunächst gelesen und dann geschrieben werden. Will man Informationen über einen LaTeX-Lauf hinaus retten, muss man bei TeX grundsätzlich Informationen in eine Datei zusätzliche Datei schreiben. Die aktuelle Datei kann man bei TeX nicht verändern. Ohne Informationen in eine Datei zu schreiben, kann man Informationen grundsätzlich nicht erhalten. Daher geht es nicht ohne so eine Datei. Die Verwendung der aux-Datei liegt dabei nahe, ist aber – wie gesagt – nicht zwingend.

Mit datetime:

Ausgehend von diesem ersten Ansatz ohne datetime und der zuvor erklärten Funktion, kann man nun auch eine Lösung mit datetime basteln. Das Problem, dass \today und \currenttime nicht expandierbar sind, bleibt natürlich bestehen. Für \currenttime ist der einfachste Ausweg bei \thisruntime aus dem ersten Ansatz zu bleiben. Für \today bietet datetime selbst eine Lösung. Das Paket bietet nämlich die Möglichkeit, mit \newdate ein Datum aufgrund nummerischer Daten zu definieren und dieses Datum dann mit \displaydate entsprechend der Formatierung von \today ausgeben zu lassen. Die nummerischen Daten des Datums eines LaTeX-Laufs können wir wie im ersten Ansatz für die Uhrzeit gezeigt, expandieren:

Open in writeLaTeX
\documentclass[a4paper]{article}
\usepackage[ngerman]{babel}
\usepackage[utf8]{inputenc}
\usepackage{datetime}
\makeatletter
\@tempcnta\time\divide\@tempcnta60\multiply\@tempcnta60
\@tempcntb\time\advance\@tempcntb-\@tempcnta
\divide\@tempcnta60
\edef\thisruntime{%
  \ifnum\@tempcnta<10 0\fi\the\@tempcnta:%
  \ifnum\@tempcntb<10 0\fi\the\@tempcntb:%
  00%
}
\edef\thisrunday{\the\day}%
\edef\thisrunmonth{\the\month}%
\edef\thisrunyear{\the\year}%
\AtBeginDocument{%
  \immediate\write\@auxout{%
    \string\gdef\string\firstrunday{\firstrunday}%
    \string\gdef\string\firstrunmonth{\firstrunmonth}%
    \string\gdef\string\firstrunyear{\firstrunyear}%
    \string\gdef\string\firstruntime{\firstruntime}%
  }%
  \newdate{firstrundate}{\firstrunday}{\firstrunmonth}{\firstrunyear}%
}
\makeatother
\newcommand*{\dyntime}{\today\ \thisruntime}
\newcommand*{\firstruntime}{\thisruntime}
\newcommand*{\firstrunday}{\thisrunday}
\newcommand*{\firstrunmonth}{\thisrunmonth}
\newcommand*{\firstrunyear}{\thisrunyear}
\newcommand*{\firstrundatetime}{\displaydate{firstrundate}\ \firstruntime}
\begin{document}
\dyntime

\firstrundatetime
\end{document}
Permanenter link

beantwortet 27 Okt '14, 06:59

gast3's gravatar image

gast3
(ausgesetzt)
Akzeptiert-Rate: 53%

bearbeitet 28 Okt '14, 08:09

Es wäre ein Irrtum anzunehmen, dass bei TeX jede Abfrage von \time, \day, \month oder \year die zum Zeitpunkt der Abfrage aktuelle Zeit, den Tag, Monat oder das Jahr ergibt. Vielmehr sind das mit Zählern vergleichbare Register, die bei TeX beim Start mit einem entsprechenden Wert initialisiert werden. Während des TeX-Laufs ändert TeX selbst den Inhalt dieser Register nicht. Somit sind sie in gewisser Weise statisch. Allerdings kann der Anwender sie ändern, indem er ihnen einen Wert zuweist.

Beginnen wir dazu mit einem plainTeX-Beispiel:

Open in writeLaTeX
%&tex
TeX run startet \the\time m after midnight.

\loop\ifnum \pageno<40000 This is only a dummy text to waist time.\endgraf\repeat

TeX run ended not \the\time m after midnight, but later.

\bye

Der pdfTeX-Lauf für diese 40000 Seiten dauert bei mir ca. 1 Minute. Trotzdem wird auf der ersten und der letzten Seite dieselbe Zeit angezeigt.

Will man nun die Startzeit auch für den Fall erhalten, dass im Dokument ein Zähler verändert wird, so kann man wie üblich den Wert des Zähler in einem anderen Zähler speichern:

Open in writeLaTeX
%&tex
\newcount\originaltime\originaltime=\time
TeX run startet \the\time m after midnight. This is also \the\originaltime m.

\time=5000
We've changed the current time to \the\time m, but the original time is still
available as \the\originaltime m.

\bye

Werden keine Rechneoperationen o. ä. auf dem ursprünglichen Zähler benötigt, so kann man auch ein Makro definieren, in dem man die Expansion des Wertes des Zählers speichert:

Open in writeLaTeX
%&tex
\edef\originaltime{\the\time}
TeX run startet \the\time m after midnight. This is also \originaltime m.

\time=5000
We've changed the current time to \the\time m, but the original time is still
available as \originaltime m.

\bye

Das Register \time diente hier nur als Beispiel für ein beliebiges Datums- oder Zeitregister von TeX. Man kann es in den Beispielen auch durch \day, \month oder \year ersetzen und erhält entsprechende Ergebnisse. Allerdings ist es ggf. schwierig dafür zu sorgen, dass der TeX-Lauf des ersten Beispiels dann min. einen Tag, einen Monat oder ein Jahr dauert. Daher bot sich \time für das Beispiel einfach an.

Wenden wir das auf \datetime unter LaTeX an:

Zunächst sei erwähnt, dass \datetime die aktuelle Zeit in den Zählern \currenthour, \currentminute und \currentsecond speichert. Auch diese werden beim Laden des Pakets einmal gesetzt und sind damit für das gesamte Dokument eigentlich statisch. In der Anleitung ist nirgendwo vorgesehen, diese zu ändern. Für den Fall, dass ein Anwender dies dennoch tut, kann man natürlich alle drei in eigenen Zählern oder eigenen Makros nach dem Laden von datetime sichern:

Open in writeLaTeX
\edef\startsecond{\the\currentsecond}
\edef\startminute{\the\currentminute}
\edef\starthour{\the\currenthour}

Für die Ausgabe einer bestimmten Zeit, kennt datetime die Anweisung \formattime. Damit genügt

Open in writeLaTeX
\formattime{\starthour}{\startminute}{\startsecond}

um die gesicherte Startuhrzeit auszugeben. Das Format ist dabei dasselbe, das für \currenttime verwendet würde.

Für das Datum verfährt man ggf. entsprechend mit den in der Einleitung erwähnten TeX-Registern, die von datetime ebenfalls verwendet werden:

Open in writeLaTeX
\edef\startday{\the\day}
\edef\startmonth{\the\month}
\edef\startyear{\the\year}

und erhält die entsprechend \today formatierte Ausgabe mit

Open in writeLaTeX
\formatdate{\startday}{\startmonth]{\startyear}

unabhängig davon, ob zwischenzeitlich ein Anwender \day, \month oder \year verändert hat.

Natürlich gibt es keine echte Möglichkeit sicherzustellen, dass die neuen Makros nicht ebenfalls umdefiniert werden. So etwas wie \static\def kennt TeX nicht.

Man kann sich auch eine Anweisung definieren, die das Speichern der aktuellen Einstellung übernimmt und zwei weitere für die zugehörigen Ausgaben:

Open in writeLaTeX
\newcommand*{\savecurrentdatetime}[1]{%
  \expandafter\edef\csname #1day\endcsname{\the\day}%
  \expandafter\edef\csname #1month\endcsname{\the\month}%
  \expandafter\edef\csname #1year\endcsname{\the\year}%
  \expandafter\edef\csname #1second\endcsname{\the\currentsecond}%
  \expandafter\edef\csname #1minute\endcsname{\the\currentminute}%
  \expandafter\edef\csname #1hour\endcsname{\the\currenthour}%
}
\newcommand*{\savedday}[1]{%
  \formatdate{\csname #1day\endcsname}{\csname #1month\endcsname}{\csname #1year\endcsname}%
}
\newcommand*{\savedtime}[1]{%
  \formattime{\csname #1hour\endcsname}{\csname #1minute\endcsname}{\csname #1second\endcsname}%
}

Nun kann man jederzeit im Dokument beispielsweise mit \savecurrentdatetime{gespeichert} die aktuellen Einstellungen der Datums- und Zeitregister sichern und mit \savedday{gespeichert}\ \savedtime{gespeichert} die gespeicherten Daten entsprechend \today und \currenttime anzeigen lassen.

Aber wie gesagt: Das ist nur notwendig, wenn man davon ausgeht, dass innerhalb des Dokument die Datums- und Zeitregister explizit durch den Anwender oder ein Paket geändert werden. TeX selbst ändert diese nicht. Das gilt ebenso für datetime. Wenn man also nicht an den Registern fummelt, dann sind \today und \currenttime bei datetime bereits statische Angaben. Insbesondere werden die beiden \dyntime im Beispiel aus der Frage immer identische Ergebnisse liefern.

Permanenter link

beantwortet 28 Okt '14, 09:07

gast3's gravatar image

gast3
(ausgesetzt)
Akzeptiert-Rate: 53%

bearbeitet 28 Okt '14, 10:56

@Ijon Tichy

Nur zu den TeX-Durchläufen: Soviel ich weiß, gibt \the\time nur die Minuten seit Mitternacht an, eine Sekundenausgabe gibt es daher nicht. Das andere muß ich erstmal in Ruhe anschauen. Aber so einen ähnlichen Ansatz habe ich auch probiert. Heut abend mehr.

(28 Okt '14, 10:17) ctansearch

Tja, die Frage ist wohl die Quadratur des Kreises. Ist wohl besser, man schreibt das Datum einfach hin.

(28 Okt '14, 18:30) ctansearch

@Ijon Tichy Ich will einfach nur einen timestamp haben, wie er in Datenbanken üblich ist, und zwar in TeX und LaTeX. (Siehe Anhang zum Fragebeispiel.)

(28 Okt '14, 19:56) ctansearch

@Ijon Tichy Abschließend: Meine Frage war klipp und klar: Wie erreicht man, daß der Wert von \dyntime konserviert werden kann und nur der jeweils neueste die aktuelle Zeit anzeigt. Alle weiteren "Komplikationen" hast Du selbst produziert.

(29 Okt '14, 10:57) ctansearch
1

@ctansearch Ich bin sicher, dass Dir Deine Frage klipp und klar ist und war. Dasselbe trifft aber nicht unbedingt für Leser der Frage zu. Wenn ich ehrlich bin, weiß ich immer noch nicht genau, worauf Du hinaus willst, obwohl ich Deine Frage, Deine inzwischen entfernte Antwort, @Ijons Antworten und die Diskussion verfolgt und gelesen habe. Mir ist z.B. völlig unklar, welchen Zeitpunkt Du festhalten möchtest, da es ja offenbar nicht der der ersten Kompilation ist.

(29 Okt '14, 11:27) cgnieder

@Clemens Ich möchte das Datum und den Zeitpunkt jeder Kompilation festhalten, auch wenn es hunderte sind, und diese Daten dann weiterverarbeiten.

(29 Okt '14, 21:19) ctansearch
Ergebnis 5 von 6 show 1 more comments
Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs fügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×19
×2
×1

gestellte Frage: 26 Okt '14, 23:44

Frage wurde gesehen: 12,301 Mal

zuletzt geändert: 29 Okt '14, 21:19