View Sidebar
Яндекс.Метрика
 
Округление времени DateTime и DateStamp в C# или выравнивание по свече или интервалу

Округление времени DateTime и DateStamp в C# или выравнивание по свече или интервалу

19.06.2016 09:291 comment

В переменной типа DateTime лежит дата с временем «19.06.2016 12:13:17», полученное например методом DateTime.Parse из текстовой строки. Хотим мы его выровнять по пятиминутному интервалу, т.е. получить «19.06.2016 12:10:00» или проделать аналогичную операцию с DateStamp. Как это сделать? Делюсь своим способом.

datestamp_datetime

Немного о сути типа DateTime

Значение DateTime измеряется в 100-наносекундных единицах, называемых тактами, и точная дата представляется числом тактов прошедших с 00 часов 00 минут 1 января 0001.

Например, число 628539264000000000 представляет собой 6 октября 1992 года 00:00:00.
Структура DateTime содержит единственное поле, которое и содержит количество прошедших тактов:

private UInt64 dateData;

Получить число тактов можно вызвав свойство DateTime.Ticks

Внимание алготрейдерам! «Ticks» в DateTime.Ticks - это не тиковые сделки, а другое.

Следует так же сказать, что начиная с .NET 2.0, 2 старших бита данного поля указывают тип DateTime: Unspecfied — не задан, Utc — координированное время, Local — местное время, а остальные 62 бита — количество тактов. Мы можем легко запросить эти два бита с помощью свойства Kind.

Перевод тиков DateTime в секунды

Мой способ предполагает работу с секундами, а не с тиками (100 наносекунд), поэтому переведем тики в секунды.

1 тик = 100 наносекунд = 0,1 микросекунд = 0,0001 миллисекунд = 0,0000001 секунд

Чтобы перевести тики в секунды, нужно тики разделить на 10 000 000.

Например:

double sec = date.Ticks / 10000000;

Округление или выравнивание по интервалу

Чтобы выровнять время по пятиминутному интервалу, нужно секунды разделить на 5 * 60, затем отбросить дробную часть, и умножить на 5 * 60.

var newSec = Math.Floor(sec / 5*60) * 5*60;

Почему 5 * 60?

5 – это 5 минут,
60 – это 60 секунд в одной минуте.

Для 10 минутного интервала будет 10 * 60, для 5 секундного – просто 5.

Теперь остается перевести «округленные» секунды в тики, умножив секунды на 10 000 000, и получить новое значение DateTime:

var newDate = new DateTime(newSec * 1000000);

Привожу пример кода для реализации данного алгоритма

static void Main(string[] args)
{

var date = (new DateTime(2016, 6, 19, 12, 13, 17, 67));

const double divider = 5 * 60 ; // Делитель

//переводим такты в секунды
//определемя количесво секунд прошедших с 00:00:00 1 января 0001 года нашей эры
double sec = date.Ticks / 10000000;

//выравниваем секунды по началу интервала
var newSec = Math.Floor(sec / divider) * divider;

//переводим секунды в такты
var newTicks = (long) newSec * 10000000;

//получаем новую выровненную дату
var newDate = new DateTime(newTicks);

Console.WriteLine(date);
Console.WriteLine(newDate);

Console.ReadKey();

}

Округление в большую сторону

Приведенный код округляет пятиминутки в меньшую сторону, т.е. из «19.06.2016 12:13:17» получится «19.06.2016 12:10:00».

Если надо получить «19.06.2016 12:15:00», то в завершении операций можно воспользоваться методом DateTime.AddMinutes (AddSeconds / AddHours / AddDays) или просто прибавить соответствующее количество секунд к расчету.

Работа с DateStamp

Тут все еще проще. Структура DateStamp хранит не такты, а количество секунд, прошедших с 1 января 1970 года.

Секунды можно получить свойством TimeSpan.TotalSeconds. Переводить такты в секунды уже не требуется. В остальном алгоритм будет очень похож.

Итог: округлять даты типа DateStamp и DateTime в C# или выравнивать их по интервалу совсем не сложно.

Пишите свои комментарии к статье!!!

1 Comment

  • Dmitry

    А подскажите как в шарпе обстоят дела с датами до н.э.? В чем хранить, чем парсиить? Не нашел об это информации в интернетах.

Добавить комментарий


css.php