dateperiod.ijs

Script: ~addons/finexec/datetime/dateperiod.ijs
Contributor: William Szuch
Updated: 2022 6 26
Depend: nil
Definitions loaded to locale: base
Status: done
Script source: dateperiod.ijs

Definition creating perodical dates and grouping dates into periods.
The definitions in the Standard Library script dates.ijs are available.
The J Calendar starts from 1800 1 1 (Wed): with day number = 0
    todate 0
1800 1 1

   1 todate 0
18000101
Monday is the first day of the week as per: ISO 8601.
Index: Monday = 0, Sunday = 6 (Days = 0 1 2 3 4 5 6)
   calendar 2020 1
The ISO 8601 calendar - a week starts on monday.
1 year = 365.2425 days
┌─────────────────────┐
│         Jan         │
│ Su Mo Tu We Th Fr Sa│
│     1  2  3  4  5  6│
│  7  8  9 10 11 12 13│
│ 14 15 16 17 18 19 20│
│ 21 22 23 24 25 26 27│
│ 28 29 30 31         │
│                     │
└─────────────────────┘
   1 calendar 2018 1
┌─────────────────────┐
│         Jan         │
│ Mo Tu We Th Fr Sa Su│
│  1  2  3  4  5  6  7│
│  8  9 10 11 12 13 14│
│ 15 16 17 18 19 20 21│
│ 22 23 24 25 26 27 28│
│ 29 30 31            │
│                     │
└─────────────────────┘
Date formats as a number: yyyy mm dd or yyyymmdd
    todayno  2017 1 1
79258
   1 todayno  20170101
79258
Use of definition ‘calendar’ is slow - could consider doing something faster.
The preferred formats for a date are:
yyyy mm dd eg. 1997 6 30 etc.
yyyymmdd eg 19970630 has advantages.
Use the definition ‘getdate’ for conversion of character dates to format: yyyy mm dd.
   getdate('2017/1/1')
2017 1 1
   getdate('1/1/2017')
2017 1 1
An Excel date is a number displayed with a date format.
It starts from 1900 1 1 with a well known leap year bug.
??? Check if this applied to Excel 2016
To convert from J day numbers (result of verb ‘todayno’ in dates.ijs),to
Excel day number subtract 36522 from the J day number.
Some useful date conversion verbs are also contained in the script.
Formated date: yyyymmdd:
(1) Dates in yyyymmdd format can be held as a vector and not a matrix.
    This can have some advantages.
    Can also help with dates in Excel
Define: 1 & todate
         1 & todayno
to work with date format yyyymmdd

Definitions

I index_period
M month_days
P periods_end_monthly, periods_hy, periods_monthly, periods_qrt, periods_yr
T todate1, todayno1
V valdate_yyyymmdd

index_period (dyad)

Form tacit
Depend: nil
Calculate the index of the period of the occurence of a date
in a sequence of dates defining the periods.
The period is closed on the right side (a < z <= b).
Dates to be converted to format: yyyymmdd

Syntax

(P)index_period(D)
P = dates setting out the periods
    dates must be in ascending order
    date format: yyyymmdd
D = dates to be grouped into the periods
    date format: yyyymmdd

Example

   (20190630 20200630)index_period(20190630 20200630 20210630)
0 1 2
   (20190630 20200630)index_period(20200531 20200630 20200701)
1 1 2
   (20150630 20160630 20170630)index_period(20170101)
2
   (20150630 20160630 20170630)index_period(20150531 20150630 20170101 20170630 20170701)
 0 0 2 2 3
   (20150630 20160630 20170630)index_period(20150630 20150701)
0 1

month_days (monad)

Form explicit
Depend: todate,todayno from dates.ijs (stdlib)
     valdate_yyyymmdd from daterperiod.ijs
Vector of dates in a month as YYYYMMDD

Syntax

 month_days(Y,M)
Y,M = Year,Month eg: 2009 12

Example

   ,.month_days 2020 2
20200201 20200202 20200203  ... 20200227 20200228 20200229

periods_end_monthly (dyad)

Form explicit
Depend: nil
Set end of monthly periods.

Syntax

