.NET DateTime to time_t in seconds

12,881

Solution 1

try

 (dt - new DateTime (1970, 1, 1)).TotalSeconds

see

Solution 2

this seems a little tidier? You could make the epoch a static datetime if you will be using it a lot.

DateTime date = DateTime.Now;
DateTime epoch = new DateTime(1970, 1, 1);
TimeSpan span = (date - epoch);
double unixTime = span.TotalSeconds;

Solution 3

In C#:

Int64 Secs(DateTime dt)
{
    var delta = dt - new DateTime(1970, 1, 1);
    return Convert.ToInt64(delta.TotalSeconds);
}

Solution 4

I suggest the following code. It seems to better transport the meaning of the code

private static readonly DateTime REFERENCE = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

Int64 seconds(DateTime dt)
{
  return (dt - REFERENCE).TotalSeconds;
}

Solution 5

After reading @jheriko's comment on the accepted answer I wrote a quick console app to test whether time() from msvcrt.dll produced differing results to calculations using the managed date/time functions, which fortunately they do not, provided UTC is used. Generally speaking, wherever possible, dates and times should be calculated with and stored in UTC as a common base, and then converted back to the relevant timezone for display if necessary.

For reference, and to illustrate different ways of arriving at the number of seconds between 1st Jan 1970 and now, my test code was:

class Program
{
    [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
    public unsafe static extern int time(int* timer);

    static unsafe void Main(string[] args)
    {
        DateTime now = DateTime.Now;
        DateTime utc_now = DateTime.UtcNow;

        int time_t_msvcrt = time(null);
        int time_t_managed = (int)Math.Floor((now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds);
        int time_t_managed_2 = (int)Math.Floor((utc_now - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds);

        Console.WriteLine(time_t_msvcrt == time_t_managed);
        Console.WriteLine(time_t_msvcrt == time_t_managed_2);

        DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        DateTime time_t_now = epoch.Add(TimeSpan.FromSeconds(time_t_msvcrt));

        long now_secs = now.Ticks / 10000000L;
        long utc_now_secs = utc_now.Ticks / 10000000L;
        long time_t_now_secs = time_t_now.Ticks / 10000000L;

        Console.WriteLine(time_t_now_secs == now_secs);
        Console.WriteLine(time_t_now_secs == utc_now_secs);
        Console.ReadLine();
    }
}

This produces the output

True
True
True
True

as expected.

Share:
12,881
cnd
Author by

cnd

Updated on June 04, 2022

Comments

  • cnd
    cnd almost 2 years

    There is C code :

    time1=((double)dt1-25569.0)*86400.0;
    

    it's convert from TDateTime (VCL) to time_t format in seconds, so finally I need to get time_t format from .NET DateTime

    about time_t :

    It is almost universally expected to be an integral value representing the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC. This is due to historical reasons, since it corresponds to a unix timestamp, but is widely implemented in C libraries across all platforms.

    So to get seconds in .NET I'm doing this (F#):

    let seconds(dt : DateTime) =
        (dt.Ticks/10000000L)
    

    or on C# (to use more popular C# tag) :

    Int64 seonds(DateTime dt)
    { return (dt.Ticks/ ((Int64)10000000)); } 
    // hope it works, but please correct if I mistaken
    

    As far as I understand it's time from 12:00:00 Jan 1, 0001 UTC.

    So to use time_t format I need to add 1970 years in seconds.

    So final function must be (F#):

    let seconds(dt : DateTime) =
        (dt.Ticks/10000000L) + 31536000*1970
    

    C# :

    Int64 seonds(DateTime dt)
    { return (dt.Ticks/ ((Int64)10000000)) + 31536000*1970; } 
    

    I really afraid I made mistake here. Please examine this solution ! (check if this is done right)

    Thank you

  • jheriko
    jheriko over 9 years
    strangely this does not produce the same values as the C standard library time functions!
  • Yahia
    Yahia over 9 years
    @jheriko perhaps one of both takes DST into consideration... explicitely using UTC in the calculation might be worth a test...
  • jheriko
    jheriko over 9 years
    the descrepency is quite enormous where i have used it. in the end i used p/invoke with msvcrt to get the correct value. as a guess the problem is that time_t ignores leap seconds which UTC does not. (so even conceptually this code is wrong)
  • dlchambers
    dlchambers about 9 years
    I like static epoch idea
  • Dan Parsonson
    Dan Parsonson about 6 years
    @jheriko UTC is indeed the key, and fortunately you can get the same result using managed code as with p/invoke - see my answer