O ile mi czegoś nie brakuje, „epoka” jest po prostu punktem początkowym określonego schematu pomiaru czasu. Przykłady obejmują 1/1/0001, 1/1/1970 i 1/1/2000. To bardziej atrybut schematu niż samego schematu (np. Julian).
Bob Kaufman
8
Czas od epoki to liczba sekund od 1 stycznia 1970 roku UTC.
Taylor Leese
13
@Taylor To epoka czasu uniksowego i prawdopodobnie ma rację, ale to nie jedyna ważna epoka. Użytkownicy czasu uniksowego nie powinni się mylić w tym punkcie.
Aby to działało poprawnie, musiałem zmienić .AddSeconds na .AddMilliseconds. Będziesz musiał wiedzieć, czy twój numer pochodzi z Sekundy czy Milisekund, aby uzyskać poprawny wynik. Na przykład następująca data: 1406310305188 (25 lipca 2014 r.). epochconverter.com pozwoli ci również sprawdzić wyniki konwersji.
jrandomuser
5
Powinieneś albo zmienić typ parametru na double (ponieważ AddSeconds akceptuje double, a zatem zostanie zmniejszony do double) lub dodaj zastrzeżenie do opisu metody, że zachowane zostaną tylko 53 z 64 bitów precyzji w argumencie.
tomosius
6
@jrandomuser: Czas epoki uniksowej jest tradycyjnie reprezentowany jako sekundy od Epoki. Od tego czasu powszechne jest używanie milisekund od Epoki (na przykład JavaScript), ale klasyczna definicja to sekundy. Podsumowując, po prostu wiedz, jaka jest twoja wartość wejściowa (sekundy, milisekundy, tiki, cokolwiek) i użyj właściwej AddXYZmetody.
TJ Crowder,
Najpierw spróbuj z AddMilliseconds, a jeśli nadal jest rok 1970, wykonaj AddSeconds. W ten sposób będzie działał cały czas, bez martwienia się o milisekundy lub sekundy. Dodatkowo możesz zapobiec przepełnieniu. Przekazywanie dużej liczby do AddSeconds spowoduje awarię kodu
Tono Nam
213
Najnowszą wersję .NET (v4.6) po prostu dodał wbudowane wsparcie dla systemu UNIX konwersji czasowych. Obejmuje to zarówno do, jak i od czasu uniksowego reprezentowanego przez sekundy lub milisekundy.
Należy zwrócić uwagę na komentarz poniżej z CodesInChaos że powyższe FromUnixTimeZwraca DateTimez Kindod Utc, co jest w porządku, ale wyżej ToUnixTimejest o wiele bardziej podejrzany, który nie bierze pod uwagę, jakie DateTimedana datejest. Aby umożliwić date„s Kindjest albo Utcalbo Local, użyj ToUniversalTime:
ToUnixTimedziała poprawnie tylko wtedy, gdy data jest w Utc. Dodaj czek lub przekonwertuj go. (Osobiście wolę czek)
CodesInChaos
2
Właśnie spędziłem ostatnią godzinę zastanawiając się, dlaczego to nie działa. Musisz pracować w millisecondsnie sekund !!!
KristianB,
7
@KristianB: „Czas uniksowy” to tradycyjnie sekundy, a nie milisekundy od Epoki, chociaż obecnie staram się sprawdzić, jakiej definicji używa ktoś. Sekundy były wystarczająco dobre i dawały nam rozsądny zasięg po obu stronach Epoki w wartościach 32-bitowych ze znakiem. (I dlatego tuż po 03:14 19 stycznia 2038 GMT może być dla niektórych zły moment ...) Używanie milisekund jest bardziej nowoczesną praktyką, ponieważ rutynowo jesteśmy w stanie wyrzucać około 64-bitowych wartości (obie integralne i podwójnej precyzji IEEE-754) ...
TJ Crowder
5
Dzięki za kod. Tylko niewielka rekomendacja podczas tworzenia podstawy Epoki: pamiętaj, aby jawnie ustawić wartość Millisecond na 0. tzn. Var epoch = new DateTime (1970, 1, 1, 0 / * h * /, 0 / * m * /, 0 / * s * /, 0 / * ms * /, DateTimeKind.Utc); Jeśli nie ustawisz go wyraźnie, wartość milisekundy wydaje się wynosić 1. To spowodowało pewne niespójności w moich testach.
ctrlplusb
1
Powinieneś użyć AddMillisecondsi powinieneś użyć Double NOT Float. W przeciwnym razie skończy się zły czas.
Axel
25
Naprawdę chcesz dodać milisekundy (milisekundy), a nie sekundy. Dodanie sekund da wyjątek poza zakresem.
Dlaczego? epochconverter.com Mówi, że dodajesz liczbę sekund od 1/1/970, a nie ms.
Jamie R Rytlewski
Jeśli wybierasz się z ms, to oczywiście chcesz, AddMillisa jeśli zaczynasz od sekund, to oczywiście chcesz AddSeconds.
But
Miałem ten sam problem, z którego korzystałem przez kilka sekund. Czas uniksowy, który próbowałem przekonwertować, trwał w milisekundach. Myślałem, że to w kilka sekund. Wydaje mi się, że jakiś czas uniksowy jest mierzony w milisekundach.
DoodleKana,
Czas uniksowy jest zwykle wyrażany w sekundach, ale 0,001 jest prawidłową liczbą sekund (= 1 ms). W razie wątpliwości użyj maksymalnej możliwej precyzji.
Scott,
9
Jeśli chcesz uzyskać lepszą wydajność, możesz użyć tej wersji.
DateTime.Ticks - każdy tik to „sto nanosekund”, co czyni go dodatkową „rzeczą” do zapamiętania. Jeśli pominiesz oba .Ticks, odzyskasz ładną instancję TimeSpan z odejmowania DateTime.
/// <summary>/// DateTime as UTV for UnixEpoch/// </summary>publicstaticreadonlyDateTimeUnixEpoch=newDateTime(1970,1,1,0,0,0,0,DateTimeKind.Utc);/// <summary>/// Per JWT spec:/// Gets the number of seconds from 1970-01-01T0:0:0Z as measured in UTC until the desired date/time./// </summary>/// <param name="datetime">The DateTime to convert to seconds.</param>/// <remarks>if dateTimeUtc less than UnixEpoch, return 0</remarks>/// <returns>the number of seconds since Unix Epoch.</returns>publicstaticlongGetIntDate(DateTime datetime){DateTime dateTimeUtc = datetime;if(datetime.Kind!=DateTimeKind.Utc){
dateTimeUtc = datetime.ToUniversalTime();}if(dateTimeUtc.ToUniversalTime()<=UnixEpoch){return0;}return(long)(dateTimeUtc -UnixEpoch).TotalSeconds;}
czy to konto dotyczy lat przestępnych i sekund przestępnych itp.?
Jodrell,
1
Aby rozwinąć poprzedni komentarz, oto krótkie wideo wyjaśniające, dlaczego czas jest skomplikowany i dlaczego nie powinieneś próbować robić tego sam: youtube.com/watch?v=-5wpm-gesOY
Odpowiedzi:
Zakładam, że masz na myśli czas uniksowy , który jest zdefiniowany jako liczba sekund od północy (UTC) 1 stycznia 1970 r.
źródło
AddXYZ
metody.Najnowszą wersję .NET (v4.6) po prostu dodał wbudowane wsparcie dla systemu UNIX konwersji czasowych. Obejmuje to zarówno do, jak i od czasu uniksowego reprezentowanego przez sekundy lub milisekundy.
DateTimeOffset
:DateTimeOffset
do czasu uniksowego w sekundach:DateTimeOffset
:DateTimeOffset
do czasu uniksowego w milisekundach:Uwaga: Te metody są konwertowane na i z
DateTimeOffset
. Aby uzyskaćDateTime
reprezentację, wystarczy użyćDateTimeOffset.DateTime
właściwości:źródło
'DateTimeOffset' does not contain a definition for 'FromUnixTimeSeconds'
Jak mógłbym rozwiązać ten problem?Z całym podziękowaniem dla LukeH, opracowałem kilka metod rozszerzenia dla łatwego użycia:
Należy zwrócić uwagę na komentarz poniżej z CodesInChaos że powyższe
FromUnixTime
ZwracaDateTime
zKind
odUtc
, co jest w porządku, ale wyżejToUnixTime
jest o wiele bardziej podejrzany, który nie bierze pod uwagę, jakieDateTime
danadate
jest. Aby umożliwićdate
„sKind
jest alboUtc
alboLocal
, użyjToUniversalTime
:ToUniversalTime
przekonwertujeLocal
(lubUnspecified
)DateTime
naUtc
.jeśli nie chcesz tworzyć instancji DateTime epoki podczas przenoszenia z DateTime do epoki, możesz również:
źródło
ToUnixTime
działa poprawnie tylko wtedy, gdy data jest w Utc. Dodaj czek lub przekonwertuj go. (Osobiście wolę czek)milliseconds
nie sekund !!!AddMilliseconds
i powinieneś użyć Double NOT Float. W przeciwnym razie skończy się zły czas.Naprawdę chcesz dodać milisekundy (milisekundy), a nie sekundy. Dodanie sekund da wyjątek poza zakresem.
źródło
AddMillis
a jeśli zaczynasz od sekund, to oczywiście chceszAddSeconds
.Jeśli chcesz uzyskać lepszą wydajność, możesz użyć tej wersji.
Z szybkiego testu porównawczego (BenchmarkDotNet) pod net471 otrzymuję ten numer:
2x szybciej w porównaniu z wersją LukeH (jeśli wydajność ma znaczenie)
Jest to podobne do wewnętrznego działania DateTime.
źródło
Użyj metody DateTimeOffset.ToUnixTimeMilliseconds () Zwraca liczbę milisekund, które upłynęły od 1970-01-01T00: 00: 00.000Z.
Jest tu dobrze udokumentowane DateTimeOffset.ToUnixTimeMilliseconds
Innym wyjściem jest skorzystanie z poniższych
Aby uzyskać EPOCH w kilka sekund, możesz użyć tylko tego
i przekonwertować
Epoch
doDateTime
z następującym sposobemźródło
.Ticks
, odzyskasz ładną instancję TimeSpan z odejmowania DateTime.Należy użyć ToUniversalTime () dla obiektu DateTime.
źródło
Używam następujących metod rozszerzenia do konwersji epoki
źródło
Aby nie martwić się o użycie milisekund lub sekund, po prostu:
Jeśli czas epoki jest w sekundach, nie można w żaden sposób przekroczyć roku 1972, dodając milisekundy.
źródło
Jeśli nie korzystasz z wersji 4.6, może to pomóc Source: System.IdentityModel.Tokens
źródło
using Microsoft.IdentityModel.Tokens; ... EpochTime.GetIntDate(dateTime);
Jeśli chcesz przekonwertować strukturę czasową (sekundy, mikrosekundy) zawierającą
UNIX time
naDateTime
bez utraty precyzji, oto jak to zrobić :źródło
Od wersji .Net 4.6 i nowszych należy używać funkcji DateTimeOffset.Now.ToUnixTimeSeconds ()
źródło
Oto moje rozwiązanie:
źródło