Funzione che crea un timestamp in c #


101

Mi chiedevo, c'è un modo per creare un timestamp in c # da un datetime? Ho bisogno di un valore di precisione in millisecondi che funzioni anche in Compact Framework (dicendo che dal momento che DateTime.ToBinary () non esiste in CF).

Il mio problema è che voglio memorizzare questo valore in modo indipendente dal database in modo da poterlo ordinare in un secondo momento e scoprire quale valore è maggiore di un altro ecc.


2
La risposta accettata qui dà una bella soluzione, ma se si vuole un vero e proprio timestamp, date un'occhiata a questo Q / A: stackoverflow.com/questions/9814060/...
inanutshellus

Risposte:


206

Uso sempre qualcosa di simile al seguente:

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

Questo ti darà una stringa come 200905211035131468, poiché la stringa va dai bit di ordine più alto del timestamp all'ordine più basso che l'ordinamento di stringhe semplice nelle tue query SQL può essere utilizzato per ordinare per data se stai attaccando i valori in un database


5
Come mai hai 21 mesi e solo 12? :)
PaulB

2
Il token dell'anno dovrebbe essere minuscolo qui: return value.ToString ("yyyyMMddHHmmssffff");
Don Cote

1
@RobV La domanda richiede una precisione al millisecondo, quindi hai bisogno di 3 'f alla fine. I tuoi 4 'f danno una precisione di 100 microsend.
Eugene Beresovsky

2
Tieni presente che Compact Framework non trasferisce i millisecondi. Saranno sempre 0. Devi modificare il codice e aggiungere qualcosa del genere: int tick = Environment.TickCount% 1000; int ms = (tick> = MOffset)? (tick - MOffset): (1000 - (MOffset - tick)); ms = Math.Min (999, Math.Max ​​(0, ms));
Redwolf

43

Credo che tu possa creare un datestamp in stile unix accurato al secondo usando quanto segue

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

La regolazione del denominatore ti consente di scegliere il tuo livello di precisione


19

È possibile utilizzare la proprietà DateTime.Ticks, che è un archivio lungo e universale, sempre in aumento e utilizzabile anche sul framework compatto. Assicurati solo che il tuo codice non venga utilizzato dopo il 31 dicembre 9999;)


Quando dici "sempre in aumento", non c'è alcuna garanzia che due chiamate a DateTime.UtcNow.Ticks forniscano valori diversi, vero? In altre parole, hai ancora bisogno di qualche cautela prima di usarlo come un timestamp univoco.
Jon Skeet,

9
@Konstantinos: non puoi evitare i duplicati se usi i timestamp. I timestamp non vengono utilizzati per chiavi univoche, ma per contrassegnare un orario. Hai detto di aver bisogno di una precisione al millisecondo e che i tick hanno una precisione di 100 ns. Il fatto è che avrai duplicati. Se non vuoi che hai bisogno di una sequenza univoca nel DB, che sfortunatamente non è indipendente dal db.
Frans Bouma,

3
"è un numero di tick reale che aumenta nel tempo". Ma l'orologio di sistema può tornare indietro, ad esempio alla fine dell'ora legale se si utilizza l'ora locale o perché l'orologio di sistema è stato regolato.
Joe,

1
@Frans: assolutamente. Ho fatto il commento solo perché le persone dovrebbero pensare alle implicazioni della soluzione che scelgono. Ad esempio, userei UTC anziché l'ora locale per eliminare almeno i problemi dell'ora legale.
Joe

1
@konstantinos: hmm ... i documenti dicono che ha una precisione di 100ns, quindi è davvero strano che non abbia la precisione documentata. Forse è davvero il framework compatto, non è un framework senza bug
Frans Bouma


4

quando hai bisogno di un timestamp in secondi, puoi utilizzare quanto segue:

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

2

Se desideri timestamp che corrispondano ai tempi reali effettivi MA vuoi che siano anche univoci (per una determinata istanza dell'applicazione), puoi utilizzare il codice seguente:

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;
       }
   }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.