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

biz*_*dee 359 c# timestamp unix-timestamp

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

biz*_*dee 554

通过使用DateTime.UtcNow并减去1970-01-01的epoc时间,您可以在C#中获得unix时间戳.

例如

Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
Run Code Online (Sandbox Code Playgroud)

DateTime.UtcNow可以替换为DateTime.UtcNow您想要获取unix时间戳的任何对象.

  • 很疯狂,UNIX时间转换不是作为DateTime的一部分在标准库中. (75认同)
  • 代表@wdhough发表评论."这个答案限制了Int32的限制,我认为,这是2,147,483,647.根据http://www.onlineconversion.com/unix_time.htm,这相当于周二,2038年1月19日03:14:07 GMT我猜任何替代数字类型,双重,长期等都将最终有限制,但我认为值得一提.我选择了很长时间,因为我想要一个整数.希望这有帮助" (23认同)
  • unix时间戳传统上是32位整数,并且具有"1970-01-01 00:00:01"UTC到"2038-01-19 03:14:07"UTC的范围. (10认同)
  • 或者使用整数arythmetic:`DateTime.UtcNow.Subtract(new DateTime(1970,1,1)).Ticks/TimeSpan.TicksPerSecond;` (7认同)
  • 减去的日期时间不需要是UTC? (2认同)
  • Unix 时间戳将在 2038 年遭遇 Y2K 式问题:https://en.wikipedia.org/wiki/Year_2038_problem (2认同)
  • 这个答案不是最好的(请参阅下面来自 @rstackhouse 的答案),而且很危险。就像已经发布的那样,这个实现将在 2038 年遭受整数溢出。我不建议使用它! (2认同)
  • 至于.NetCore 2.1,有一个新常量“DateTime.UnixEpoch”,因此您可以简单地使用以下代码: var timestamp = DateTime.UtcNow.Subtract(DateTime.UnixEpoch).TotalSeconds; (2认同)
  • 顺便说一句:“DateTime.UnixEpoch”被定义为 UTC。因此,请确保您的变量也是 UTC 格式(如果您不只是使用“DateTime.UtcNow”)。例如,`someNotUtcDateTimeVariable.ToUniversalTime().Subtract(DateTime.UnixEpoch).TotalSeconds()`。 (2认同)

Bob*_*Bob 487

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


这是一个实例方法,因此您需要在实例上调用它DateTimeOffset.您也可以投射任何实例DateTime,但要注意时区.

要获取当前时间戳:

DateTimeOffset.UtcNow.ToUnixTimeSeconds()
Run Code Online (Sandbox Code Playgroud)

要从以下位置获取时间戳DateTime:

DateTime foo = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)foo).ToUnixTimeSeconds();
Run Code Online (Sandbox Code Playgroud)

  • 好.是时候了 (102认同)
  • @MattBorja值得庆幸的是,它返回一个`Int64` - 到翻身时,由于缺少地球,我们不再使用地球年了. (31认同)
  • 对于其他想知道的人,可以使用`DateTimeOffset.Now.ToUnixTimeSeconds()获取当前时间戳. (20认同)
  • @bizzehdee,双关打算? (7认同)
  • 您可以使用以下命令获取UTC unixtimestamp:DateTimeOffset.UtcNow.ToUnixTimeSeconds() (4认同)
  • 直到 [`Unix Millenium Bug`](https://en.wikipedia.org/wiki/Year_2038_problem) 出现 :) (3认同)
  • @Ony,`DateTime.Now.ToFileTimeUtc()`不会**返回与`DateTimeOffset.Now.ToUnixTimeSeconds()`相同的内容.根据[MSDN](https://msdn.microsoft.com/en-us/library/system.datetime.tofiletimeutc(v = vs.110).aspx),"Windows文件时间是一个64位的值,表示自公元1601年1月1日午夜12点(世卫组织协调世界时(UTC))以来经过的100纳秒间隔的数量. (3认同)
  • @Lost_In_Library:这是答案,但不是答案,因为不是每个人都使用4.6(或者无论出于何种原因都可以使用) (2认同)

小智 37

你也可以使用Ticks.我正在为Windows Mobile编码,所以没有完整的方法.我无法使用TotalSeconds.

long epochTicks = new DateTime(1970, 1, 1).Ticks;
long unixTime = ((DateTime.UtcNow.Ticks - epochTicks) / TimeSpan.TicksPerSecond);
Run Code Online (Sandbox Code Playgroud)

要么

TimeSpan epochTicks = new TimeSpan(new DateTime(1970, 1, 1).Ticks);
TimeSpan unixTicks = new TimeSpan(DateTime.UtcNow.Ticks) - epochTicks;
double unixTime = unixTicks.TotalSeconds;
Run Code Online (Sandbox Code Playgroud)

  • `new DateTime(1970,1,1)`用未指定的`Kind`属性创建一个时间.你真正希望`new DateTime(1970,1,1,0,0,0,DateTimeKind.Utc)`真的是正确的 (4认同)
  • 从 .NET Core 2.1 开始,您可以使用 DateTime.UnixEpoch 而不是 new DateTime(1970, 1, 1) 请参阅 https://learn.microsoft.com/en-us/dotnet/api/system.datetime.unixepoch?view=netcore -3.1 (2认同)

Lea*_*dro 34

使用.NET 6.0,并使用long以避免该2038问题:

从 DateTime.UtcNow 到 UnixTime

long seconds = (long)DateTime.UtcNow.Subtract(DateTime.UnixEpoch).TotalSeconds;
Run Code Online (Sandbox Code Playgroud)

seconds将包含自 01/01/1970 (UnixTime) 以来的秒数

从 UnixTime 到 DateTime.UtcNow

DateTime timestamp = DateTime.UnixEpoch.AddSeconds(seconds);
Run Code Online (Sandbox Code Playgroud)

小提琴: https: //dotnetfiddle.net/xNhO6q

  • 为什么要对已经存在的 `ToUnixTimeSeconds`/`FromUnixTimeSeconds` 方法执行此操作? (2认同)

Bar*_*cha 25

这是我使用的:

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

请记住,此方法将返回协调通用时间(UTC)的时间.


Bra*_*rad 19

截断.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);
}
Run Code Online (Sandbox Code Playgroud)

  • 这不是int的演员阵容吗? (3认同)
  • (这个DateTime被忽略了)是非常非常误导的 (3认同)
  • 扩展方法显然是巧妙地做到这一点的方法。这是一个优秀、成熟的答案——我不明白为什么它的票数如此之少。非常确定 Robba 是正确的 - 将输出转换为 (int) 会自动截断结果。(字面上忽略双精度的小数部分)。 (2认同)

小智 8

从 Brad 更新了一些代码:您不需要 Math.truncate,转换为 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();
    }

}
Run Code Online (Sandbox Code Playgroud)


Kel*_*son 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.
Run Code Online (Sandbox Code Playgroud)


小智 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;
        }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

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

  • 时区本地化
  • 以秒或毫秒为单位的输入\输出。

在OP的例子中,用法是:

DateTime.Now.ToUnixtime();
Run Code Online (Sandbox Code Playgroud)

或者

DateTime.UtcNow.ToUnixtime();
Run Code Online (Sandbox Code Playgroud)

尽管存在直接答案,但我相信使用通用方法更好。特别是因为它很可能是一个需要这样转换的项目,无论如何也需要这些扩展,所以最好对所有人使用相同的工具。

    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;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)