ChatGPT解决这个技术问题 Extra ChatGPT

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

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


Z
Zombo

从 .NET 4.6 开始,有 DateTimeOffset.ToUnixTimeSeconds

这是一个实例方法,因此您应该在 DateTimeOffset 的实例上调用它。您也可以强制转换 DateTime 的任何实例,但 beware the timezone。获取当前时间戳:

DateTimeOffset.Now.ToUnixTimeSeconds()

要从 DateTime 获取时间戳:

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

直到 Unix Millenium Bug 点击:)
@MattBorja 谢天谢地,它返回一个 Int64 - 到滚动时,我们将不再使用地球年,因为缺少地球。
@Ony,DateTime.Now.ToFileTimeUtc() not 返回与 DateTimeOffset.Now.ToUnixTimeSeconds() 相同的值。根据 MSDN,“Windows 文件时间是一个 64 位值,表示自公元 1601 年 1 月 1 日 (CE) 协调世界时 (UTC) 午夜 12:00 以来经过的 100 纳秒间隔数。 ”
您可以通过以下方式获取 UTC unixtimestamp: DateTimeOffset.UtcNow.ToUnixTimeSeconds()
@Lost_In_Library:这是一个答案,但不是答案,因为不是每个人都使用 4.6(或能够使用,无论出于何种原因)
b
bizzehdee

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

例如

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

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

还有一个字段 DateTime.UnixEpoch,它是 MSFT 的 very poorly documented,但可以替代 new DateTime(1970, 1, 1)


代表@wdhough 发表评论。 “这个答案有限制 Int32 的限制,我相信它是 2,147,483,647。根据 onlineconversion.com/unix_time.htm,这相当于 2038 年 1 月 19 日星期二 03:14:07 GMT 我猜任何替代数字类型,双倍,长等最终也会有限制,但我认为值得一提。我在这里选择long,因为我想要一个整数。希望这有帮助”
unix 时间戳传统上是一个 32 位整数,其范围为 '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC。
疯狂的是 UNIX 时间转换不在标准库中作为 DateTime 的一部分。
或使用整数算法:DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).Ticks / TimeSpan.TicksPerSecond;
减去的日期时间不需要是UTC?
s
sikander

您也可以使用刻度。我正在为 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;

第二种解决方案的错误:无法将源类型“double”转换为目标类型“long”。
@Pixar:第二个样本是固定的
new DateTime(1970, 1, 1) 使用未指定的 Kind 属性创建时间。你真正想要的new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)是真正正确的
从 .NET Core 2.1 您可以使用 DateTime.UnixEpoch 而不是 new DateTime(1970, 1, 1) 请参阅 docs.microsoft.com/en-us/dotnet/api/…
B
Bartłomiej Mucha

这就是我使用的:

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

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


(TotalSeconds 具有 double 类型;将其转换为 long 会导致精度损失。)
你说得对,但我们不必担心几千年 :)
B
Brad

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

扩展方法显然是巧妙地做到这一点的方法。这是一个出色、成熟的答案——我不明白为什么它的票数这么少。很确定 Robba 是正确的 - 将输出转换为 (int) 会自动截断结果。 (字面上忽略双精度的小数部分)。
(忽略此 DateTime)非常非常具有误导性
我喜欢第一个扩展。第二个只是一个实用方法,不值得扩展。
S
Sylwester Kogowski

更新了 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();
    }

}

对于 ParseUnixTimestamp(..) 方法,它应该是 AddMilliseconds。不是AddSeconds
L
Leandro Bardelli

对于 .NET 6.0,使用 long 避免 2038

DateTime.UtcNow to UnixTime

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

UnixTime to DateTime.UtcNow

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

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


K
Kelly Anderson

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

M
Matthew James Lewis

这就是我使用的。

 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 的扩展方法
S
SingleFlake

下面是一个支持的 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。
A
Aslan Kystaubayev

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

   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)

X
XDS

我已经将这个实用方法的最优雅的方法拼接在一起:

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

T
Timur Lemeshko

系统中有 DateTimeOffset 的 ToUnixTimeMilliseconds

您可以为 DateTime 编写类似的方法:

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

10000000L - 将刻度转换为秒

62135596800L - 将 01.01.01 转换为 01.01.1978

Utc和泄漏没有问题


B
Bruce Cameron

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

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

G
Gaurav Sharma

我认为这会更好地从任何 DateTime 对象获取 unix 时间戳。我正在使用.net Core 3.1。

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

H
Hermetism

如果您将 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;
        }

E
Erkin Eren

我正在使用的简单代码:

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

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