ChatGPT解决这个技术问题 Extra ChatGPT

How to get the unix timestamp in C#

I have had look around stackoverflow, and even looked at some of the suggested questions and none seem to answer, how do you get a unix timestamp in C#?


Z
Zombo

As of .NET 4.6, there is DateTimeOffset.ToUnixTimeSeconds.

This is an instance method, so you are expected to call it on an instance of DateTimeOffset. You can also cast any instance of DateTime, though beware the timezone. To get the current timestamp:

DateTimeOffset.Now.ToUnixTimeSeconds()

To get the timestamp from a DateTime:

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

Until the Unix Millenium Bug hits :)
@MattBorja Thankfully, it returns an Int64 - by the time that rolls over, we'd not be using Earth years anymore for lack of an Earth.
@Ony, DateTime.Now.ToFileTimeUtc() does not return the same as DateTimeOffset.Now.ToUnixTimeSeconds(). According to MSDN, “A Windows file time is a 64-bit value that represents the number of 100-nanosecond intervals that have elapsed since 12:00 midnight, January 1, 1601 A.D. (C.E.) Coordinated Universal Time (UTC).”
You can get the UTC unixtimestamp with: DateTimeOffset.UtcNow.ToUnixTimeSeconds()
@Lost_In_Library: it is AN answer, but not THE answer, as not everybody uses 4.6 (or is able to use, for whatever reason)
b
bizzehdee

You get a unix timestamp in C# by using DateTime.UtcNow and subtracting the epoch time of 1970-01-01.

e.g.

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

DateTime.UtcNow can be replaced with any DateTime object that you would like to get the unix timestamp for.

There is also a field, DateTime.UnixEpoch, which is very poorly documented by MSFT, but may be a substitute for new DateTime(1970, 1, 1)


Commenting on behalf of @wdhough. "This answer has limitation with the limit of Int32 which is, I believe, 2,147,483,647. According to onlineconversion.com/unix_time.htm this equates to a time of Tue, 19 Jan 2038 03:14:07 GMT I guess any alternative number type, double, long, etc will ultimately have a limit too, but I thought it worth mentioning. I choose long here as I wanted a whole number. Hope this helps"
The unix timestamp is traditionally a 32 bit integer, and has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.
Crazy that UNIX time conversion is not in the standard library as part of DateTime.
Or using integer arythmetic: DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).Ticks / TimeSpan.TicksPerSecond;
The subtracted datetime does not need to be UTC?
s
sikander

You can also use Ticks. I'm coding for Windows Mobile so don't have the full set of methods. TotalSeconds is not available to me.

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

or

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

Error for the second solution: Cannot convert source type 'double' to target type 'long'.
@Pixar: The second sample is fixed
new DateTime(1970, 1, 1) creates a time with unspecified Kind property. What you really want to new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) to be truly correct
From .NET Core 2.1 You can use DateTime.UnixEpoch instead of new DateTime(1970, 1, 1) see docs.microsoft.com/en-us/dotnet/api/…
B
Bartłomiej Mucha

This is what I use:

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

Keep in mind that this method will return the time as Coordinated Univeral Time (UTC).


(TotalSeconds has double type; casting it to long will cause loss of precision.)
You right, but we don't have to worry about that for several thousand years :)
B
Brad

Truncating .TotalSeconds is important since it's defined as the value of the current System.TimeSpan structure expressed in whole fractional seconds.

And how about an extension for DateTime? The second one is probably more confusing that it's worth until property extensions exist.

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

Extension method is clearly the way to do this neatly. This is an excellent, mature answer - and i don't understand why it has so few votes. Pretty sure that Robba is correct - casting the output as (int) automatically truncates the result. (Literally ignoring the decimal part of the double).
(this DateTime ignored) is very, very misleading
I like the first extension. The second is just a utility method, doesn't deserve to be an extension.
S
Sylwester Kogowski

Updated code from Brad with few things: You don't need Math.truncate, conversion to int or long automatically truncates the value. In my version I am using long instead of int (We will run out of 32 bit signed integers in 2038 year). Also, added timestamp parsing.

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

}

It should be AddMilliseconds for the ParseUnixTimestamp(..) method. Not AddSeconds
L
Leandro Bardelli

With .NET 6.0, using long to avoid 2038:

DateTime.UtcNow to UnixTime:

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

UnixTime to DateTime.UtcNow:

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

Fiddle: https://dotnetfiddle.net/xNhO6q


K
Kelly Anderson

When you subtract 1970 from the current time, be aware that the timespan will most often have a non zero milliseconds field. If for some reason you are interested in the milliseconds, keep this in mind.

Here's what I did to get around this issue.

 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

This is what I use.

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

perhaps make it an extension method of DateTime
S
SingleFlake

Below is a 2-way extension class that supports:

Timezone localization

Input\output in seconds or milliseconds.

In OP's case, usage is:

DateTime.Now.ToUnixtime();

or

DateTime.UtcNow.ToUnixtime();

Even though a direct answer exists, I believe using a generic approach is better. Especially because it's most likely a project that needs a conversion like this, will also need these extensions anyway, so it's better to use the same tool for all.

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

Be careful not to confuse the milliseconds and seconds formats (best case is an exception, worst is illogical conversion) I've defaulted the input\output to the milliseconds format. If you prefer to use the seconds format as default, just switch the isInMilliseconds=true (in both methods) to false.
A
Aslan Kystaubayev

This solution helped in my situation:

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

using helper in code:

double ret = DateHelper.DateTimeToUnixTimestamp(DateTime.Now)

X
XDS

I've spliced together the most elegant approaches to this utility method:

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

There is a ToUnixTimeMilliseconds for DateTimeOffset in System

You can write similar method for DateTime:

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

10000000L - converting ticks to seconds

62135596800L - converting 01.01.01 to 01.01.1978

There is no problem with Utc and leaks


B
Bruce Cameron

I used this after struggling for a while, it caters to the timezone offset as well:

    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

I think this would work better to get the unix timestamp from any DateTime object. I am using .net Core 3.1.

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

H
Hermetism

If you have a UTC TimeStamp as a long in Tick form there is an even faster shortcut for this.

        /// <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

The simple code that I am using:

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

This code is giving unix timestamp, total milliseconds from 1970-01-01 to now.