Holen Sie sich DateTime.Now mit Millisekunden-Genauigkeit

230

Wie kann ich einen Zeitstempel der tatsächlichen Zeit mit Millisekundengenauigkeit genau erstellen?

Ich brauche so etwas wie 16.4.2013 9: 48: 00: 123. Ist das möglich? Ich habe eine Anwendung, in der ich 10 Mal pro Sekunde Werte abtastet und diese in einem Diagramm anzeigen muss.

LuckyHK
quelle
Beachten Sie, dass einige der Antworten hhstundenlang verwendet werden (Standardzeit). Im Falle eines Zeitstempels (und in vielen anderen Fällen) sollte dieser wahrscheinlich mit tt(am / pm) gepaart oder durch HH(Militärzeit) ersetzt werden.
Goz

Antworten:

302

Wie kann ich einen Zeitstempel der tatsächlichen Zeit mit Millisekundengenauigkeit genau erstellen?

Ich vermute , Sie Millisekunden bedeuten Genauigkeit . DateTimehat viel Präzision, ist aber in Bezug auf die Genauigkeit ziemlich grob. Im Allgemeinen können Sie nicht. Normalerweise hat die Systemuhr (von der die DateTime.NowDaten stammen) eine Auflösung von ca. 10-15 ms. Weitere Informationen finden Sie in Eric Lipperts Blogbeitrag über Präzision und Genauigkeit .

Wenn Sie ein genaueres Timing benötigen, sollten Sie einen NTP-Client verwenden.

Es ist jedoch nicht klar, dass Sie hier wirklich eine Millisekundengenauigkeit benötigen. Wenn Sie sich nicht für das genaue Timing interessieren - Sie möchten nur die Samples in der richtigen Reihenfolge mit "ziemlich guter" Genauigkeit anzeigen, sollte die Systemuhr in Ordnung sein. Ich würde Ihnen raten, DateTime.UtcNowanstatt DateTime.NowZeitzonenprobleme bei Sommerzeitübergängen usw. zu verwenden.

Wenn es bei Ihrer Frage eigentlich nur darum geht DateTime, a mit Millisekundengenauigkeit in einen String umzuwandeln , würde ich Folgendes empfehlen:

string timestamp = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff",
                                            CultureInfo.InvariantCulture);

(Beachten Sie, dass dies im Gegensatz zu Ihrer Stichprobe sortierbar ist und weniger Verwirrung darüber stiftet, ob es sich um "Monat / Tag / Jahr" oder "Tag / Monat / Jahr" handelt.)

Jon Skeet
quelle
5
@antonio: Mit nicht mehr Informationen als "funktioniert nicht" kann ich keine weitere Hilfe leisten.
Jon Skeet
Ja, ich kann weitere Informationen bereitstellen: "{0: yyyyMMdd HH: mm: ss.fff}", DateTime.UtcNow -> 20180502 11: 07: 20.000 Win32.GetSystemTime (ref stime) -> 2018,2,5,11 , 7,20,0 (ymdh mm ss ms) Ich kann eine Instanz der Datums- und Uhrzeitangabe mit Millisekunden erstellen: var dt = new DateTime (2018, 5, 2, 19, 34, 55, 200); "{0: yyyyMMdd HH: mm: ss.fff}", dt -> 20180502 19: 34: 55.200. Net Compact Framework, Windows Embedded Compact 7, auf ARM Cortex-A8
Antonio
@antonio: Es hört sich also so an, als ob die Version von .NET, die Sie auf der von Ihnen verwendeten Hardware verwenden, einfach keine Genauigkeit von weniger als einer Sekunde bietet - oder Sie haben sie zufällig an einer zweiten Grenze aufgerufen. (Wenn Sie immer wieder schlagen DateTime.UtcNow, erhöht es sich immer nur einmal pro Sekunde? Sie haben das nicht gezeigt.)
Jon Skeet
Wenn ich Ticks von DateTime.Now abrufe, wird der Wert abgeschnitten: Ticks 636534596580000000 DateTime von Ticks 20180205 20: 34: 18.000. Die Einschränkung liegt in der Hard / Software, denke ich. Ich habe Stopwatch-Klasse, stattdessen Danke Jon
Antonio
@antonio: Es lohnt sich wahrscheinlich, eine neue Frage mit allen Details des an dieser Stelle beteiligten Geräts zu erstellen.
Jon Skeet
117

Das sollte funktionieren:

DateTime.Now.ToString("hh.mm.ss.ffffff");

Wenn Sie es nicht anzeigen müssen und nur den Zeitunterschied kennen müssen, konvertieren Sie es nicht in einen String. Lass es einfach so,DateTime.Now();

Und verwenden Sie TimeSpan, um den Unterschied zwischen Zeitintervallen zu kennen:

Beispiel

DateTime start;
TimeSpan time;

start = DateTime.Now;

//Do something here

