Przedstawienie DateTime w milisekundach?

81

Mam sygnaturę czasową serwera SQL, którą muszę przekonwertować na reprezentację czasu w milisekundach od 1970 r. Czy mogę to zrobić za pomocą zwykłego języka SQL? Jeśli nie, wyodrębniłem go do DateTimezmiennej w C #. Czy można uzyskać reprezentację w milisekundach?

Dzięki,
Teja.

Tejaswi Yerukalapudi
źródło
1
W przypadku drugiego pytania :, (now - Epoch).TotalMillisecondsgdzie nowi Epochsą obiektami DateTime.

Odpowiedzi:

143

Prawdopodobnie próbujesz przekonwertować na znacznik czasu podobny do UNIX, który jest w UTC:

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

Pozwala to również uniknąć problemów w okresie letnim, ponieważ UTC ich nie ma.

Andomar
źródło
2
to daje ułamek jako wynik, na przykład: „1552678714362,79” Skąd pochodzi „0,79”?
Sharif Yazdian
2
@SharifYazdian To jest dokładnie to, czego można by się spodziewać, to 0,79 milisekundy. Czas systemowy jest mierzony w taktach. Zakładając, że 1 milisekunda ma 10000 taktów DateTimei TimeSpanprzechowuj ich wartości z większą dokładnością niż całe milisekundy. 0,79 ms = 7900 tyknięć. Jeśli potrzebujesz liczby całkowitej, możesz użyć long ms = myTimeSpan.TotalTicks / 10000;.
LWChris
2
W .NET Core (> 2,1) można użyć DateTime.UnixEpochzamiast deklarowania daty.
Thom
1
Ten kod ma problem: zakłada, że DateTime(patrz uwaga w umowie ToUniversalTime) jest w czasie lokalnym, czego nie może. Na przykład często próbkuje się czas z DateTime.UtcNowinną strefą czasową lub może to być w innej strefie czasowej.
ceztko
70

W C # możesz pisać

(long)(date - new DateTime(1970, 1, 1)).TotalMilliseconds
SLaks
źródło
15
Proponuję obsadę longzamiast int:)
Jon Skeet
4
new DateTime(1970, 1, 1).AddMilliseconds(myDateAsALong);Jeśli chcesz iść w drugą stronę.
JackMorrissey
@JackMorrissey: AddMilliseconds()oczekuje parametru typu double. Dba o to niejawna konwersja, ale warto zauważyć.
Axel Kemper
@JonSkeet Dlaczego sugerujesz rzutowanie na long zamiast int? :)
Roxy'Pro
4
@ Roxy'Pro: int.MaxValuew milisekundach to około 25 dni. To raczej nie będzie przydatne.
Jon Skeet
35

Począwszy od .NET 4.6, można użyć DateTimeOffsetobiektu, aby uzyskać milisekundy systemu UNIX. Ma konstruktora, który pobiera DateTimeobiekt, więc możesz po prostu przekazać swój obiekt, jak pokazano poniżej.

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

Jak wspomniano w innych odpowiedziach, upewnij się, yourDateTimeże Kindpodano poprawne lub użyj.ToUniversalTime() najpierw, aby przekonwertować go na czas UTC.

Tutaj możesz dowiedzieć się więcej o DateTimeOffset.

Pion
źródło
1
ToUnixTimeMilliseconds () w rzeczywistości nie istnieje w .Net 3.5.
NickLokarno
2
Według MSDN , ToUnixTimeMilliseconds()jest dostępny od .NET 4.6
NM
1
@kayleeFrye_onDeck OP pyta o sygnaturę czasową pobraną z bazy danych, więc Twój komentarz .Nownie dotyczy bezpośrednio tego pytania.
Bob
2
SELECT CAST(DATEDIFF(S, '1970-01-01', SYSDATETIME()) AS BIGINT) * 1000

Nie daje to pełnej precyzji, ale DATEDIFF(MS...powoduje przepełnienie. Jeśli sekundy są wystarczająco dobre, powinno to wystarczyć.


źródło
2

To inne rozwiązanie dla ukrytej daty i godziny do 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
źródło
1

Używając odpowiedzi Andomy, właśnie to robię

Możesz stworzyć Strukturę lub Klasę taką jak ta

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

    }

Możesz użyć tego w swoim kodzie w następujący sposób

DateTime dateTime = DateTime.Now;

double total = Date.GetTime(dateTime);

dateTime = Date.DateTimeParse(total);

Mam nadzieję, że to ci pomoże

Pablo V
źródło
1

Istnieją ToUnixTime()i ToUnixTimeMs()metody w klasie DateTimeExtensions

DateTime.UtcNow.ToUnixTimeMs()

dmirg
źródło