Код APL для распаковки даты, преобразованной в количество дней по григорианским правилам

Меня интересует код APL для распаковки даты, упакованной в целое число дней, с использованием правил григорианского календаря.

Месяц назад я задал вопрос, чтобы код APL упаковал дату, чтобы я мог рассчитать количество дней между датами (Преобразование даты в количество дней). Это отлично сработало, и теперь я хотел бы хранить даты таким образом; однако это означает, что мне нужно будет их распаковать.

Я пытался это сделать, но логика превратилась в беспорядок, и я чувствую, что промахиваюсь... есть крайние случаи, которые терпят неудачу.

Предполагая, что функция распаковки - Y, что я хотел бы видеть:

    Y¨ 1 365 730 1095 736591
1 1 1  1 12 31  2 12 31  3 12 31  2017 9 19

В некоторых версиях может быть библиотечная/внутренняя поддержка, помогающая решить эту проблему, но я ищу решение с чистым кодом APL.


apl
person Paul Houle    schedule 20.09.2017    source источник


Ответы (2)


      ∇r←Y b;d;m
[1]   r←r++⌿36584 73108 109632∘.≤r←146097|b←365+b
[2]   r←366|r++⌿425 790 1155∘.≤r←1461|r
[3]   m←+/r∘.≥d←0 31 60 91 121 152 182 213 244 305 335
[4]   r←(⌊0.5+(b-r)÷365.2425),m,(r-d[m-~⎕IO])∘.+,1

Вот пример запуска с выводом (я использовал сегодняшний год, месяц, день):

Y 736592
2017 9 20
person Paul Smietan    schedule 20.09.2017
comment
Это отличные ответы, и они очень ценятся; Я выбрал тот, который работает в APL, который я использую (это не Dyalog). Но я изучу оба, чтобы попытаться выяснить, как именно они работают. - person Paul Houle; 21.09.2017

Вы не упомянули, каким переводчиком пользуетесь, поэтому вам может понадобиться перевести это на ваш диалект. Следующее взято из рабочего пространства Dyalog dfsn.

 date←{⎕ML←1                             ⍝ ⎕TS format from day number (Meeus).
     ⍺←¯53799                            ⍝ start of Gregorian calendar (GB).
     qr←{⊂⍤¯1⊢(0,⍺)⊤⍵}                   ⍝ quotient and remainder.
     Z F←1 qr ⍵+2415020                  ⍝
     a←⌊(Z-1867216.25)÷36524.25          ⍝
     A←Z+(Z≥⍺+2415021)×1+a-⌊a÷4          ⍝
     B←A+1524                            ⍝
     C←⌊(B-122.1)÷365.25                 ⍝
     D←⌊C×365.25                         ⍝
     E←⌊(B-D)÷30.6001                    ⍝
     dd df←1 qr(B-D)+F-⌊30.6001×E        ⍝
     mm←E-1+12×E≥14                      ⍝
     yyyy←C-6614+mm>2                    ⍝
     part←60 60 1000 qr⌊0.5+df×86400000  ⍝
     ↑[⎕IO-0.5]yyyy mm dd,part           ⍝
 }
      date¨1 365 730 1095 736591
┌─────────────┬───────────────┬───────────────┬───────────────┬─────────────────┐
│1 1 1 0 0 0 0│1 12 31 0 0 0 0│2 12 31 0 0 0 0│3 12 31 0 0 0 0│2017 9 19 0 0 0 0│
└─────────────┴───────────────┴───────────────┴───────────────┴─────────────────┘
person MBaas    schedule 20.09.2017