1

I'm interested in APL code to unpack a date packed to an integer day count using Gregorian calendar rules.

I asked a question a month or so ago for APL code to pack a date so I could calculate the count of days between dates (Convert date to day count). That worked great and now I'd like to store dates in this manner; however, that means I will need to unpack them.

I have attempted it but the logic has become a mess and I feel I'm missing the mark... there are edge cases that fail.

Assuming the unpacking function is Y, what I'd like to see:

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

There may be library/intrinsic support in some versions to help solve this, but I'm looking for a pure APL code solution.

Paul Houle
  • 735
  • 9
  • 17

2 Answers2

2

You didn't mention which interpreter you are using, so you may need to translate this into your dialect. The following is taken from Dyalog's dfsn-workspace.

 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│
└─────────────┴───────────────┴───────────────┴───────────────┴─────────────────┘
MBaas
  • 7,248
  • 6
  • 44
  • 61
1
      ∇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

Here's a sample run with the output (I used today's year month day):

Y 736592
2017 9 20
  • These are great answers and much appreciated; I went with the one that works in the APL I use (which is not Dyalog). But I will study both to try and figure out exactly how they work. – Paul Houle Sep 21 '17 at 17:15