Respuestas:
Obtiene una marca de tiempo de Unix en C # al usar DateTime.UtcNow
y restar el tiempo de la época de 1970-01-01.
p.ej
Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
DateTime.UtcNow
se puede reemplazar con cualquier DateTime
objeto para el que desea obtener la marca de tiempo de Unix.
También hay un campo, DateTime.UnixEpoch
que está muy poco documentado por MSFT, pero puede ser un sustituto denew DateTime(1970, 1, 1)
DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).Ticks / TimeSpan.TicksPerSecond;
A partir de .NET 4.6, existe DateTimeOffset.ToUnixTimeSeconds()
.
Este es un método de instancia, por lo que se espera que lo llame en una instancia de DateTimeOffset
. También puede emitir cualquier instancia de DateTime
, aunque tenga cuidado con la zona horaria .
Para obtener la marca de tiempo actual:
DateTimeOffset.UtcNow.ToUnixTimeSeconds()
Para obtener la marca de tiempo de un DateTime
:
DateTime foo = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)foo).ToUnixTimeSeconds();
Int64
: para cuando se da la vuelta, ya no estaríamos usando los años de la Tierra por falta de una Tierra.
DateTimeOffset.Now.ToUnixTimeSeconds()
También puedes usar garrapatas. Estoy codificando para Windows Mobile, así que no tengo el conjunto completo de métodos. TotalSeconds no está disponible para mí.
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 tiempo con Kind
propiedad no especificada . Lo que realmente quieres que new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
sea realmente correcto
Esto es lo que uso:
public long UnixTimeNow()
{
var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0));
return (long)timeSpan.TotalSeconds;
}
Tenga en cuenta que este método devolverá la hora como hora universal coordinada (UTC).
double
tipo; si lo hace demasiado largo, perderá precisión.)
Truncar .TotalSeconds
es importante ya que se define comothe value of the current System.TimeSpan structure expressed in whole fractional seconds.
¿Y qué tal una extensión para DateTime
? El segundo es probablemente más confuso que vale la pena hasta que existan extensiones de propiedad.
/// <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);
}
Cuando resta 1970 del tiempo actual, tenga en cuenta que el intervalo de tiempo tendrá un campo de milisegundos distinto de cero. Si por alguna razón está interesado en los milisegundos, tenga esto en cuenta.
Esto es lo que hice para solucionar este 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.
Esto es lo que yo 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;
}
}
He unido los enfoques más elegantes para este método de utilidad:
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;
}
Esta solución ayudó en mi situación:
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 ayuda en el código:
double ret = DateHelper.DateTimeToUnixTimestamp(DateTime.Now)
Hay un ToUnixTimeMilliseconds para DateTimeOffset en el sistema
Puede escribir un método similar para DateTime:
public static long ToUnixTimeSeconds(this DateTime value)
{
return value.Ticks / 10000000L - 62135596800L;
}
10000000L - convirtiendo ticks a segundos
62135596800L - convirtiendo 01.01.01 a 01.01.1978
No hay problema con Utc y fugas
A continuación se muestra una clase de extensión de 2 vías que admite:
En el caso de OP, el uso es:
DateTime.Now.ToUnixtime();
o
DateTime.UtcNow.ToUnixtime();
Aunque existe una respuesta directa, creo que usar un enfoque genérico es mejor. Especialmente porque es muy probable que un proyecto que necesite una conversión como esta, también necesite estas extensiones de todos modos, por lo que es mejor usar la misma herramienta para todos.
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;
}
}
}
Usé esto después de luchar por un tiempo, también atiende el desplazamiento de la zona horaria:
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;
}
El código simple que estoy usando:
public static long CurrentTimestamp()
{
return (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds * 1000);
}
Este código proporciona una marca de tiempo de Unix, milisegundos totales desde 1970-01-01 hasta ahora.