Reputation: 20993
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#?
Upvotes: 667
Views: 883725
Reputation: 871
To get a Unix timestamp you can use the extension method below:
public static class DateTimeExtensions
{
public static long ToUnixTimeMilliseconds(this DateTime dateTime)
{
DateTimeOffset offset = (DateTimeOffset)dateTime.ToUniversalTime();
return offset.ToUnixTimeMilliseconds();
}
}
There are NUnit tests for this method:
[TestFixture]
public class DateTimeExtensionsTests
{
[TestCase("31.12.9999 23:59:59", 253402289999000)] // DateTime.MaxValue
[TestCase("01.01.0001 0:00:00", -62135596800000)] // DateTime.MinValue
[TestCase("31.12.2025 21:59:59", 1767207599000)]
public void ToUnixTimeMilliseconds_ReturnsCorrectValue(string dateTime, long millisecondsExpected)
{
// Act
long result = DateTime.Parse(dateTime).ToUnixTimeMilliseconds();
// Assert
result.Should().Be(millisecondsExpected);
}
}
Upvotes: 3
Reputation: 1850
With NET 8
You have this other option as well to get the timestamp with the new TimeProvider Class
var timestamp = TimeProvider.System.GetUtcNow().ToUnixTimeSeconds();
Upvotes: 9
Reputation: 11578
With .NET 6.0, and using long
to avoid the 2038
problem:
From DateTime.UtcNow to UnixTime
long seconds = (long)DateTime.UtcNow.Subtract(DateTime.UnixEpoch).TotalSeconds;
seconds
will contains the seconds since 01/01/1970 (UnixTime)
From UnixTime to DateTime.UtcNow
DateTime timestamp = DateTime.UnixEpoch.AddSeconds(seconds);
Fiddle: https://dotnetfiddle.net/xNhO6q
Upvotes: 41
Reputation: 16541
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.UtcNow.ToUnixTimeSeconds()
To get the timestamp from a DateTime
:
DateTime currentTime = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)currentTime).ToUnixTimeSeconds();
Upvotes: 998
Reputation:
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;
}
Upvotes: 0
Reputation: 31
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();
Upvotes: 2
Reputation: 20993
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)
Upvotes: 737
Reputation: 170
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();
}
}
Upvotes: 13
Reputation: 9
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;
}
Upvotes: 0
Reputation: 59
Below is a 2-way extension class that supports:
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;
}
}
}
Upvotes: 5
Reputation: 2879
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
Upvotes: 1
Reputation: 61
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.
Upvotes: -2
Reputation: 4188
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;
}
Upvotes: 2
Reputation: 567
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;
Upvotes: 55
Reputation: 131
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.
Upvotes: 6
Reputation: 15567
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);
}
Upvotes: 30
Reputation: 2782
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).
Upvotes: 34
Reputation: 49
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;
}
}
Upvotes: 4