How can I convert a DateTime to the number of seconds since 1970?
Asked Answered
A

8

166

I'm trying to convert a C# DateTime variable to Unix time, ie, the number of seconds since Jan 1st, 1970. It looks like a DateTime is actually implemented as the number of 'ticks' since Jan 1st, 0001.

My current thought is to subtract Jan 1st, 1970 from my DateTime like this:

TimeSpan span= DateTime.Now.Subtract(new DateTime(1970,1,1,0,0,0));
return span.TotalSeconds;

Is there a better way?

Alboran answered 28/7, 2010 at 16:7 Comment(1)
Possible duplicate of How do you convert epoch time in C#?Kimura
H
245

That's basically it. These are the methods I use to convert to and from Unix epoch time:

public static DateTime ConvertFromUnixTimestamp(double timestamp)
{
    DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
    return origin.AddSeconds(timestamp);
}

public static double ConvertToUnixTimestamp(DateTime date)
{
    DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
    TimeSpan diff = date.ToUniversalTime() - origin;
    return Math.Floor(diff.TotalSeconds);
}

Update: As of .Net Core 2.1 and .Net Standard 2.1 a DateTime equal to the Unix Epoch can be obtained from the static DateTime.UnixEpoch.

Hue answered 28/7, 2010 at 16:9 Comment(5)
It should be worth noting that if you want to convert to millseconds for either more accurate timestamps or Javascript Date() object compatibility, you need to use long instead of int for the timestamp type.Sanburn
Did not work for me. This answer did the trick: #250260Lido
@Jonny - ToUniversalTime() converts to UTC, so it does account for UTC.Hue
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); Interesting that no one suggested this. Very often you will have milliseconds representing Utc time. And if you dont specify this explicitly and somewhere later in code youll have ToUniversalTime() than you end up with bad Utc time, because by default DateTime is NOT Utc.Diaphony
nice post, I needed to remove the Math.floor because I needed a little more detail.Anlace
B
95

If the rest of your system is OK with DateTimeOffset instead of DateTime, there's a really convenient feature:

long unixSeconds = DateTimeOffset.Now.ToUnixTimeSeconds();
Barolet answered 25/7, 2016 at 0:46 Comment(2)
This is a cleaner way, but it's only available in framework 4.6 msdn.microsoft.com/en-us/library/…Marj
Nice. And of course for going from unix to a DateTimeOffset, you can use var time = DateTimeOffset.FromUnixTimeSeconds(5000); MS DocStaff
I
23

The only thing I see is that it's supposed to be since Midnight Jan 1, 1970 UTC

TimeSpan span= DateTime.Now.Subtract(new DateTime(1970,1,1,0,0,0, DateTimeKind.Utc));
return span.TotalSeconds;
Integral answered 28/7, 2010 at 16:12 Comment(1)
Should it be DateTime.UtcNow?Kwok
R
18

You probably want to use DateTime.UtcNow to avoid timezone issue

TimeSpan span= DateTime.UtcNow.Subtract(new DateTime(1970,1,1,0,0,0)); 
Rockingham answered 28/7, 2010 at 16:13 Comment(1)
The only way to avoid timezone issues is to 1) remain blissfully ignorant, and support only one timezone, or 2) handle timezones (at least) everywhere you interface with another system or end-user. In particular, using UTC everywhere internally is only part of the battle. In the first scenario, adding UTC datetimes actually makes the problem worse, until you are ready to do all of (2), because you go from supporting any one timezone to supporting only UTC.Kimura
C
4

I use year 2000 instead of Epoch Time in my calculus. Working with smaller numbers is easy to store and transport and is JSON friendly.

Year 2000 was at second 946684800 of epoch time.

Year 2000 was at second 63082281600 from 1-st of Jan 0001.

DateTime.UtcNow Ticks starts from 1-st of Jan 0001

Seconds from year 2000:

DateTime.UtcNow.Ticks/10000000-63082281600

Seconds from Unix Time:

DateTime.UtcNow.Ticks/10000000-946684800

For example year 2020 is:

var year2020 = (new DateTime()).AddYears(2019).Ticks; // Because DateTime starts already at year 1

637134336000000000 Ticks since 1-st of Jan 0001

63713433600 Seconds since 1-st of Jan 0001

1577836800 Seconds since Epoch Time

631152000 Seconds since year 2000

References:

Epoch Time converter: https://www.epochconverter.com

Year 1 converter: https://www.epochconverter.com/seconds-days-since-y0

Ciliata answered 24/2, 2020 at 0:18 Comment(1)
This doesn't answer OPs question, which was specifically about the numbers of seconds since the Unix epoch.Gallia
A
2

UTC:

long timeSince1970 = DateTimeOffset.Now.ToUnixTimeSeconds();

Local time:

long timeSince1970 = DateTime.Now.Ticks / 10000000 - 62135596800;
Acroter answered 28/6, 2022 at 8:3 Comment(0)
L
1

That approach will be good if the date-time in question is in UTC, or represents local time in an area that has never observed daylight saving time. The DateTime difference routines do not take into account Daylight Saving Time, and consequently will regard midnight June 1 as being a multiple of 24 hours after midnight January 1. I'm unaware of anything in Windows that reports historical daylight-saving rules for the current locale, so I don't think there's any good way to correctly handle any time prior to the most recent daylight-saving rule change.

Lax answered 28/7, 2010 at 17:21 Comment(0)
C
0

You can create a startTime and endTime of DateTime, then do endTime.Subtract(startTime). Then output your span.Seconds.

I think that should work.

Chromatology answered 28/7, 2010 at 16:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.