Risposte:
Ottieni un timestamp unix in C # usando DateTime.UtcNow
e sottraendo il tempo dell'epoca del 1970-01-01.
per esempio
Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
DateTime.UtcNow
può essere sostituito con qualsiasi DateTime
oggetto per il quale si desidera ottenere il timestamp unix.
C'è anche un campo, DateTime.UnixEpoch
che è scarsamente documentato da MSFT, ma può essere un sostitutonew DateTime(1970, 1, 1)
DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).Ticks / TimeSpan.TicksPerSecond;
A partire da .NET 4.6, c'è DateTimeOffset.ToUnixTimeSeconds()
.
Questo è un metodo di istanza, quindi dovresti chiamarlo su un'istanza di DateTimeOffset
. Puoi anche trasmettere qualsiasi istanza di DateTime
, anche se fai attenzione al fuso orario .
Per ottenere il timestamp corrente:
DateTimeOffset.UtcNow.ToUnixTimeSeconds()
Per ottenere il timestamp da un DateTime
:
DateTime foo = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)foo).ToUnixTimeSeconds();
Int64
- quando si ribalta , non avremmo più usato gli anni terrestri per mancanza di terra.
DateTimeOffset.Now.ToUnixTimeSeconds()
Puoi anche usare le zecche. Sto codificando per Windows Mobile, quindi non ho il set completo di metodi. TotalSeconds non è disponibile per me.
long epochTicks = new DateTime(1970, 1, 1).Ticks;
long unixTime = ((DateTime.UtcNow.Ticks - epochTicks) / TimeSpan.TicksPerSecond);
o
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)
crea un orario con Kind
proprietà non specificate . Quello che vuoi davvero new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
essere veramente corretto
Questo è quello che uso:
public long UnixTimeNow()
{
var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0));
return (long)timeSpan.TotalSeconds;
}
Tieni presente che questo metodo restituirà l'ora come Tempo coordinato universale (UTC).
double
tipo; lanciarlo a lungo causerà una perdita di precisione.)
Troncare .TotalSeconds
è importante poiché è definito comethe value of the current System.TimeSpan structure expressed in whole fractional seconds.
E che ne dici di un'estensione per DateTime
? Il secondo è probabilmente più confuso che vale fino a quando non esistono estensioni di proprietà.
/// <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);
}
Quando si sottraggono 1970 dall'ora corrente, tenere presente che l'intervallo di tempo avrà spesso un campo non zero millisecondi. Se per qualche motivo sei interessato ai millisecondi, tienilo a mente.
Ecco cosa ho fatto per aggirare questo 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.
Questo è quello che 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;
}
}
Ho unito gli approcci più eleganti a questo metodo di utilità:
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;
}
Questa soluzione mi ha aiutato nella mia situazione:
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 l'helper nel codice:
double ret = DateHelper.DateTimeToUnixTimestamp(DateTime.Now)
Esiste un ToUnixTimeMilliseconds per DateTimeOffset nel sistema
Puoi scrivere un metodo simile per DateTime:
public static long ToUnixTimeSeconds(this DateTime value)
{
return value.Ticks / 10000000L - 62135596800L;
}
10000000L - conversione di tick in secondi
62135596800L - conversione da 01.01.01 a 01.01.1978
Non ci sono problemi con Utc e perdite
Di seguito è una classe di estensione a 2 vie che supporta:
Nel caso di OP, l'utilizzo è:
DateTime.Now.ToUnixtime();
o
DateTime.UtcNow.ToUnixtime();
Anche se esiste una risposta diretta, credo che sia meglio usare un approccio generico. Soprattutto perché è molto probabile che un progetto abbia bisogno di una conversione come questa, avrà comunque bisogno di queste estensioni, quindi è meglio usare lo stesso strumento per tutti.
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;
}
}
}
L'ho usato dopo aver lottato per un po ', si rivolge anche all'offset del fuso orario:
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;
}
Il semplice codice che sto usando:
public static long CurrentTimestamp()
{
return (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds * 1000);
}
Questo codice indica unix timestamp, in millisecondi totali dal 1970-01-01 ad oggi.