Как конвертировать datetime в timestamp с помощью С#/.NET(игнорируя текущий часовой пояс)

Как преобразовать datetime в timestamp с помощью С#.NET(игнорируя текущий часовой пояс)?

Я использую приведенный ниже код:

private long ConvertToTimestamp(DateTime value)
{
    long epoch = (value.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
    return epoch;
}

Но он возвращает значение временной метки в соответствии с текущим часовым поясом, и мне нужен результат без использования текущего часового пояса.

Ответ 1

В данный момент вы вызываете ToUniversalTime() - просто избавитесь от этого:

private long ConvertToTimestamp(DateTime value)
{
    long epoch = (value.Ticks - 621355968000000000) / 10000000;
    return epoch;
}

В качестве альтернативы и более читаемо ИМО:

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

private static long ConvertToTimestamp(DateTime value)
{
    TimeSpan elapsedTime = value - Epoch;
    return (long) elapsedTime.TotalSeconds;
}

РЕДАКТ. Как отмечено в комментариях, Kind DateTime, который вы проходите, не учитывается при выполнении вычитания. Вы должны действительно передать значение с Kind из Utc, чтобы это работало. К сожалению, DateTime немного нарушен в этом отношении - см. мой пост в блоге (рассказ о DateTime) для более подробной информации.

Возможно, вы захотите использовать мой API Noda Time, который делает все более ясным, IMO.

Ответ 2

Я не совсем уверен, что вы хотите. Вы хотите TimeStamp? Тогда вы можете сделать что-то простое:

TimeStamp ts = TimeStamp.FromTicks(value.ToUniversalTime().Ticks);

Поскольку вы назвали переменную эпоху, хотите ли вы эквивалент времени Unix вашей даты?

DateTime unixStart = DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc);
long epoch = (long)Math.Floor((value.ToUniversalTime() - unixStart).TotalSeconds);

Ответ 3

JonSkeet имеет хороший ответ, но в качестве альтернативы, если вы хотите сохранить результат более переносимым, вы можете преобразовать дату в формат ISO 8601 который затем может быть прочитан в большинстве других фреймворков, но это может не соответствовать вашим требованиям.

value.ToUniversalTime().ToString("O");

Ответ 4

Найти временную метку из DateTime:

private long ConvertToTimestamp(DateTime value)
{
    TimeZoneInfo NYTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
    DateTime NyTime = TimeZoneInfo.ConvertTime(value, NYTimeZone);
    TimeZone localZone = TimeZone.CurrentTimeZone;
    System.Globalization.DaylightTime dst = localZone.GetDaylightChanges(NyTime.Year);
    NyTime = NyTime.AddHours(-1);
    DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime();
    TimeSpan span = (NyTime - epoch);
    return (long)Convert.ToDouble(span.TotalSeconds);
}