Answers:
通过使用DateTime.UtcNow
并减去1970-01-01的纪元时间,可以在C#中获得unix时间戳。
例如
Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
DateTime.UtcNow
可以用任何DateTime
您想要获取unix时间戳的对象替换。
还有一个字段,MSFT DateTime.UnixEpoch
对此文档的记录很差,但是可以替代new DateTime(1970, 1, 1)
DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).Ticks / TimeSpan.TicksPerSecond;
从.NET 4.6开始,有DateTimeOffset.ToUnixTimeSeconds()
。
这是一个实例方法,因此您应该在的实例上调用它DateTimeOffset
。您也可以投射任何实例DateTime
,尽管要注意时区。
要获取当前时间戳:
DateTimeOffset.UtcNow.ToUnixTimeSeconds()
要从获取时间戳DateTime
:
DateTime foo = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)foo).ToUnixTimeSeconds();
Int64
-到翻转时,我们将不再由于缺少地球而使用地球年。
DateTimeOffset.Now.ToUnixTimeSeconds()
您也可以使用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;
new DateTime(1970, 1, 1)
使用未指定的Kind
属性创建时间。您真正想要new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.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);
}
当您从当前时间中减去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 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 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 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;
}
}
在代码中使用助手:
double ret = DateHelper.DateTimeToUnixTimestamp(DateTime.Now)
系统中的DateTimeOffset有一个ToUnixTimeMilliseconds
您可以为DateTime编写类似的方法:
public static long ToUnixTimeSeconds(this DateTime value)
{
return value.Ticks / 10000000L - 62135596800L;
}
10000000L-将刻度转换为秒
62135596800L-将01.01.01转换为01.01.1978
Utc和泄漏没有问题
下面是一个2向扩展类,它支持:
在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;
}