如何在c#中获得unix时间戳

我已经环顾stackoverflow,甚至看了一些建议的问题,似乎没有人回答,你如何在c#中获得unix时间戳?

717897 次浏览

通过使用DateTime.UtcNow并减去1970年01月01日的纪元时间,可以在c#中获得unix时间戳。

如。

Int32 unixTimestamp = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;

DateTime.UtcNow可以替换为任何DateTime对象,只要你想获取它的unix时间戳。

还有一个字段DateTime.UnixEpoch,它是MSFT的很少有文献记载,但可以替代new DateTime(1970, 1, 1)

这就是我用的。

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

这是我所使用的:

public long UnixTimeNow()
{
var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0));
return (long)timeSpan.TotalSeconds;
}

请记住,此方法将返回协调世界时(UTC)的时间。

截断.TotalSeconds很重要,因为它被定义为the value of the current System.TimeSpan structure expressed in whole fractional seconds.

如何扩展DateTime?第二种方法可能更令人困惑,在存在属性扩展之前,它是值得的。

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

你也可以使用Ticks。我正在为Windows Mobile编写代码,所以没有完整的方法集。TotalSeconds对我来说不可用。

long epochTicks = new DateTime(1970, 1, 1).Ticks;
long unixTime = ((DateTime.UtcNow.Ticks - epochTicks) / TimeSpan.TicksPerSecond);

TimeSpan epochTicks = new TimeSpan(new DateTime(1970, 1, 1).Ticks);
TimeSpan unixTicks = new TimeSpan(DateTime.UtcNow.Ticks) - epochTicks;
double unixTime = unixTicks.TotalSeconds;

当您从当前时间中减去1970时,请注意,时间跨度通常会有一个非零毫秒字段。如果出于某种原因,您对毫秒感兴趣,请记住这一点。

以下是我解决这个问题的方法。

 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.

这个解决方案对我的情况很有帮助:

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

在代码中使用helper:

double ret = DateHelper.DateTimeToUnixTimestamp(DateTime.Now)

我已经拼接了这个实用方法的最优雅的方法:

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

我正在使用的简单代码:

public static long CurrentTimestamp()
{
return (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds * 1000);
}

这段代码给出了unix时间戳,从1970-01-01到现在的总毫秒数。

系统中DateTimeOffset有一个tounixtimemillisecseconds

你可以为DateTime写类似的方法:

public static long ToUnixTimeSeconds(this DateTime value)
{
return value.Ticks / 10000000L - 62135596800L;
}

10000000L—将刻度转换为秒

62135596800L -将01.01.01转换为01.01.1978

Utc和泄漏没有问题

下面是一个2-way扩展类,支持:

  • 时区定位
  • 输入/输出以秒或毫秒为单位。

在OP的例子中,用法是:

DateTime.Now.ToUnixtime();

DateTime.UtcNow.ToUnixtime();
即使有一个直接的答案,我相信使用通用的方法更好。 特别是因为它很可能是一个需要这样转换的项目,无论如何也需要这些扩展,所以最好对所有人使用相同的工具
    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;
}
}
}

我在挣扎了一段时间后使用了这个,它也迎合了时区偏移:

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

更新代码从Brad与一些事情: 你不需要数学。截断,转换为int或long会自动截断值。 在我的版本中,我使用long而不是int(我们将在2038年用完32位有符号整数)。 同时,增加了时间戳解析

public static class DateTimeHelper
{
/// <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 long ToUnixTimestamp(this DateTime value)
{
return (long)(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 long UnixTimestamp(this DateTime ignored)
{
return (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
}


/// <summary>
/// Returns a local DateTime based on provided unix timestamp
/// </summary>
/// <param name="timestamp">Unix/posix timestamp</param>
/// <returns>Local datetime</returns>
public static DateTime ParseUnixTimestamp(long timestamp)
{
return (new DateTime(1970, 1, 1)).AddSeconds(timestamp).ToLocalTime();
}


}

在。net 6.0中,使用long来避免2038:

# EYZ0:

long seconds = (long)DateTime.UtcNow.Subtract(DateTime.UnixEpoch).TotalSeconds;

# EYZ0:

(秒是一个很长的表示UnixTime)

DateTime timestamp = DateTime.UnixEpoch.AddSeconds(seconds);

小提琴:# EYZ0

我认为从任何DateTime对象获取unix时间戳会更好。我使用的是。net Core 3.1。

    DateTime foo = DateTime.Now;
long unixTime = ((DateTimeOffset)foo ).ToUnixTimeMilliseconds();

如果你有UTC TimeStamp作为Tick形式的long,有一个更快的快捷方式。

        /// <summary>
/// Convert Ticks to Unix Timestamp
/// </summary>
/// <param name="time"></param>
/// <returns></returns>
public static long ToUnixTimestamp(long time)
{
return (time - 621355968000000000) / TimeSpan.TicksPerMillisecond;
}