Script:
~addons/finexec/datetime/date_tools.ijs
Contributor: William Szuch
Updated: 2022 6-26
Depend: nil
Definitions loaded to locale: base
Status: review
Script source:
date_tools.ijs
This script has definitions that are useful for
handling dates.
checking dates
age
system
date conversions
The J Calendar starts from 1800 1 1 (Wed): day number = 0 eg todate 0
gives 1800 1 1
also, 1 todate 0 gives 18000101
Use is made of the J utility: dates.ijs that is loaded
into ‘z’ as part of the Standard Library.
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 2009
1 calendar 2009 NB. < ISO 8601 >
In the ISO 8601 calendar a week starts on
monday.
1 YEAR = 365.2425 days
Date format as a number: or
Use of ‘calendar’ is slow - could consider doing
something faster.
The preferred formats for a date are: yyyy mm dd
eg. 1997 6 30 etc.
Alternative format: yyyymmdd eg 19970630 has advantages.
Use ‘getdate’ for conversion of character dates
to format: yyyy mm dd.
An Excel date is a number displayed with a date
format.
It starts from 1900 1 1 with a well known leap year bug.
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.
Format 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
Consider: 1&todate
1&todayno
to work with date format yyyymmdd
Gregorian Calendar - Started by Pope Gregory
Vlll in 1582.
Leap Year:
Every year that is exactly divisible by four is a leap year,
except for years that are exactly divisible by 100;
The centurial years that are exactly divisible by 400 are still leap
years.
For example, the years 1800,1900,2100,2200 are not leap years;
The year 2000 ia a leap year.
Definitions
|
A
|
age_lastbd, age_nearestbd, age_nextbd, age_yrs, age_yydd
|
|
C
|
calendar_yr
|
|
D
|
date_convert1, date_convert2, date_convert3, date_convert4, date_convert5, date_convert6, date_sys, date_test, date_time_sys, dates_test, day_of_week, day_of_weekno, DAYS, days_diff, days_in_month, days_in_year, DAYSA, DAYSB, dur_yrs
|
|
E
|
end_of_month
|
|
L
|
last_bd, leapyr
|
|
M
|
MONTHS, MONTHSA
|
|
N
|
next_bd, next_month
|
|
S
|
set_monthly_dates, set_weekly_dates
|
|
T
|
time_sys, todate1, todayno1, tsdiff_a, tsdiff_b, tsdiff_c
|
|
V
|
valdate_yyyymmdd
|
|
W
|
week, wks, wks53, wks53y, wy
|
|
Y
|
yearb
|
|
DAYS
|
n
|
Days as dd
|
|
DAYSA
|
n
|
Days full name
|
|
DAYSB
|
n
|
Days as ddd
|
|
MONTHS
|
n
|
Months mmm
|
|
MONTHSA
|
n
|
Months full name
|
age_lastbd (verb)
Form explicit
Depend: last_bd
Age last birthday
If birthay on D then gives age at D
Syntax
(D)age_lastbd(B) y
D = date of calculation: yyyy mm dd
B = date of birth: yyyy mm dd
Example
1997 6 30 age_lastbd 1948 11 10
48
age_nearestbd (verb)
Form explicit
Depend: tsdiff
Age nearest birthday.
If birthay on D then gives age at D
Watch for B > D
Based on the tsdiff using 365 days.
Syntax
(D)age_nearestbd(B)
D = calculation date: yyyy mm dd
B = birth date: yyyy mm dd
Example
2002 10 9 age_nearestbd 1948 11 10
54
age_nextbd (verb)
Form explicit
Depend: next_bd
Age next birthday
If birthay on D then gives age at D
Syntax
(D)age_nextbd(B)
D = date of calculation: yyyy mm dd
B = date of birth: yyyy mm dd
### Example
1997 6 30 age_nextbd 1948 11 10
49
age_yrs (verb)
Form explicit
Depend: tsdiff
Same as ‘tsdiff’ in dates.ijs
Produces age of y at x in years(fractions).
Years converted to fraction by using ‘tsdiff’
Based on months and days.
Watch for cases when B > D
Syntax
(D)age_yrs(B)
D = date of calculation: yyyy mm dd
B = date of birth: yyyy mm dd
Example
1997 6 30 age_yrs 1954 5 12
43.1326
2002 11 9 age_yrs 1948 11 10
53.9961
age_yydd (verb)
Form explicit
Depend: todayno
Produces age of B at D in yy,dd (years & days).
Syntax
(D)age_yydd(B)
D = date of calculation: yyyy mm dd
B = date of birth: yyyy mm dd
calendar_yr (verb)
Form explicit
Depend: nil
Formatted calendar for year [months]
Returns calendar for year, as a list of months
Based on ‘calendar’ in dates.ijs (stdlib) but shows YEAR
In the ISO 8601 calendar a week starts on Monday.
Syntax
([x]) calendar_yr(Y)
[x] = optional left argument and is the start day of week
0=sunday (default)
1=monday, 2 Tuesday ...
y = is one or more numbers: year, months
If no months are given, it defaults to all months in year.
Example
calendar_yr 2009
calendar_yr 2020 1 2 12
date_convert1 (verb)
Form explicit
Depend: chopstring
Verb to convert text date of the form ‘yy-mm-dd’, yyyy mm dd etc.
with ‘-’ as the separetar between parts of date to ‘yyyy mm dd’
format.
Syntax
([C])date_convert1(D)
[C] = Century eg. 1900 2000 etc: default = 1900
D = date as text: yy-mm-dd
Example
1900 date_convert1 '97-6-30'
1997 6 30
2000 date_convert1 '97-6-30'
2097 6 20
2000 date_convert1'1-6-30'
2001 6 30
date_convert2 (verb)
Form explicit
Depend: chopstring
Verb to convert text date of the form ‘yyZmmZdd’ to yyyy mm dd.
with ‘Z’ as the separetar between parts of date.
Syntax
(Z;C) FORM: x date_convert2 y
Z;C = delimitor;century eg. (1900;Z)
D = date as text: 'yyZmmZdd' Z = some delimiter
Example
('s';1900) date_convert2 '97s6s30'
1997 6 30
('/';1900) date_convert2 '97/6/30'
1997 6 30
('s';2000)date_convert2 '97s6s30'
2097 6 30
date_convert3 (verb)
Form explicit
Depend: nil
Convert from yyyy mm dd to yyyymmdd.
Syntax
date_convert3(D)
D = date: yyyy mm dd
Example
date_convert3 1994 7 1
19940701
date_convert4 (verb)
Convert from yyyymmdd to yyyy mm dd.
date_convert5 (verb)
Form explicit
Depend: charsub, getdate
Convert date text ‘dd.mm.yyyy’ to yyyy mm dd.
Syntax
date_convert5(D)
D = text text in format: 'dd.mm.yyyy'
Example
date_convert5 '1.1.2000'
2000 1 1
date_convert6 (verb)
Form explicit
Depend: charsub
Convert date text ‘dd.mm.yy’ -> yyyy mm dd.
Note the treatment of the year in yy format.
Syntax
([C]) date_convert6(D)
[C] = Century eg. 1900 2000 etc: default = 1900
D = date in text format 'dd.mm.yy'
Example
1900 date_convert6 '1.1.89'
1989 1 1
2000 date_convert6 '1.1.00'
2000 1 1
date_sys (verb)
Form explicit
Depend: nil
Gives current date on system - YYYY MM DD.
synyax: ~~~ date_sys ’’ ~~~
Example
date_sys ''
date_test (verb)
Form explicit
Depend: valdate
Test if a boxed date is valid.
Test for dates in yyyy mm dd format
Syntax
date_test(D) y
D = boxed date
Example
date_test < 2000 1 1
1
date_test < 20200811
0
date_test < '2000/1/1'
0
date_time_sys (verb)
Form explicit
Depend: nil
Gives current date and time on the system - yyyy MM DD HH MM SS.
Syntax
date_time_sys ''
Example
date_time_sys ''
dates_test (verb)
Form explicit
Depend: date_test
Test if a boxed list of dates is valid and
the result is an index of invalid dates.
Test for dates in yyyy mm dd format.
Syntax
dates_test(D) y
D = boxed dates
Example
dates_test < 2000 1 1
dates_test <20200811
0
dates_test <20200811
dates_test < '2000/1/1'
0
dates_test (10 # < 2000 1 1),(5 # < '2000/1/1'),(<'234'),(< 2005 1 1),(<20060101)
10 11 12 13 14 15 17
(dates_test { [) (10 # < 2000 1 1),(5 # < '2000/1/1'),(<'234'),(< 2005 1 1),(<20060101)
┌────────┬────────┬────────┬────────┬────────┬───┬────────┐
│2000/1/1│2000/1/1│2000/1/1│2000/1/1│2000/1/1│234│20060101│
└────────┴────────┴────────┴────────┴────────┴───┴────────┘
day_of_week (verb)
Form explicit
Depend: todayno from dates.ijs (stdlib)
Day of the week.
Syntax
day_of_week(D)
D = date: yyyy mm dd
Example
day_of_week(1800 1 1)
Wed
day_of_week(2020 8 7)
Fri
day_of_weekno (verb)
Form explicit
Depend: todayno from dates.ijs (stdlib)
Number of day in the week, start with Monday = 0
Form explicit
Depend: todayno from dates.ijs (stdlib)
Sunday = 6 (Days = 0 1 2 3 4 5 6)
Calendar starts from 1800 1 1
symtax: ~~~ day_of_weekno(D) D = date: yyyy mm dd ~~~
Example
day_of_weekno 1996 6 30
6
day_of_weekno 2020 8 10
0
days_diff (verb)
Form explicit
Depend: todayno
By: R.E. Ross
Number of days between to dates.
Syntax
(S)days_diff(E)
S = start date: yyyy mm dd
E = end date: yyyy mm dd
Example
1948 11 10 days_diff 2003 7 8
19963
>1948 11 10 & days_diff each 2003 7 8;2004 1 1;2005 2 1
19963 20140 20537
days_in_month (verb)
Form explicit
Depend: todayno from dates.ijs (stdlib)
Days in month.
Syntax
days_in_month(YYYY,MM)
YYYY,MM = year and month
Example
days_in_month 1996 6
30
days_in_month 2020 2
29
days_in_year (verb)
Form explicit
Depend: days_diff
Shows number of days in a year.
Syntax
days_in_year(Y)
y = year
Example
days_in_year 1800
365
>days_in_year each 1800 2000 2004 2005 2008 2009 2020
365 366 366 365 366 365 366
dur_yrs (verb)
Form explicit
Depend: tsdiff
Duration years & fractions from x to y
Based on months and days.
end_of_month (verb)
Form explicit
Depend: days_in_month
Sets future end of month dates.
Inculdes first date.
Syntax
(YYYY,MM)end_of_month(N)
YYYY,MM = start month
N = number of monthly intervals
Example
(1990 11)end_of_month 4
1990 11 30
1991 12 31
1991 1 31
1991 2 28
(2020 1)end_of_month 4
2020 1 31
2020 2 29
2020 3 31
2020 4 30
last_bd (verb)
Form explicit
Depend: todayno, todate
Gives date of last bithday at x for date of birth y
leapyr (verb)
Form explicit
Depend: nil
Result: 1 if year is a leap year, 0 otherwise.
Syntax
leapyr(Y) y
Y = YEAR
Example
>leapyr each 1800 2000 2004
0 1 1
next_bd (verb)
Form explicit
Depend: todayno, todate
Gives date of next bithday at x for date of birth y
Syntax
(D)next_bd(B)
D = date of calculation: yyyy mm dd
B = date of birth: yyyy mm dd
next_month (verb)
Form explicit
Depend: days_in_month
Gives future or past month with same day or nearest if at end of
month.
Syntax
(D)next_month(N)
D = start date : yyyy mm dd
N = Number of months forward or back
Example
1996 6 30 next_month 2
1996 8 30
2020 3 30 next_month _1
2020 2 29
set_monthly_dates (verb)
Form explicit
Depend: next_month
Set dates at monthly intervals on fixed day, From 1800 1 1.
Includes first date.
Watch out for end of months ie. 28,29,30 & 31
Syntax
(D)set_monthly_dates(N)
D = start date: yyyy mm dd
N = number of months forward
Example
2020 8 11 set_monthly_dates 3
2020 8 11
2020 9 11
2020 10 11
2020 1 31 set_monthly_dates 12
2020 1 31
2020 2 29
2020 3 31
2020 4 30
2020 5 31
2020 6 30
2020 7 31
2020 8 31
2020 9 30
2020 10 31
2020 11 30
2020 12 31
set_weekly_dates (verb)
Form explicit
Depend: todayno from dates.ijs (stdlib)
Set dates at weekly intervals.
Includes the start date.
Syntax
(D)set_weekly_dates(N)
D = start date: yyyy mm dd
N = number of weekly intervals
Example
1998 9 22 set_weekly_dates 3
1998 9 22
1998 9 29
1998 10 6
1998 10 13
time_sys (verb)
Form explicit
Depend: nil
Gives current time on system - HH MM SS(with fractions).
Syntax
time_sys ''
Example
time_sys ''
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.
tsdiff_a (verb)
Form explicit
Depend: nil
The differences between pairs of dates is expressed as: - yyyy mm
dd.
Based on tsdiff
start and end dates are vectors or matrices in form yyyy mm dd
end dates should be later than begin dates
Method is to subtract dates on a calendar basis to determine
Result is integer number of years, months and days (yy,mm,dd).
Note the result when D<F
Syntax
(T)tsdiff_a(F)
T = to date: yyyy mmm dd
F = from date: yyyy mm dd
Example
1998 10 1 tsdiff_a 1988 5 23
10 4 9
1998 10 1 tsdiff_a 1998 10 3
_1 11 29
tsdiff_b (verb)
Form explicit
Depend: tsrep
The differences between pairs of dates is expressed
in 1000’s of a second.
Based on tsrep
Syntax
(S)tsdiff_a(F)
S = start date and time: yyyy mm dd hh mm ss:eg: 2001 1 1 0 0 0
F = finish date and time: yyyy mm dd hh mm ss eg. 2001 1 1 0 1 0
Example
2001 1 1 0 0 0 tsdiff_b 2001 1 1 0 1 0
60000
2001 1 1 0 0 0 tsdiff_b 2002 1 1 0 0 0
31536000000
tsdiff_c (verb)
Form explicit
Depend: tsrep
The differences between pairs of dates is expressed as: - yyyy mm dd hh
mm ss.
Based on tsrep
Syntax
(S)tsdiff_a(F)
S = start date and time: yyyy mm dd hh mm ss eg: 2001 1 1 0 0 0>
F = finish date and time: yyyy mm dd hh mm ss eg. 2002 1 1 0 1 0
Example
2001 1 1 0 0 0 tsdiff_c 2002 1 1 0 1 0
1 0 0 0 1 0
valdate_yyyymmdd (verb)
Form explicit
Validate that a date is in YYYYMMDD format
Returns 1 if date valid.
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
week (verb)
Form explicit
Depend: weekday,wks,todauno
By: R.E. Ross
Gives the year and week of a date.
A week belongs to a year if and only if 4 days of the
week belong to that year.
Week is based on a Mathematical procedure in
http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
In the ISO calendar a week starts on Monday
Syntax
([x])week(D)
[F]= first day of week:
0 - first day of week is Sunday (default)
D = date: yyyy mm dd
Example
1 week 2004 1 1
2004 1
week 2004 1 1
2003 53
wks (verb)
Form explicit
Depend: weekday
Gives number of weeks in year.
In the ISO calendar a week starts on Monday
Syntax
([F])wks(Y)
[F] = first day of week:
0 - first day of week is Sunday (default)
Y = year
Example
wks 2000 +i.10
52 52 52 53 52 52 52 52 53 52
4 wks 2000 +i.10
52 52 52 52 52 52 52 52 52 52
wks53 (verb)
Form explicit
Depend: nil
A function for determining whether an ISO year has 52 or 53 weeks.
1 if year has 53 ISO weeks, 0 otherwise
Syntax
wks53(Y)
Y = YEAR
Example
>wks53 each 2000 2004
0 1
wks53y (verb)
Form explicit
Depend: learyr,yearb
A definition for determining whether an ISO year has 52 or 53
weeks.
This is faster then wks53.
wy (verb)
Form explicit
Depend: wks53
By: Eugene McDonnell
A function giving the number of weeks in an ISO year.
Syntax
wy(Y)
Y = YEAR
Example
wy 2000
52
>wy each 2000 + i. 10
52 52 52 52 53 52 52 52 52 52
yearb (verb)
Form explicit
Depend: nil
Gives the index of the weekday that the year begins.
0 = Sunday, 1 = Monday, 2 = Tuesday etc