如何在C#中获取Unix时间戳


Answers:


597

通过使用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)


28
代表@wdhough发表评论。“这个答案的局限性是Int32,我认为是2,147,483,647。根据onlineconversion.com/unix_time.htm的说法,这相当于2038年1月19日星期二的时间,格林尼治标准时间,我猜是任何替代数字类型,double,long等也会最终受到限制,但是我认为值得一提。我在这里选择long,因为我想要一个整数。希望这会
有所

11
Unix时间戳传统上是32位整数,范围为'1970-01-01 00:00:01'UTC到'2038-01-19 03:14:07'UTC。
the_nuts 2014年

88
疯狂地将UNIX时间转换作为DateTime的一部分不在标准库中。
xingyu

7
或使用整数算法:DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).Ticks / TimeSpan.TicksPerSecond;
Anton Petrov

2
减去的日期时间不需要是UTC吗?
jjxtra

570

从.NET 4.6开始,有DateTimeOffset.ToUnixTimeSeconds()


这是一个实例方法,因此您应该在的实例上调用它DateTimeOffset。您也可以投射任何实例DateTime,尽管要注意时区

要获取当前时间戳:

DateTimeOffset.UtcNow.ToUnixTimeSeconds()

要从获取时间戳DateTime

DateTime foo = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)foo).ToUnixTimeSeconds();

126
好。它的时间
bizzehdee

35
@MattBorja值得庆幸的是,它返回一个Int64-到翻转时,我们将不再由于缺少地球而使用地球年。
鲍勃

24
对于任何其他想知道的人,您都可以通过DateTimeOffset.Now.ToUnixTimeSeconds()
kR105 '16

8
@ bizzehdee,Pun打算吗?
st0le

5
您可以使用以下日期获取UTC unixtimestamp:DateTimeOffset.UtcNow.ToUnixTimeSeconds()
Yair Levi

39

您也可以使用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;

1
第二种解决方案错误:无法将源类型“ double”转换为目标类型“ long”。
皮克斯2015年

@Pixar:第二个示例已修复
-JBert

5
new DateTime(1970, 1, 1)使用未指定的Kind属性创建时间。您真正想要new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)真正正确的事

从.NET 2.1的核心,您可以使用,而不是新的日期时间DateTime.UnixEpoch(1970,1,1)见docs.microsoft.com/en-us/dotnet/api/...
贾^ h

27

这是我用的:

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

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


(TotalSeconds具有double类型;铸造它长将导致精度的损失。)
法兰克

你的权利,但我们没有关于担心几千年:)
巴特洛梅耶木栅

21

截断.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);
}

2
扩展方法显然是整齐地做到这一点的方法。这是一个很好的,成熟的答案-我不明白为什么投票这么少。完全确定Robba是正确的-将输出强制转换为(int)会自动截断结果。(实际上忽略了双精度数的小数部分)。
Stephanie

4
(这个日期被忽略)是非常,非常的误导
拉斯Corneliussen

6

当您从当前时间中减去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.

5

这就是我用的。

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

也许使其成为DateTime的扩展方法
bizzehdee 2013年

3

我将最实用的方法拼接在一起:

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

2

此解决方案对我的情况有所帮助:

   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)


0

下面是一个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;
            }
        }
    }

注意不要混淆毫秒和秒的格式(最好的情况是例外,最糟糕的是不合理的转换)我已经将输入\输出默认为毫秒的格式。如果您希望使用秒格式作为默认格式,只需将isInMilliseconds = true(在两种方法中)都设置为false。
SingleFlake

0

我在挣扎了一段时间后使用了它,它也可以满足时区偏移:

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

-1

我正在使用的简单代码:

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.