Unix timestamp function not returning expected timestamp, wrong timezone?

I'm using a custom function to take the current date and subtract days on it then return a timestamp in unix format. All the conversions are working fine except the expected output is not correct. I thought by setting

DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, 0, 0, 0)

to 0,0,0 that it would give me that day on midnight but it's giving me 5am (GMT).

My custom function:

public static int getUnixTimestamp(int days) {
    // Date to convert
    DateTime dateTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, 0, 0, 0).AddDays(-days);

    return (int)(TimeZoneInfo.ConvertTimeToUtc(dateTime) -
           new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds;
}

Any ideas or feedback on what could be causing this would be great, thanks!

Jon Skeet
people
quotationmark

You're calling the DateTime constructor without specifying a Kind, then you're calling ConvertTimeToUtc. That's going to assume that dateTime is actually local, and convert it to UTC. Given that you're already constructing it with UTC values, you don't need to convert it.

You have a separate problem which is calling DateTime.UtcNow several times - the date could change between those calls. It's better to use DateTime.UtcNow.Date to get the "today-in-UTC date".

Here's better code:

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

// TODO: Give this a clearer name
public static int GetUnixTimestamp(int days)
    => (int) ((DateTime.UtcNow.Date.AddDays(-days) - UnixEpoch).TotalSeconds);

Importantly, the Kind of DateTime.UtcNow.Date.AddDays(-days) will still be DateTimeKind.Utc.

people

See more on this question at Stackoverflow