Obtenez DateTime.Now avec une précision en millisecondes

231

Comment puis-je construire exactement un horodatage du temps réel avec une précision en millisecondes?

J'ai besoin de quelque chose comme 16.4.2013 9: 48: 00: 123. Est-ce possible? J'ai une application, où j'échantillonne des valeurs 10 fois par seconde, et je dois les montrer dans un graphique.

LuckyHK
la source
Sachez qu'un certain nombre de réponses sont utilisées hhpendant des heures (heure standard). Dans le cas d'un horodatage (et dans de nombreux autres cas), celui-ci devrait probablement être associé à tt(am / pm) ou remplacé par HH(heure militaire).
gonez

Réponses:

304

Comment puis-je construire exactement un horodatage du temps réel avec une précision en millisecondes?

Je suppose que vous voulez dire une précision en millisecondes . DateTimea beaucoup de précision, mais est assez grossier en termes de précision. D'une manière générale, vous ne pouvez pas. Habituellement, l'horloge système (d'où DateTime.Nowproviennent ses données) a une résolution d'environ 10 à 15 ms. Voir le blog d' Eric Lippert sur la précision et l'exactitude pour plus de détails.

Si vous avez besoin d'un timing plus précis que cela, vous voudrez peut-être envisager d'utiliser un client NTP.

Cependant, il n'est pas clair que vous ayez vraiment besoin d'une précision en millisecondes ici. Si vous ne vous souciez pas du timing exact - vous voulez juste montrer les échantillons dans le bon ordre, avec une précision "assez bonne", alors l'horloge du système devrait être correcte. Je vous conseille d'utiliser DateTime.UtcNowplutôt que de DateTime.Nowbien, pour éviter les problèmes de fuseau horaire autour des transitions d'heure d'été, etc.

Si votre question est en fait simplement convertir autour DateTimed'une chaîne avec une précision milliseconde, je suggère d' utiliser:

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

(Notez que contrairement à votre échantillon, cela est triable et moins susceptible de créer de la confusion quant à savoir s'il est censé être "mois / jour / année" ou "jour / mois / année".)

Jon Skeet
la source
5
@antonio: Avec pas plus d'informations que "ne fonctionne pas", je ne peux pas fournir plus d'aide.
Jon Skeet
Oui, je peux fournir plus d'informations: "{0: aaaaMMjj 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) Je peux créer une instance de date-heure avec des millisecondes: var dt = new DateTime (2018, 5, 2, 19, 34, 55, 200); "{0: aaaaMMjj HH: mm: ss.fff}", dt -> 20180502 19: 34: 55.200. Framework compact Net, Windows Embedded Compact 7, sur ARM Cortex-A8
antonio
@antonio: Il semble donc que la version de .NET que vous utilisez sur le matériel que vous utilisez ne fournisse tout simplement pas une précision inférieure à la seconde - ou vous l'avez appelé sur une deuxième limite. (Si vous continuez à frapper à DateTime.UtcNowplusieurs reprises, cela n'augmente-t-il qu'une fois par seconde? Vous ne l'avez pas montré.)
Jon Skeet
Lorsque je récupère les ticks de DateTime.Now, la valeur est tronquée: Ticks 636534596580000000 DateTime de Ticks 20180205 20: 34: 18.000. la limitation est dans le matériel / logiciel, je pense. J'ai utilisé la classe Chronomètre, à la place Merci Jon
antonio
@antonio: Cela vaut probablement la peine de créer une nouvelle question avec tous les détails de l'appareil impliqué à ce stade.
Jon Skeet
117

Cela devrait fonctionner:

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

Si vous n'avez pas besoin qu'il soit affiché et que vous ayez juste besoin de connaître le décalage horaire, ne le convertissez pas en chaîne. Laissez-le comme,DateTime.Now();

Et utilisez TimeSpanpour connaître la différence entre les intervalles de temps:

Exemple

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'));
Pyromancien
la source
J'ai besoin de calculer avec, donc je ne peux pas le convertir en chaîne.
LuckyHK
25

Je cherchais une solution similaire, basée sur ce qui a été suggéré sur ce fil, j'utilise ce qui suit DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff") , et cela fonctionne comme un charme. Remarque: ce .fffsont les nombres de précision que vous souhaitez capturer.

Jozcar
la source
1
Si la date est dans l'après-midi (16h00), elle apparaît comme le matin. CORRECTIF: utilisez HH(heure militaire) ou ajoutez tt(PM ou AM). Comme le montre cet exemple: repl.it/KGr3/1
Jaider
22

Utilisez la structure DateTime avec des millisecondes et un format comme celui-ci:

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

La réponse de Pyromancer me semble plutôt bonne, mais peut-être que vous vouliez:

DateTime.Now.Millisecond

Mais si vous comparez des dates, TimeSpan est le chemin à parcourir.

Renae
la source
15
Remarque: Si vous comparez la différence entre deux DateTimes en tant que TimeSpan, vous en avez besoin TotalMilliseconds. Millisecondes contient le compteur Millisecondes actuel, qui n'est jamais supérieur à 1000, tandis que TotalMilliseconds contient le total des millisecondes écoulées depuis l'époque.
Contango
4

Si vous voulez toujours une date au lieu d'une chaîne comme les autres réponses, ajoutez simplement cette méthode d'extension.

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);
}
bouleau
la source
3

Pour autant que je comprends la question, vous pouvez opter pour:

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

Cela coupera les tiques inférieures à 1 milliseconde.

Roland Dietz
la source
Oui, mais la résolution réelle de DateTime.Now ne doit pas dépasser 16 ms environ.
Peter Mortensen
2

Le problème avec DateTime.UtcNowet DateTime.Nowest que, selon l'ordinateur et le système d'exploitation, il peut n'être précis qu'entre 10 et 15 millisecondes. Cependant, sur les ordinateurs Windows, on peut utiliser la fonction de bas niveau GetSystemTimePreciseAsFileTime pour obtenir une précision en microsecondes, voir la fonction GetTimeStamp()ci-dessous.

    [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;
    }
Stochastiquement
la source
Merci beaucoup. Je cherche ça depuis si longtemps. Est-ce que cela cause des problèmes de performances et est-il sûr d'utiliser le code de production?
Muhammet Göktürk Ayan
-2
public long millis() {
  return (long.MaxValue + DateTime.Now.ToBinary()) / 10000;
}

Si vous voulez des microsecondes, passez simplement 10000à10 , et si vous voulez le 10e de micro, supprimez / 10000.

distiking
la source
-3

DateTime.Now.ToString ("ddMMyyyyhhmmssffff")

amol jadhao
la source