¿Representación de DateTime en milisegundos?

81

Tengo una marca de tiempo del servidor SQL que necesito convertir en una representación del tiempo en milisegundos desde 1970. ¿Puedo hacer esto con SQL simple? Si no, lo extraje en una DateTimevariable en C #. ¿Es posible obtener una representación en milisegundos de esto?

Gracias,
Teja.

Tejaswi Yerukalapudi
fuente
1
Para la última pregunta:, (now - Epoch).TotalMillisecondsdónde nowy Epochson los objetos DateTime.

Respuestas:

140

Probablemente esté intentando convertir a una marca de tiempo similar a UNIX, que está en UTC:

yourDateTime.ToUniversalTime().Subtract(
    new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
    ).TotalMilliseconds

Esto también evita problemas de verano, ya que UTC no los tiene.

Andomar
fuente
2
esto da una fracción como salida, por ejemplo: "1552678714362.79" ¿De dónde viene el ".79"?
Sharif Yazdian
2
@SharifYazdian Es exactamente lo que cabría esperar, son 0,79 milisegundos. El tiempo del sistema se mide en tics. Dado que 1 milisegundo tiene 10000 tics DateTimey TimeSpanalmacena sus valores con mayor precisión que milisegundos completos. 0,79 ms = 7900 tics. Si necesita un número entero, puede usar long ms = myTimeSpan.TotalTicks / 10000;.
LWChris
2
En .NET Core (> 2.1) puede usar en DateTime.UnixEpochlugar de declarar la fecha.
Thom
1
Este código tiene un problema: asume que DateTime(mira la nota en el contrato de ToUniversalTime) está en la hora local, lo que podría no serlo. Por ejemplo, es común muestrear el tiempo con DateTime.UtcNowo podría ser en otra zona horaria.
ceztko
68

En C #, puedes escribir

(long)(date - new DateTime(1970, 1, 1)).TotalMilliseconds
SLaks
fuente
15
Sugiero un elenco en longlugar de int:)
Jon Skeet
4
new DateTime(1970, 1, 1).AddMilliseconds(myDateAsALong);Si quieres ir al otro lado.
JackMorrissey
@JackMorrissey: AddMilliseconds()espera un parámetro de tipo double. Una conversión implícita se encarga de eso, pero vale la pena señalarlo.
Axel Kemper
@JonSkeet ¿Por qué sugieres transmitir a long en lugar de int? :)
Roxy'Pro
4
@ Roxy'Pro: int.MaxValueen milisegundos es aproximadamente 25 días. Es poco probable que sea útil.
Jon Skeet
35

A partir de .NET 4.6, puede usar un DateTimeOffsetobjeto para obtener los milisegundos de Unix. Tiene un constructor que toma un DateTimeobjeto, por lo que puede pasar su objeto como se muestra a continuación.

DateTime yourDateTime;
long yourDateTimeMilliseconds = new DateTimeOffset(yourDateTime).ToUnixTimeMilliseconds();

Como se indica en otras respuestas, asegúrese de yourDateTimetener la Kindespecificación correcta o utilice .ToUniversalTime()para convertirla a la hora UTC primero.

Aquí puede obtener más información sobre DateTimeOffset.

Beto
fuente
1
ToUnixTimeMilliseconds () en realidad no existe en .Net 3.5.
NickLokarno
1
Según MSDN , ToUnixTimeMilliseconds()está disponible desde .NET 4.6
NM
1
@kayleeFrye_onDeck El OP está preguntando sobre una marca de tiempo extraída de una base de datos, por lo que su comentario sobre .Nowno se aplica directamente a esta pregunta.
Bob
2
SELECT CAST(DATEDIFF(S, '1970-01-01', SYSDATETIME()) AS BIGINT) * 1000

Esto no le da una precisión total, pero DATEDIFF(MS...provoca un desbordamiento. Si los segundos son lo suficientemente buenos, esto debería ser suficiente.


fuente
2

Esta otra solución para la fecha y hora encubierta para unixtimestampmillis C #.

private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

public static long GetCurrentUnixTimestampMillis()
{
    DateTime localDateTime, univDateTime;
    localDateTime = DateTime.Now;          
    univDateTime = localDateTime.ToUniversalTime();
    return (long)(univDateTime - UnixEpoch).TotalMilliseconds;
} 
samsanthosh2008
fuente
1

Usando la respuesta de Andoma, esto es lo que estoy haciendo

Puedes crear una estructura o una clase como esta

struct Date
    {
        public static double GetTime(DateTime dateTime)
        {
            return dateTime.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
        }

        public static DateTime DateTimeParse(double milliseconds)
        {
            return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(milliseconds).ToLocalTime();
        }

    }

Y puede usar esto en su código de la siguiente manera

DateTime dateTime = DateTime.Now;

double total = Date.GetTime(dateTime);

dateTime = Date.DateTimeParse(total);

Espero que esto te ayude

Pablo V
fuente
1

Hay ToUnixTime()y ToUnixTimeMs()métodos en la clase DateTimeExtensions

DateTime.UtcNow.ToUnixTimeMs()

dmirg
fuente