1

I would like a function (using Gregorian calendar rules) given 3⍴⎕TS would return 1+ the number of days since 1 1 1. EG if the function were named X:

      X¨ (1 1 1) (1 12 31) (2 12 31) (3 12 31) (4 12 31)
1 365 730 1095 1461

I need this so I can subtract two dates to find the number of days between them.

Paul Houle
  • 735
  • 9
  • 17
  • @Adam Thanks! I edited my question to specify Gregorian calendar. I am dealing with newly created business records -- certainly nothing approaching 100 years old. The initial day value makes no difference as long as it can't be zero (I reserve that as an "empty" indicator). I'll only be subtracting these values to determine the count of days between them. – Paul Houle Jul 31 '17 at 20:39

2 Answers2

2

Please see the following example - function X assumes index origin 1 as follows:

r←X b  
r←(0 31 59 90 120 151 181 212 243 273 304 334)[b[2]]    
r←r+b[3]+(365×b[1]-1)+-/⌊(b[1]-3>b[2])÷4 100 400
  • Perfect that works and is what I was hoping for... an answer with a snippet of code I could cut-and-paste. – Paul Houle Jul 31 '17 at 20:46
  • Though not part of the question, I notice this function also provides the day-of-week. 7 modulo the value returned yields (0=Sun, 1=Mon, ..., 6=Sat). – Paul Houle Aug 01 '17 at 03:15
1

In Dyalog APL, you can make use of the interpreter's built-in DateToIDN and IDNToDate methods to convert to and from an International Day Number, and thus allow interger math.

You can conveniently package them as follows:

ToIDN ← {⊢ 2 ⎕NQ # 'DateToIDN' , ⍵}
ToDate ← {3 ⍴ 2 ⎕NQ # 'IDNToDate' , ⍵}

Try it online!

The is to counter ⎕NQ being shy, and the 3⍴ is to chop off the weekday number which is appended as a 4th element.

You can additionally define an operator which allows you to operate on dates seamlessly:

Datewise ← {ToDate (ToIDN ⍺) ⍺⍺ ⍵}

Try it online!

Finally, if you are not using Dyalog APL, or if you are interested in the actual formulas to determine the IDN, have a look at the days and date functions from the dfns workspace.

Adám
  • 6,573
  • 20
  • 37