Расчет времени будущей эпохи в C # - PullRequest
15 голосов
/ 25 мая 2009

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

Ответы [ 4 ]

31 голосов
/ 25 мая 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 блаженно не знает о Leap Seconds (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/

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

30 голосов
/ 25 мая 2009

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

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.

1 голос
/ 25 мая 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);
0 голосов
/ 25 мая 2009

Базовое решение:

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

В c # (вне головы, не проверено):

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