Como obter o timestamp unix em c #


Respostas:


597

Você obtém um registro de data e hora unix em C # usando DateTime.UtcNowe subtraindo o tempo da época de 01-01-2009.

por exemplo

Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;

DateTime.UtcNowpode ser substituído por qualquer DateTimeobjeto para o qual você gostaria de obter o registro de data e hora unix.

Há também um campo, DateTime.UnixEpochque é muito mal documentado pelo MSFT, mas pode ser um substituto paranew DateTime(1970, 1, 1)


28
Comentando em nome de @wdhough. "Esta resposta tem limitação com o limite do Int32, que é, acredito, 2.147.483.647. Segundo onlineconversion.com/unix_time.htm, isso equivale a um horário de ter, 19 de janeiro de 2038 03:14:07 GMT Acho que qualquer tipo de número alternativo , double, longo, etc acabará por ter um limite muito, mas eu pensei que vale a pena mencionar que eu escolher longo aqui como eu queria um número inteiro Espero que isso ajude.".
Ismails

11
O registro de data e hora do unix é tradicionalmente um número inteiro de 32 bits e tem um intervalo de '1970-01-01 00:00:01' UTC a '2038-01-19 03:14:07' UTC.
the_nuts

89
É uma loucura que a conversão de horário do UNIX não esteja na biblioteca padrão como parte do DateTime.
Xingyu

7
Ou usando aritmética inteira:DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).Ticks / TimeSpan.TicksPerSecond;
Anton Petrov

2
O datetime subtraído não precisa ser UTC?
Jjxtra #

573

A partir do .NET 4.6, existe DateTimeOffset.ToUnixTimeSeconds().


Este é um método de instância, portanto, você deve chamá-lo em uma instância de DateTimeOffset. Você também pode transmitir qualquer instância de DateTime, embora tenha cuidado com o fuso horário .

Para obter o carimbo de data / hora atual:

DateTimeOffset.UtcNow.ToUnixTimeSeconds()

Para obter o registro de data e hora de DateTime:

DateTime foo = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)foo).ToUnixTimeSeconds();

126
Boa. É sobre o tempo #
22416 bizzehdee

35
@MattBorja Felizmente, ele retorna um Int64- no momento em que rola, não estaríamos mais usando os anos da Terra por falta de uma Terra.
Bob

24
Para qualquer outra pessoa perguntando, você pode obter o timestamp atual comDateTimeOffset.Now.ToUnixTimeSeconds()
kR105

8
@bizzehdee, Pun pretendeu?
26517 st0le

5
Você pode obter o unixtimestamp UTC com: DateTimeOffset.UtcNow.ToUnixTimeSeconds ()
Yair Levi

39

Você também pode usar carrapatos. Estou codificando para o Windows Mobile, para não ter o conjunto completo de métodos. O TotalSeconds não está disponível para mim.

long epochTicks = new DateTime(1970, 1, 1).Ticks;
long unixTime = ((DateTime.UtcNow.Ticks - epochTicks) / TimeSpan.TicksPerSecond);

ou

TimeSpan epochTicks = new TimeSpan(new DateTime(1970, 1, 1).Ticks);
TimeSpan unixTicks = new TimeSpan(DateTime.UtcNow.Ticks) - epochTicks;
double unixTime = unixTicks.TotalSeconds;

11
Erro para a segunda solução: Não é possível converter o tipo de origem 'double' para o tipo de destino 'long'.
Pixar

@Pixar: A segunda amostra é fixa
JBert

5
new DateTime(1970, 1, 1)cria um horário com Kindpropriedade não especificada . O que você realmente quer new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)ser verdadeiramente correta
Detunized

Do .NET Core 2.1 Você pode usar o DateTime.UnixEpoch em vez do novo DateTime (1970, 1, 1), consulte docs.microsoft.com/en-us/dotnet/api/…
Jaa H

27

Isto é o que eu uso:

public long UnixTimeNow()
{
    var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0));
    return (long)timeSpan.TotalSeconds;
}

Lembre-se de que esse método retornará a hora como Hora Universal Coordenada (UTC).


(TotalSeconds tem doubletipo, lançando-a longa irá causar perda de precisão.)
frankish

Você direito, mas não temos que se preocupar com isso por vários milhares de anos :)
Bartłomiej Mucha

21

O truncamento .TotalSecondsé importante, pois é definido comothe value of the current System.TimeSpan structure expressed in whole fractional seconds.

E que tal uma extensão para DateTime? O segundo é provavelmente mais confuso que vale a pena até que existam extensões de propriedade.

/// <summary>
/// Converts a given DateTime into a Unix timestamp
/// </summary>
/// <param name="value">Any DateTime</param>
/// <returns>The given DateTime in Unix timestamp format</returns>
public static int ToUnixTimestamp(this DateTime value)
{
    return (int)Math.Truncate((value.ToUniversalTime().Subtract(new DateTime(1970, 1, 1))).TotalSeconds);
}

