Fonction qui crée un horodatage en c #

101

Je me demandais, y a-t-il un moyen de créer un horodatage en c # à partir d'un datetime? J'ai besoin d'une valeur de précision en millisecondes qui fonctionne également dans Compact Framework (en disant que depuis DateTime.ToBinary () n'existe pas dans CF).

Mon problème est que je veux stocker cette valeur de manière indépendante de la base de données afin de pouvoir la trier plus tard et découvrir quelle valeur est la plus grande d'une autre, etc.

Konstantinos
la source
2
La réponse acceptée ici donne une bonne solution, mais si vous voulez un horodatage réel, consultez ce Q / R: stackoverflow.com/questions/9814060
...

Réponses:

206

J'utilise toujours quelque chose comme ce qui suit:

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

Cela vous donnera une chaîne comme 200905211035131468, car la chaîne va des bits de poids fort de l'horodatage au tri de chaîne simple d'ordre le plus bas dans vos requêtes SQL peut être utilisé pour trier par date si vous collez des valeurs dans une base de données

RobV
la source
5
Comment se fait-il que vous ayez 21 mois et n'en ayez que 12? :)
PaulB
2
Le jeton pour l'année doit être en minuscules ici: return value.ToString ("aaaaMMjjHHmmssffff");
Don Cote
1
@RobV La question demande une précision à la milliseconde, vous avez donc besoin de 3 'f à la fin. Vos 4 'f donnent une précision de 100 microsend.
Eugene Beresovsky
2
Sachez que Compact Framework ne transfère pas les millisecondes. Ils seront toujours 0. Vous devez modifier le code et ajouter quelque chose comme ceci: int tick = Environment.TickCount% 1000; int ms = (tick> = MOffset)? (tick - MOffset): (1000 - (MOffset - tick)); ms = Math.Min (999, Math.Max ​​(0, ms));
Redwolf
43

Je crois que vous pouvez créer un horodatage de style Unix précis à une seconde en utilisant ce qui suit

//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();

L'ajustement du dénominateur vous permet de choisir votre niveau de précision

Voxel
la source
19

Vous pouvez utiliser la propriété DateTime.Ticks, qui est un stockage long et universel, toujours croissant et utilisable également sur le framework compact. Assurez-vous simplement que votre code n'est pas utilisé après le 31 décembre 9999;)

Frans Bouma
la source
Quand vous dites "toujours croissant" - il n'y a aucune garantie que deux appels à DateTime.UtcNow.Ticks donneront des valeurs différentes, n'est-ce pas? En d'autres termes, vous devez toujours faire preuve de prudence avant de l'utiliser comme horodatage unique.
Jon Skeet
9
@Konstantinos: vous ne pouvez pas éviter les doublons si vous utilisez des horodatages. Les horodatages ne sont pas utilisés pour les clés uniques, mais pour marquer une heure. Vous avez dit que vous aviez besoin d'une précision à la milliseconde et que les graduations ont une précision de 100 ns. Le fait est que vous aurez des doublons. Si vous ne voulez pas que vous ayez besoin d'une séquence unique dans la base de données, qui n'est malheureusement pas indépendante de la base de données.
Frans Bouma
3
"c'est un vrai nombre de ticks qui augmente avec le temps". Mais l'horloge système peut reculer - par exemple à la fin de l'heure d'été si vous utilisez l'heure locale ou parce que l'horloge système a été ajustée.
Joe
1
@Frans: absolument. Je n'ai fait ce commentaire que parce que les gens devraient réfléchir aux implications de la solution qu'ils choisissent. Par exemple, j'utiliserais UTC plutôt que l'heure locale pour au moins éliminer les problèmes d'heure d'été.
Joe
1
@konstantinos: hmm ... la documentation dit qu'il a une précision de 100ns, il est donc étrange qu'il n'ait pas cette précision comme documenté. C'est peut-être le framework compact en effet, ce n'est pas un framework sans bugs
Frans Bouma
6

Vous pouvez aussi utiliser

Stopwatch.GetTimestamp (). ToString ();

mgokhanbakal
la source
4

lorsque vous avez besoin d'un horodatage en secondes, vous pouvez utiliser les éléments suivants:

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

Si vous souhaitez des horodatages qui correspondent aux temps réels réels MAIS souhaitez également qu'ils soient uniques (pour une instance d'application donnée), vous pouvez utiliser le code suivant:

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;
       }
   }
}
Ian Mercer
la source