Funktion, die einen Zeitstempel in c # erstellt


101

Ich habe mich gefragt, ob es eine Möglichkeit gibt, einen Zeitstempel in c # aus einer Datums- / Uhrzeitangabe zu erstellen. Ich benötige einen Millisekunden-Genauigkeitswert, der auch in Compact Framework funktioniert (da DateTime.ToBinary () in CF nicht vorhanden ist).

Mein Problem ist, dass ich diesen Wert datenbankunabhängig speichern möchte, damit ich ihn später sortieren und herausfinden kann, welcher Wert von einem anderen größer ist usw.


2
Die hier akzeptierte Antwort bietet eine gute Lösung, aber wenn Sie einen echten Zeitstempel wünschen,
lesen Sie

Antworten:


206

Ich benutze immer so etwas wie das Folgende:

public static String GetTimestamp(this DateTime value)
{
    return value.ToString("yyyyMMddHHmmssfff");
}

Auf diese Weise erhalten Sie eine Zeichenfolge wie 200905211035131468, da die Zeichenfolge von Bits höchster Ordnung des Zeitstempels zu Bits niedrigster Ordnung in Ihren SQL-Abfragen wechselt und nach Datum sortiert werden kann, wenn Sie Werte in eine Datenbank einfügen


5
Wie kommt es, dass du 21 Monate und nur 12 bekommst? :)
PaulB

2
Das Token für das Jahr sollte hier klein geschrieben sein: return value.ToString ("yyyyMMddHHmmssffff");
Don Cote

1
@RobV Die Frage fragt nach Millisekundengenauigkeit, sodass Sie am Ende 3 'fs benötigen. Ihre 4 'f's geben 100 Microsend Präzision.
Eugene Beresovsky

2
Beachten Sie, dass Compact Framework die Millisekunden nicht überträgt. Sie werden immer 0 sein. Sie müssen den Code ändern und Folgendes hinzufügen: int tick = Environment.TickCount% 1000; int ms = (tick> = MOffset)? (tick - MOffset): (1000 - (MOffset - tick)); ms = Math.Min (999, Math.Max ​​(0, ms));
Redwolf

43

Ich glaube, Sie können einen Datenstempel im Unix-Stil auf eine Sekunde genau erstellen, indem Sie Folgendes verwenden

//Find unix timestamp (seconds since 01/01/1970)
long ticks = DateTime.UtcNow.Ticks - DateTime.Parse("01/01/1970 00:00:00").Ticks;
ticks /= 10000000; //Convert windows ticks to seconds
timestamp = ticks.ToString();

Durch Anpassen des Nenners können Sie die Genauigkeit auswählen


19

Sie können die DateTime.Ticks-Eigenschaft verwenden, die lang und universell speicherbar ist, immer größer wird und auch auf dem kompakten Framework verwendet werden kann. Stellen Sie einfach sicher, dass Ihr Code nach dem 31. Dezember 9999 nicht mehr verwendet wird;)


Wenn Sie "immer größer" sagen, gibt es keine Garantie dafür, dass zwei Aufrufe von DateTime.UtcNow.Ticks unterschiedliche Werte ergeben. Mit anderen Worten, Sie müssen noch einige Vorsicht walten lassen, bevor Sie es als eindeutigen Zeitstempel verwenden.
Jon Skeet

9
@Konstantinos: Sie können Duplikate nicht vermeiden, wenn Sie Zeitstempel verwenden. Zeitstempel werden nicht für eindeutige Schlüssel verwendet, sondern zum Markieren einer Zeit. Sie sagten, Sie brauchten eine Millisekundengenauigkeit, und Ticks haben eine Genauigkeit von 100 ns. Die Sache ist, dass Sie Duplikate haben werden. Wenn Sie das nicht wollen, brauchen Sie eine eindeutige Sequenz in der DB, die leider nicht db-agnostisch ist.
Frans Bouma

3
"Es ist eine echte Zeckenzahl, die mit der Zeit zunimmt". Die Systemuhr kann jedoch rückwärts gehen - z. B. am Ende der Sommerzeit, wenn Sie die Ortszeit verwenden oder weil die Systemuhr angepasst wurde.
Joe

1
@ Trans: absolut. Ich habe den Kommentar nur gemacht, weil die Leute über die Auswirkungen der von ihnen gewählten Lösung nachdenken sollten. Zum Beispiel würde ich UTC anstelle der Ortszeit verwenden, um zumindest die Probleme der Sommerzeit zu beseitigen.
Joe

1
@konstantinos: hmm ... die Dokumente sagen, dass es 100ns Genauigkeit hat, also ist es in der Tat seltsam, dass es nicht so genau ist, wie dokumentiert. Vielleicht ist es tatsächlich das kompakte Framework, es ist kein Framework ohne Fehler
Frans Bouma


4

Wenn Sie einen Zeitstempel in Sekunden benötigen, können Sie Folgendes verwenden:

var timestamp = (int)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalSeconds;

2

Wenn Sie Zeitstempel wünschen, die der tatsächlichen Echtzeit entsprechen, ABER auch möchten, dass sie eindeutig sind (für eine bestimmte Anwendungsinstanz), können Sie den folgenden Code verwenden:

public class HiResDateTime
{
   private static long lastTimeStamp = DateTime.UtcNow.Ticks;
   public static long UtcNowTicks
   {
       get
       {
           long orig, newval;
           do
           {
               orig = lastTimeStamp;
               long now = DateTime.UtcNow.Ticks;
               newval = Math.Max(now, orig + 1);
           } while (Interlocked.CompareExchange
                        (ref lastTimeStamp, newval, orig) != orig);

           return newval;
       }
   }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.