Вычисление времени будущей эпохи в C#

Мне удалось найти пример кода для получения текущей метки времени в Linux Epoch (секунды с полуночи 1 января 1970 года), однако у меня возникли проблемы с поиском примера того, как рассчитать, какой будет эпоха в будущем, скажем, например, 10 минут, так как я могу рассчитать будущее время в эпоху Linux?


person UnkwnTech    schedule 25.05.2009    source источник
comment
Ваше заявление о том, как рассчитать, какой будет Эпоха в будущем, скажем, например, через 10 минут, сбивает с толку. Эпоха Unix всегда 01.01.1970 00:00:00, даже через 10 минут! Вы имеете в виду, как рассчитать количество секунд, так как Unix Epoch будет в будущем, скажем, например, через 10 минут?   -  person Chris Walsh    schedule 23.03.2016


Ответы (4)


Этот метод расширения должен выполнять эту работу:

private static double GetUnixEpoch(this DateTime dateTime)
{
    var unixTime = dateTime.ToUniversalTime() - 
        new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

    return unixTime.TotalSeconds;
}

И вы можете использовать его как таковой:

var unixTime1 = DateTime.Now.GetUnixEpoch(); // precisely now
var unixTime2 = (DateTime.Now + new TimeSpan(0, 10, 0)).GetUnixEpoch(); // 10 minutes in future

Обратите внимание, что вам нужно иметь дело со всеми датами и временем в UTC (универсальное время), поскольку именно так определяется начало эпохи Unix.

person Noldorin    schedule 25.05.2009

Есть интересный поворот, когда вы хотите узнать время эпохи Unix в .Net в системе Windows.

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

System.TimeSpan timeDifference = DateTime.UTCNow - 
            new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
long unixEpochTime = System.Convert.ToInt64(timeDifference.TotalSeconds);

Но,

Время эпохи Unix определяется как «... система для описания моментов времени, определяемая как количество секунд, прошедших с полуночи по всемирному координированному времени (UTC) 1 января 1970 года, без учета високосных секунд ." (1)

С 1972 года UTC включает «високосные секунды», и до сих пор у нас их было 25. (2)

В .Net DateTime не предусмотрены високосные секунды, а просто полагается на время ОС. Windows счастливо не знает о високосных секундах (3) (4), и поэтому будет просто иметь представление о времени, поскольку оно получает его от своего мастера NTP (я полагаю, что по умолчанию для машины, не подключенной к домену, используется time.windows.com ) , который, вероятно, обслуживает UTC, включая дополнительные секунды.

Это означает, что для того, чтобы быть педантично правильным в отношении реального количества секунд, прошедших с эпохи Unix, вам, вероятно, следует добавить високосные секунды к полученному выше результату для приложений, которые полагаются на это. Вам придется отслеживать количество секунд, добавляемых каждый раз, поскольку дополнительные секунды не объявляются заранее (2). Однако, поскольку определение Unix Epoch Time явно исключает високосные секунды, вы можете спокойно игнорировать это и просто пересчитывать секунды из текущего времени UTC.

Иногда високосные секунды вызывают программный хаос (5). Споры о том, следует ли сохранить или отменить эту практику, продолжаются (6) (7) (8).

Последняя дополнительная секунда на момент ответа произошла 1 июля 2012 года (9) и вызвала проблемы для различных сайтов и приложений (10)

(1) http://en.wikipedia.org/wiki/Unix_time

(2) http://en.wikipedia.org/wiki/Leap_second

(3) http://support.microsoft.com/kb/909614

(4) http://www.meinberg.de/english/info/leap-second.htm

(5) http://www.networkworld.com/news/2009/010609-leap-second-snafu-affects-oracle.html

(6) http://www.pcworld.idg.com.au/article/358024/time_waits_no_one_leap_seconds_may_cut/

(7) http://queue.acm.org/detail.cfm?id=1967009< /а>

(8) http://arxiv.org/abs/1106.3141

(9) http://hpiers.obspm.fr/iers/bul/bulc/bulletinc.dat

(10) http://arstechnica.com/business/2012/07/one-day-later-the-leap-second-v-the-internet-scorecard/

(В исходном ответе была ошибка, которую, к счастью, заметили комментаторы Эдвард Брей и Мормегил ниже)

person Peter Stuer    schedule 25.05.2009
comment
+1, потому что это интересно, однако, поскольку я работаю по шкале минут (в большинстве случаев больше похоже на часы), а операции не очень точны, я не думаю, что 24 секунды будут большой проблемой, но спасибо, что указали на это. - person UnkwnTech; 25.05.2009
comment
Я не думаю, что это правильно. Оба предположения в порядке (Unix и Windows не считают/не знают високосных секунд), но вы делаете неправильный вывод, ИМХО. Время Unix игнорирует дополнительные секунды, что означает, что оно считает 1973-01-01T00:00:00Z временем Unix 94694400, то есть (365 + 366 + 365) * 24 * 60 * 60, хотя за это время прошло две дополнительные секунды. И точно то же самое верно для Windows. Он знает от мастера NTP, что это 1973-01-01T00:00:00Z, но не знает о двух високосных секундах. Время Unix и Windows не является непрерывной шкалой времени, но они синхронизированы друг с другом. - person Mormegil; 22.02.2014
comment
Вот почему я сказал «педантично правильно». Мы сравниваем с официальным определением времени эпохи Unix, а не с практической реализацией в системе Unix, которая, как вы указываете, находится в той же лодке, что и Windows. - person Peter Stuer; 01.07.2015
comment
Практическая реализация Unix педантично правильна. Его основанная на эпохе математика не учитывает високосные секунды, что соответствует официальному определению. Чтобы уточнить, вот педантичный вопрос и ответ: что такое время эпохи Unix для 1973-01-01T00:00:00Z? 94694400. Сколько реальных секунд прошло с 1970-01-01T00:00:00Z до 1973-01-01T00:00:00Z? 94694402. - person Edward Brey; 02.07.2015
comment
Спасибо за разъяснения, Эдвард Брей и Мормегил. Я отредактирую ответ, чтобы отразить ваше понимание. - person Peter Stuer; 03.07.2015

Основное решение:

  1. Возьмите текущее время
  2. Добавить смещение в будущее (10 минут в вашем примере)
  3. Вычесть полночь 1 января 1970 г.
  4. Получите общее количество секунд между двумя

В С# (внезапно, непроверенный):

DateTime myEpoch = DateTime.Now.Add( new TimeSpan(...) );
return myEpoch.Subtract( new DateTime(1970, 1, 1, 0, 0, 0) ).TotalSeconds;
person Nick    schedule 25.05.2009

Какую функцию вы используете для получения текущего времени?

Конечно, для этого требуется параметр .NET DateTime...

Конечно, это просто вопрос передачи будущего DateTime в функцию.

или выполнить DateDiff в секундах между текущим временем и будущим временем и добавить это.

var dt = new DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime();

var now = System.DateTime.Now.ToUniversalTime();
var future = new DateTime(2010, 1, 1).ToUniversalTime();

Console.WriteLine((now - dt).TotalSeconds);
Console.WriteLine((future - dt).TotalSeconds);
person Eoin Campbell    schedule 25.05.2009
comment
Это должно быть сделано во временном интервале UTC, но в остальном это правильно. - person Noldorin; 25.05.2009