(Y,M)periods_end_monthly(N)
Y,M = year and month to start ie: YYYY,MM
N = Number of monthly periods

Example

  (2019 12)periods_end_monthly(0)
20191231
  (2019 12)periods_end_monthly(4)
20191231 20200131 20200229 20200331 20200430
  (2018 12)periods_end_monthly(4)
20181231 20190131 20190228 20190331 20190430

periods_hy (dyad)

Form explicit
Depend: nil
Half yearly periods.
Note:
Leap year date 29/2 not valid as invalid dates result.

Syntax

(D,D1)periods_yr(N)
D = start date for first half year format YYYMMDD
D1 = end date for firt half year format YYYYMMDD
N = Number of half yearly periods

Example

  19800630 19801231 periods_hy 0
19800630
  19800630 19801231 periods_hy 1
19800630 19801231
   19801231 19800630 periods_hy 5
19800630 19801231 19810630 19811231 19820630 19821231
  valdate_yyyymmdd 20200229 20200731 periods_hy 10
1 1 0 1 0 1 0 1 1 1 0
   valdate_yyyymmdd 20200228 20200731 periods_hy 10
1 1 1 1 1 1 1 1 1 1 1

periods_monthly (dyad)

Form explicit
Depend: todate,todayno from dates.ijs (stdlib)
    valdate_yyyymmdd from daterperiod.ijs
Set monthly dates for a specific day of the month.
Treatment of 29, 30 and 31:
Treated as End of MONTH if date exceeds End of Month.

Syntax

 (D)periods_monthly(N)
D = start date - format yyymmdd
N = number of monthly periods

Example

  (20090132)periods_monthly(4)
*** Invalid Start Date ***
  (20200131)periods_monthly(0)
20200131
  ,.(20200131)periods_monthly(13)
20200131
20200229
20200331
20200430
20200531
20200630
20200731
20200831
20200930
20201031
20201130
20201231
20210131
20210228

periods_qrt (dyad)

Form explicit
Depend: nil
Quarterly period dates.
Note:
Leap year date 29/2 not valid as invalid dates result.

Syntax

(D,D1,D2,D3)periods_qrt(N)
D,D1,D2,D3 = first four quarterly dates format YYYYMMDD
N = number of quarterly periods

Example

  (19800331 19800630 19800930 19801231)periods_qrt(0)
19800630
 (19800331 19800630 19800930 19801231)periods_qrt(2)
19800630 19800930 19801231
  ,.(19800331 19800630 19800930 19801231)periods_qrt 8
19800630
19800930
19801231
19810630
19810930
19811231
19820630
19820930
19821231

periods_yr (dyad)

Form tacit
Depend: nil
Yearly period dates
Note:
February start date 29/2 and 28/2 will result in invalid dates .
Need to modify definition if end of February dates are required.
29/2/and 28/2

Syntax

(D)periods_yr(N)
D = start date format YYYMMDD
N = Number of yearly periods

Example

   19801231 periods_yr 0
19801231
   19801231 periods_yr 1
19801231 19811231
  20200630 periods_yr 4
20200630 20210630 20220630 20230630 20240630
  valdate_yyyymmdd 20200229 periods_yr 6
1 0 0 0 1 0 0

todate1 (monad)

Form: explicit-
Depend: todate from dates.ijs (stdlib)
Convert a day number to a date with format: yyyymmdd.
Similiar to todate.

Syntax

todate1(N)
N = day number

Example

   todate1 79000
20160418
   todate 79000
2016 4 18
   todate1 0
18000101

todayno1 (monad)

Form explicit
Depend: todayno from dates.ijs (stdlib)
Convert date to a day number.
Similiar to todayno.

valdate_yyyymmdd (verb)

Form explicit
Depend: valdate from dates.ijs (stdlib)
Validate that a date is in YYYYMMDD format
Returns 1 if date valid, 0 for invalid date.
Based on valdate in dates.ijs (stdlib)

Syntax

valdate_yyyymmdd(D)
D = dates in YYYYMMDD format

Example

  valdate_yyyymmdd 20200131 20200132
1 0
  valdate_yyyymmdd 20190228 20190229 20200229
1 0 1