Função que cria um carimbo de data / hora em c #

101

Eu queria saber, há uma maneira de criar um carimbo de data / hora em c # a partir de uma data e hora? Eu preciso de um valor de precisão de milissegundos que também funcione no Compact Framework (dizendo que, uma vez que DateTime.ToBinary () não existe no CF).

Meu problema é que eu quero armazenar esse valor de uma forma agnóstica de banco de dados para que possa classificá-lo mais tarde e descobrir qual valor é maior de outro etc.

Konstantinos
fonte
2
A resposta aceita aqui é uma boa solução, mas se você quiser um registro de data e hora real, verifique esta P / A: stackoverflow.com/questions/9814060/…
inanutshellus

Respostas:

206

Eu sempre uso algo como o seguinte:

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

Isso lhe dará uma string como 200905211035131468, já que a string vai dos bits de ordem mais alta do carimbo de data / hora para a classificação de string simples de ordem mais baixa em suas consultas SQL pode ser usada para ordenar por data se você estiver colando valores em um banco de dados

RobV
fonte
5
Por que você consegue 21 meses e só consegue 12? :)
PaulB
2
O token para o ano deve estar em minúsculas aqui: return value.ToString ("yyyyMMddHHmmssffff");
Don Cote
1
@RobV A questão pede precisão de milissegundos, então você precisa de 3 'f's no final. Seus 4 'f's fornecem uma precisão de 100 microsend.
Eugene Beresovsky
2
Esteja ciente de que o Compact Framework não transfere os milissegundos. Eles sempre serão 0. Você deve modificar o código e adicionar algo como isto: int tick = Environment.TickCount% 1000; int ms = (tick> = MOffset)? (tick - MOffset): (1000 - (MOffset - tick)); ms = Math.Min (999, Math.Max ​​(0, ms));
Redwolf
43

Eu acredito que você pode criar um datestamp estilo Unix com precisão de um segundo usando o seguinte

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

Ajustar o denominador permite que você escolha seu nível de precisão

Voxel
fonte
19

Você poderia usar a propriedade DateTime.Ticks, que é um longo e universal armazenável, sempre crescente e utilizável também no framework compacto. Apenas certifique-se de que seu código não seja usado depois de 31 de dezembro de 9999;)

Frans Bouma
fonte
Quando você diz "sempre aumentando", não há garantia de que duas chamadas para DateTime.UtcNow.Ticks fornecerão valores diferentes, certo? Em outras palavras, você ainda precisa de algum cuidado antes de usá-lo como um carimbo de data / hora exclusivo.
Jon Skeet
9
@Konstantinos: você não pode evitar duplicatas se usar carimbos de data / hora. Os carimbos de data / hora não são usados ​​para chaves exclusivas, mas para marcar um tempo. Você disse que precisava de precisão de milissegundos, e ticks tem precisão de 100 ns. A questão é que você terá duplicatas. Se você não quer isso, você precisa de uma sequência única no banco de dados, o que infelizmente não é independente do banco de dados.
Frans Bouma
3
"é uma contagem real de carrapatos que aumenta com o tempo". Mas o relógio do sistema pode retroceder - por exemplo, no final do horário de verão, se você estiver usando a hora local, ou porque o relógio do sistema foi ajustado.
Joe
1
@Frans: absolutamente. Só fiz o comentário porque as pessoas deveriam pensar nas implicações da solução que escolheram. Por exemplo, eu usaria o UTC em vez da hora local para, pelo menos, eliminar os problemas do DST.
Joe
1
@konstantinos: hmm ... os docs dizem que tem 100ns de precisão, então é estranho que não tenha a precisão documentada. Talvez seja o framework compacto de fato, não é um framework sem bugs
Frans Bouma
6

Você também pode usar

Stopwatch.GetTimestamp (). ToString ();

mgokhanbakal
fonte
4

quando precisar de um carimbo de data / hora em segundos, você pode usar o seguinte:

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

Se você deseja carimbos de data / hora que correspondam a tempos reais reais, MAS também deseja que sejam exclusivos (para uma determinada instância do aplicativo), você pode usar o seguinte código:

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
fonte