/// <summary>
/// Gets a Unix timestamp representing the current moment
/// </summary>
/// <param name="ignored">Parameter ignored</param>
/// <returns>Now expressed as a Unix timestamp</returns>
public static int UnixTimestamp(this DateTime ignored)
{
    return (int)Math.Truncate((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds);
}

2
O método de extensão é claramente a maneira de fazer isso perfeitamente. Essa é uma resposta excelente e madura - e eu não entendo por que ela tem tão poucos votos. Tenha certeza de que Robba está correto - converter a saída como (int) trunca automaticamente o resultado. (Literalmente ignorando a parte decimal do dobro).
23715 Stephanie

4
(este DateTime ignorado) é muito, muito enganosa
Lars Corneliussen

6

Ao subtrair 1970 do horário atual, lembre-se de que o período de tempo geralmente terá um campo diferente de zero milissegundos. Se, por algum motivo, você estiver interessado em milissegundos, lembre-se disso.

Aqui está o que eu fiz para contornar esse problema.

 DateTime now = UtcNow();

 // milliseconds Not included.
 DateTime nowToTheSecond = new DateTime(now.Year,now.Month,now.Day,now.Hour,now.Minute,now.Second); 

 TimeSpan span = (date - new DateTime(1970, 1, 1, 0, 0, 0, 0));

 Assert.That(span.Milliseconds, Is.EqualTo(0)); // passes.

5

É isso que eu uso.

 public class TimeStamp
    {
        public Int32 UnixTimeStampUTC()
        {
            Int32 unixTimeStamp;
            DateTime currentTime = DateTime.Now;
            DateTime zuluTime = currentTime.ToUniversalTime();
            DateTime unixEpoch = new DateTime(1970, 1, 1);
            unixTimeStamp = (Int32)(zuluTime.Subtract(unixEpoch)).TotalSeconds;
            return unixTimeStamp;
        }
}

talvez torná-lo um método de extensão de DateTime
bizzehdee

3

Eu juntei as abordagens mais elegantes desse método utilitário:

public static class Ux {
    public static decimal ToUnixTimestampSecs(this DateTime date) => ToUnixTimestampTicks(date) / (decimal) TimeSpan.TicksPerSecond;
    public static long ToUnixTimestampTicks(this DateTime date) => date.ToUniversalTime().Ticks - UnixEpochTicks;
    private static readonly long UnixEpochTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
}

2

Esta solução ajudou na minha situação:

   public class DateHelper {
     public static double DateTimeToUnixTimestamp(DateTime dateTime)
              {
                    return (TimeZoneInfo.ConvertTimeToUtc(dateTime) -
                             new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds;
              }
    }

usando helper no código:

double ret = DateHelper.DateTimeToUnixTimestamp(DateTime.Now)

0

Há ToUnixTimeMilliseconds para DateTimeOffset no sistema

Você pode escrever um método semelhante para o DateTime:

public static long ToUnixTimeSeconds(this DateTime value)
{
    return value.Ticks / 10000000L - 62135596800L;
}

10000000L - convertendo ticks em segundos

62135596800L - convertendo 01.01.01 para 01.01.1978

Não há nenhum problema com Utc e vazamentos



0

Abaixo está uma classe de extensão bidirecional que suporta:

  • Localização de fuso horário
  • Entrada \ saída em segundos ou milissegundos.

No caso do OP, o uso é:

DateTime.Now.ToUnixtime();

ou

DateTime.UtcNow.ToUnixtime();

Embora exista uma resposta direta, acredito que usar uma abordagem genérica é melhor. Especialmente porque é mais provável que um projeto que precise de uma conversão como essa também precise dessas extensões, então é melhor usar a mesma ferramenta para todos.

    public static class UnixtimeExtensions
    {
        public static readonly DateTime UNIXTIME_ZERO_POINT = new DateTime(1970, 1, 1, 0, 0,0, DateTimeKind.Utc);

        /// <summary>
        /// Converts a Unix timestamp (UTC timezone by definition) into a DateTime object
        /// </summary>
        /// <param name="value">An input of Unix timestamp in seconds or milliseconds format</param>
        /// <param name="localize">should output be localized or remain in UTC timezone?</param>
        /// <param name="isInMilliseconds">Is input in milliseconds or seconds?</param>
        /// <returns></returns>
        public static DateTime FromUnixtime(this long value, bool localize = false, bool isInMilliseconds = true)
        {
            DateTime result;

            if (isInMilliseconds)
            {
                result = UNIXTIME_ZERO_POINT.AddMilliseconds(value);
            }
            else
            {
                result = UNIXTIME_ZERO_POINT.AddSeconds(value);
            }

            if (localize)
                return result.ToLocalTime();
            else
                return result;
        }

        /// <summary>
        /// Converts a DateTime object into a Unix time stamp
        /// </summary>
        /// <param name="value">any DateTime object as input</param>
        /// <param name="isInMilliseconds">Should output be in milliseconds or seconds?</param>
        /// <returns></returns>
        public static long ToUnixtime(this DateTime value, bool isInMilliseconds = true)
        {
            if (isInMilliseconds)
            {
                return (long)value.ToUniversalTime().Subtract(UNIXTIME_ZERO_POINT).TotalMilliseconds;
            }
            else
            {
                return (long)value.ToUniversalTime().Subtract(UNIXTIME_ZERO_POINT).TotalSeconds;
            }
        }
    }

Cuidado para não confundir os formatos de milissegundos e segundos (o melhor caso é uma exceção, o pior é a conversão ilógica) Eu padronizei a entrada \ output para o formato de milissegundos. Se você preferir usar o formato de segundos como padrão, mude o isInMilliseconds = true (nos dois métodos) para false.
SingleFlake

0

Eu usei isso depois de lutar por um tempo, que também serve para o deslocamento do fuso horário:

    public double Convert_DatTime_To_UNIXDATETIME(DateTime dt)
    {
        System.DateTime from_date = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
        double unix_time_since = dt.Subtract(from_date).TotalMilliseconds;

        TimeSpan ts_offset = TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow);

        double offset = ts_offset.TotalMilliseconds;

        return unix_time_since - offset;
    }

-1

O código simples que estou usando:

public static long CurrentTimestamp()
{
   return (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds * 1000);
}

Este código está fornecendo um carimbo de data / hora unix, total de milissegundos de 01-01-2009 até agora.

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.