time = DateTime.Now - start;
label1.Text = String.Format("{0}.{1}", time.Seconds, time.Milliseconds.ToString().PadLeft(3, '0'));
Pyromant
quelle
Ich muss damit rechnen, daher kann ich es nicht in einen String konvertieren.
LuckyHK
25

Ich suchte nach einer ähnlichen Lösung, basierend auf dem, was in diesem Thread vorgeschlagen wurde. Ich verwende Folgendes DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff") und es funktioniert wie Charme. Hinweis: Dies .fffsind die Genauigkeitszahlen, die Sie erfassen möchten.

Jozcar
quelle
1
Wenn das Datum am Nachmittag (16:00 Uhr) liegt, wird dies wie am Morgen angezeigt. UPDATE: Verwenden HH(Militärzeit) oder Hinzufügen tt(PM oder AM). Wie in diesem Beispiel gezeigt: repl.it/KGr3/1
Jaider
22

Verwenden Sie DateTime Structure mit Millisekunden und Format wie folgt:

string timestamp = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff", 
CultureInfo.InvariantCulture);
timestamp = timestamp.Replace("-", ".");
Jacman
quelle
16

Antwort des Pyromanten scheint mir ziemlich gut zu sein, aber vielleicht wollten Sie:

DateTime.Now.Millisecond

Wenn Sie jedoch Daten vergleichen, ist TimeSpan der richtige Weg.

Renae
quelle
15
Hinweis: Wenn Sie den Unterschied zwischen zwei DateTimes als TimeSpan vergleichen, benötigen Sie TotalMilliseconds. Millisekunden enthält den aktuellen Millisekunden-Zähler, der niemals größer als 1000 ist, während TotalMillisekunden die gesamten Millisekunden enthält, die seit der Epoche vergangen sind.
Contango
4

Wenn Sie weiterhin ein Datum anstelle einer Zeichenfolge wie bei den anderen Antworten wünschen, fügen Sie einfach diese Erweiterungsmethode hinzu.

public static DateTime ToMillisecondPrecision(this DateTime d) {
    return new DateTime(d.Year, d.Month, d.Day, d.Hour, d.Minute,
                        d.Second, d.Millisecond, d.Kind);
}
Birke
quelle
3

Soweit ich die Frage verstehe, können Sie sich für Folgendes entscheiden:

DateTime dateTime = DateTime.Now;
DateTime dateTimeInMilliseconds = dateTime.AddTicks(-1 * dateTime.Ticks % 10000); 

Dadurch werden Zecken abgeschnitten, die kleiner als 1 Millisekunde sind.

Roland Dietz
quelle
Ja, aber die tatsächliche Auflösung von DateTime.Now darf nicht mehr als 16 ms betragen.
Peter Mortensen
2

Das Problem mit DateTime.UtcNowund DateTime.Nowist, dass es je nach Computer und Betriebssystem möglicherweise nur zwischen 10 und 15 Millisekunden genau ist. Auf Windows-Computern kann jedoch die Low-Level-Funktion GetSystemTimePreciseAsFileTime verwendet werden , um eine Mikrosekundengenauigkeit zu erzielen (siehe Funktion GetTimeStamp()unten).

    [System.Security.SuppressUnmanagedCodeSecurity, System.Runtime.InteropServices.DllImport("kernel32.dll")]
    static extern void GetSystemTimePreciseAsFileTime(out FileTime pFileTime);

    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct FileTime  {
        public const long FILETIME_TO_DATETIMETICKS = 504911232000000000;   // 146097 = days in 400 year Gregorian calendar cycle. 504911232000000000 = 4 * 146097 * 86400 * 1E7
        public uint TimeLow;    // least significant digits
        public uint TimeHigh;   // most sifnificant digits
        public long TimeStamp_FileTimeTicks { get { return TimeHigh * 4294967296 + TimeLow; } }     // ticks since 1-Jan-1601 (1 tick = 100 nanosecs). 4294967296 = 2^32
        public DateTime dateTime { get { return new DateTime(TimeStamp_FileTimeTicks + FILETIME_TO_DATETIMETICKS); } }
    }

    public static DateTime GetTimeStamp() { 
        FileTime ft; GetSystemTimePreciseAsFileTime(out ft);
        return ft.dateTime;
    }
Stochastisch
quelle
Ich danke dir sehr. Ich habe so lange gesucht. Verursacht es Leistungsprobleme und ist es sicher, Produktionscode zu verwenden?
Muhammet Göktürk Ayan
-2
public long millis() {
  return (long.MaxValue + DateTime.Now.ToBinary()) / 10000;
}

Wenn Sie Mikrosekunden möchten, wechseln Sie einfach 10000zu 10, und wenn Sie das 10. Mikro möchten, löschen Sie / 10000.

auffällig
quelle
-3

DateTime.Now.ToString ("ddMMyyyyhhmmssffff")

Amol Jadhao
quelle