Odpowiedzi:
Otrzymasz uniksowy znacznik czasu w języku C #, używając DateTime.UtcNow
i odejmując czas epoki 1970-01-01.
na przykład
Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
DateTime.UtcNow
można zastąpić dowolnym DateTime
obiektem, dla którego chcesz uzyskać znacznik czasu unix.
Istnieje również pole, DateTime.UnixEpoch
które jest bardzo słabo udokumentowane przez MSFT, ale może być zamiennikiemnew DateTime(1970, 1, 1)
DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).Ticks / TimeSpan.TicksPerSecond;
Od wersji .NET 4.6 istnieje DateTimeOffset.ToUnixTimeSeconds()
.
Jest to metoda instancji, dlatego należy wywoływać ją w instancji DateTimeOffset
. Możesz także rzucić dowolną instancję DateTime
, choć strzeż się strefy czasowej .
Aby uzyskać bieżący znacznik czasu:
DateTimeOffset.UtcNow.ToUnixTimeSeconds()
Aby uzyskać znacznik czasu z DateTime
:
DateTime foo = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)foo).ToUnixTimeSeconds();
Int64
- do czasu, gdy się przewróci, nie będziemy już korzystać z ziemskich lat z powodu braku Ziemi.
DateTimeOffset.Now.ToUnixTimeSeconds()
Możesz także użyć Kleszczy. Piszę dla Windows Mobile, więc nie mam pełnego zestawu metod. TotalSeconds nie jest dla mnie dostępny.
long epochTicks = new DateTime(1970, 1, 1).Ticks;
long unixTime = ((DateTime.UtcNow.Ticks - epochTicks) / TimeSpan.TicksPerSecond);
lub
TimeSpan epochTicks = new TimeSpan(new DateTime(1970, 1, 1).Ticks);
TimeSpan unixTicks = new TimeSpan(DateTime.UtcNow.Ticks) - epochTicks;
double unixTime = unixTicks.TotalSeconds;
new DateTime(1970, 1, 1)
tworzy czas z nieokreśloną Kind
właściwością. To, co naprawdę chcesz new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
być naprawdę poprawne
Oto, czego używam:
public long UnixTimeNow()
{
var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0));
return (long)timeSpan.TotalSeconds;
}
Należy pamiętać, że ta metoda zwróci czas jako skoordynowany czas uniwersalny (UTC).
double
typ; rzutowanie na długi spowoduje utratę precyzji.)
Obcinanie .TotalSeconds
jest ważne, ponieważ jest zdefiniowane jakothe value of the current System.TimeSpan structure expressed in whole fractional seconds.
A może rozszerzenie DateTime
? Drugi jest prawdopodobnie bardziej mylący, że jest wart, dopóki nie pojawią się rozszerzenia własności.
/// <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);
}
Kiedy odejmiesz 1970 od bieżącego czasu, pamiętaj, że przedział czasu najczęściej będzie miał niezerowe pole milisekund. Jeśli z jakiegoś powodu jesteś zainteresowany milisekundami, pamiętaj o tym.
Oto, co zrobiłem, aby obejść ten problem.
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.
Tego używam.
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;
}
}
Połączyłem najbardziej eleganckie podejścia do tej metody użyteczności:
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;
}
To rozwiązanie pomogło w mojej sytuacji:
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;
}
}
za pomocą pomocnika w kodzie:
double ret = DateHelper.DateTimeToUnixTimestamp(DateTime.Now)
W systemie istnieje ToUnixTimeMilliseconds dla DateTimeOffset
Możesz napisać podobną metodę dla DateTime:
public static long ToUnixTimeSeconds(this DateTime value)
{
return value.Ticks / 10000000L - 62135596800L;
}
10000000L - konwersja tyknięć na sekundy
62135596800L - konwersja 01.01.01 na 01.01.1978
Nie ma problemu z Utc i przeciekami
Poniżej znajduje się dwukierunkowa klasa rozszerzenia, która obsługuje:
W przypadku OP użycie to:
DateTime.Now.ToUnixtime();
lub
DateTime.UtcNow.ToUnixtime();
Chociaż istnieje bezpośrednia odpowiedź, uważam, że zastosowanie podejścia ogólnego jest lepsze. Zwłaszcza, że najprawdopodobniej jest to projekt, który wymaga takiej konwersji, i tak będzie potrzebował tych rozszerzeń, dlatego lepiej jest używać tego samego narzędzia dla wszystkich.
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;
}
}
}
Użyłem tego po dłuższej walce, dotyczy to również przesunięcia strefy czasowej:
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;
}
Prosty kod, którego używam:
public static long CurrentTimestamp()
{
return (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds * 1000);
}
Ten kod podaje uniksowy znacznik czasu, łącznie milisekund od 1970-01-01 do chwili obecnej.