Как получить первый день года в KDB/Q?

Я ищу эффективную функцию для получения первого дня года в Q. Например, 2017.05.10 -> 2017.01.01 или 2016.08.19 -> 2016.01.01.

Следующий фрагмент работает, но неэффективно

{"D"$(string `year$x),".01.01"} .z.d

person Anton Dovzhenko    schedule 27.11.2017    source источник


Ответы (4)


Обычный трюк в такого рода расчетах заключается в использовании того факта, что в отличие от дат месяцы очень регулярны: в каждом году ровно 12 месяцев. Таким образом, чтобы найти первый день года, мы сначала приводим дату к типу месяца, затем округляем ее до числа, кратного 12, и возвращаем обратно к типу даты:

q)f:"d"$12 xbar"m"$
q)f .z.d
2017.01.01

или с датами ОП:

q)f 2017.05.10 2016.08.19
2017.01.01 2016.01.01
person Alexander Belopolsky    schedule 27.11.2017

для некоторого диапазона "d":

q)"d"$ceiling 365.245*-2000+`year$.z.Z
2017.01.01

(даты указаны в днях от 2000 г.)

person effbiae    schedule 27.11.2017
comment
Я думаю, что этот пример может работать для большинства заданных дат, но если я подам ему любую дату в 2290 году, он даст мне вторую дату года. - person Thomas Smyth; 27.11.2017
comment
Измените 365.245 на 365.2425, если вам небезразличны такие даты. (Или посмотрите мой ответ.) - person Alexander Belopolsky; 27.11.2017

Просто чтобы добавить еще один вариант в микс:

q){.Q.addmonths[x;1-`mm$x]+1-`dd$x} .z.d
2017.01.01
person Jonathon McMurray    schedule 27.11.2017
comment
Полную информацию см. на вики-странице .Q.addmonths. - person Thomas Smyth; 27.11.2017

Другое решение ради этого:

{"d"$1+(-).`month`mm$x}.z.d
2017.01.01
person Thomas Smyth    schedule 27.11.2017