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.


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


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


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


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


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;

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;
       }
   }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.