tind
Packagetind
package provides an extensive set of functions for
calendrical computations. These include: extraction of time index
components, determination of properties of time periods (leap years,
number of subperiods within a period), computation of dates of moveable
observances, and calendar arithmetic. For applications in business and
finance, computations involving business days (using different rolling
conventions) and computation of accrual factors are provided.
Before proceeding, let us load the package.
library("tind")
Current date and time can be checked using functions
today()
and now()
.
today()
## date [tind]
## [1] 2025-10-18
now()
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2025-10-18 21:06:49 CEST
By default, the system time zone (as returned by
Sys.timezone()
) is used. However, we can check the current
time in other time zones. Let us do it for Tokyo, Warsaw, London, and
New York.
now("Asia/Tokyo")
## date-time, time zone: Asia/Tokyo [tind]
## [1] 2025-10-19 04:06:49 JST
today("Asia/Tokyo")
## date [tind]
## [1] 2025-10-19
now("Europe/Warsaw")
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2025-10-18 21:06:49 CEST
today("Europe/Warsaw")
## date [tind]
## [1] 2025-10-18
now("Europe/London")
## date-time, time zone: Europe/London [tind]
## [1] 2025-10-18 20:06:49 BST
today("Europe/London")
## date [tind]
## [1] 2025-10-18
now("America/New_York")
## date-time, time zone: America/New_York [tind]
## [1] 2025-10-18 15:06:49 EDT
today("America/New_York")
## date [tind]
## [1] 2025-10-18
tind
package provides a collection of intuitively-named
functions for extracting time index components, see examples below.
<- now()) (nw
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2025-10-18 21:06:50 CEST
year(nw)
## [1] 2025
quarter(nw)
## [1] 4
month(nw)
## [1] 10
month(nw, labels = TRUE)
## [1] Oct
## 12 Levels: Jan < Feb < Mar < Apr < May < Jun < Jul < Aug < Sep < ... < Dec
month(nw, labels = TRUE, abbreviate = FALSE)
## [1] October
## 12 Levels: January < February < March < April < May < June < ... < December
week(nw)
## [1] 42
day(nw)
## [1] 18
day_of_week(nw)
## [1] 6
day_of_week(nw, labels = TRUE)
## [1] Sat
## Levels: Mon < Tue < Wed < Thu < Fri < Sat < Sun
day_of_week(nw, labels = TRUE, abbreviate = FALSE)
## [1] Saturday
## 7 Levels: Monday < Tuesday < Wednesday < Thursday < Friday < ... < Sunday
day_of_year(nw)
## [1] 291
hour(nw)
## [1] 21
am(nw)
## [1] FALSE
pm(nw)
## [1] TRUE
minute(nw)
## [1] 6
second(nw)
## [1] 50
The inherent irregularity of our calendar is well known. Years are divided into leap and non-leap ones, months have different numbers of days (and so do quarters and years), years have varying number of weeks (52 or 53 in ISO 8601). In many time zones Daylight Saving Time is used, which then leads to some days having more or less than 24 hours. The functions shown below allow to easily check properties of time indices at hand.
<- tind(y = 2023:2024, m = c(10, 2), d = 29, H = 1, tz = "Europe/Warsaw")) (tm
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2023-10-29 01:00 CEST 2024-02-29 01:00 CET
is.leap_year(tm)
## [1] FALSE TRUE
days_in_year(tm)
## [1] 365 366
weeks_in_year(tm)
## [1] 52 52
days_in_quarter(tm)
## [1] 92 91
days_in_month(tm)
## [1] 31 29
hours_in_day(tm)
## [1] 25 24
is.dst(tm)
## [1] TRUE FALSE
Time indices can be shifted using +
and -
operators and -
can be used to compute time differences
(returning objects of auxiliary tdiff
class).
<- today()) (x
## date [tind]
## [1] 2025-10-18
+ 0:3 x
## date [tind]
## [1] 2025-10-18 2025-10-19 2025-10-20 2025-10-21
- 0:3 x
## date [tind]
## [1] 2025-10-18 2025-10-17 2025-10-16 2025-10-15
- 3:0 x
## date [tind]
## [1] 2025-10-15 2025-10-16 2025-10-17 2025-10-18
- as.date("2000-01-01") x
## time difference, unit: day [tdiff]
## [1] 9422d (~25.8y)
Operators %+y%
, %-y%
, %+m%
,
%-m%
, %+d%
, %-d%
, etc. can be
used to shift time indices by multiples of a given time unit. An
alternative is to use time differences constructed by
as.tdiff
method or convenience functions
years
, qrtrs
, mnths
,
weeks
, days
, hours
,
mins
, and secs
. (The naming was chosen in
order to avoid conflicts with base functions months
and
quarters
).
<- today()) (x
## date [tind]
## [1] 2025-10-18
%+y% -1:1 x
## date [tind]
## [1] 2024-10-18 2025-10-18 2026-10-18
+ years(-1:1) x
## date [tind]
## [1] 2024-10-18 2025-10-18 2026-10-18
%+m% -1:1 x
## date [tind]
## [1] 2025-09-18 2025-10-18 2025-11-18
+ mnths(-1:1) x
## date [tind]
## [1] 2025-09-18 2025-10-18 2025-11-18
%+d% -1:1 # same as x + -1:1 x
## date [tind]
## [1] 2025-10-17 2025-10-18 2025-10-19
<- now()) (x
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2025-10-18 21:06:50 CEST
%-h% 3:0 x
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2025-10-18 18:06:50 CEST 2025-10-18 19:06:50 CEST
## [3] 2025-10-18 20:06:50 CEST 2025-10-18 21:06:50 CEST
- hours(3:0) x
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2025-10-18 18:06:50 CEST 2025-10-18 19:06:50 CEST
## [3] 2025-10-18 20:06:50 CEST 2025-10-18 21:06:50 CEST
%-min% 3:0 x
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2025-10-18 21:03:50 CEST 2025-10-18 21:04:50 CEST
## [3] 2025-10-18 21:05:50 CEST 2025-10-18 21:06:50 CEST
- mins(3:0) x
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2025-10-18 21:03:50 CEST 2025-10-18 21:04:50 CEST
## [3] 2025-10-18 21:05:50 CEST 2025-10-18 21:06:50 CEST
%-s% 3:0 # same as x - 3:0 x
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2025-10-18 21:06:47 CEST 2025-10-18 21:06:48 CEST
## [3] 2025-10-18 21:06:49 CEST 2025-10-18 21:06:50 CEST
- secs(3:0) # same as x - 3:0 x
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2025-10-18 21:06:47 CEST 2025-10-18 21:06:48 CEST
## [3] 2025-10-18 21:06:49 CEST 2025-10-18 21:06:50 CEST
seq
method for tind
allows to easily
construct series of time indices. The following code creates a sequence
of months with a step of two months from November 2023 till April
2025:
seq(as.month("2023-11"), as.month("2025-04"), by = 2)
## month [tind]
## [1] 2023-11 2024-01 2024-03 2024-05 2024-07 2024-09 2024-11 2025-01 2025-03
Consider the following problem: for a given month we need to construct a sequence of dates in that month. Note that the last day in a month is the day before the first day in the following month. The following piece of code does the job:
<- as.month("2025-03")) (m
## month [tind]
## [1] 2025-03
seq(as.date(m), as.date(m + 1) - 1)
## date [tind]
## [1] 2025-03-01 2025-03-02 2025-03-03 2025-03-04 2025-03-05 2025-03-06
## [7] 2025-03-07 2025-03-08 2025-03-09 2025-03-10 2025-03-11 2025-03-12
## [13] 2025-03-13 2025-03-14 2025-03-15 2025-03-16 2025-03-17 2025-03-18
## [19] 2025-03-19 2025-03-20 2025-03-21 2025-03-22 2025-03-23 2025-03-24
## [25] 2025-03-25 2025-03-26 2025-03-27 2025-03-28 2025-03-29 2025-03-30
## [31] 2025-03-31
seq
method for tind
also accepts different
types of time indices and automatically converts them. The two lines
below create sequences from the beginning of current quarter till today
and from today till the end of the quarter:
<- today()) (td
## date [tind]
## [1] 2025-10-18
seq(as.quarter(td), td)
## date [tind]
## [1] 2025-10-01 2025-10-02 2025-10-03 2025-10-04 2025-10-05 2025-10-06
## [7] 2025-10-07 2025-10-08 2025-10-09 2025-10-10 2025-10-11 2025-10-12
## [13] 2025-10-13 2025-10-14 2025-10-15 2025-10-16 2025-10-17 2025-10-18
seq(td, as.quarter(td))
## date [tind]
## [1] 2025-10-18 2025-10-19 2025-10-20 2025-10-21 2025-10-22 2025-10-23
## [7] 2025-10-24 2025-10-25 2025-10-26 2025-10-27 2025-10-28 2025-10-29
## [13] 2025-10-30 2025-10-31 2025-11-01 2025-11-02 2025-11-03 2025-11-04
## [19] 2025-11-05 2025-11-06 2025-11-07 2025-11-08 2025-11-09 2025-11-10
## [25] 2025-11-11 2025-11-12 2025-11-13 2025-11-14 2025-11-15 2025-11-16
## [31] 2025-11-17 2025-11-18 2025-11-19 2025-11-20 2025-11-21 2025-11-22
## [37] 2025-11-23 2025-11-24 2025-11-25 2025-11-26 2025-11-27 2025-11-28
## [43] 2025-11-29 2025-11-30 2025-12-01 2025-12-02 2025-12-03 2025-12-04
## [49] 2025-12-05 2025-12-06 2025-12-07 2025-12-08 2025-12-09 2025-12-10
## [55] 2025-12-11 2025-12-12 2025-12-13 2025-12-14 2025-12-15 2025-12-16
## [61] 2025-12-17 2025-12-18 2025-12-19 2025-12-20 2025-12-21 2025-12-22
## [67] 2025-12-23 2025-12-24 2025-12-25 2025-12-26 2025-12-27 2025-12-28
## [73] 2025-12-29 2025-12-30 2025-12-31
floor_t
and ceiling_t
round time indices
down or up given time unit or multiple of a unit. round_t
returns the result of one of these two functions, whichever is
closer.
<- tind(y = 2025, m = 3, d = 30)) (x
## date [tind]
## [1] 2025-03-30
floor_t(x, "w")
## date [tind]
## [1] 2025-03-24
ceiling_t(x, "w")
## date [tind]
## [1] 2025-03-31
round_t(x, "w")
## date [tind]
## [1] 2025-03-31
floor_t(x, "m")
## date [tind]
## [1] 2025-03-01
ceiling_t(x, "m")
## date [tind]
## [1] 2025-04-01
round_t(x, "m")
## date [tind]
## [1] 2025-04-01
floor_t(x, "2m")
## date [tind]
## [1] 2025-03-01
ceiling_t(x, "2m")
## date [tind]
## [1] 2025-05-01
round_t(x, "2m")
## date [tind]
## [1] 2025-03-01
floor_t(x, "q")
## date [tind]
## [1] 2025-01-01
ceiling_t(x, "q")
## date [tind]
## [1] 2025-04-01
round_t(x, "q")
## date [tind]
## [1] 2025-04-01
floor_t(x, "y")
## date [tind]
## [1] 2025-01-01
ceiling_t(x, "y")
## date [tind]
## [1] 2026-01-01
round_t(x, "y")
## date [tind]
## [1] 2025-01-01
trunc_t
truncates time indices changing type when
possible.
<- date_time(x, H = "13:13:13.13")) (x
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2025-03-30 13:13:13.13 CEST
trunc_t(x, "s")
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2025-03-30 13:13:13 CEST
trunc_t(x, "min")
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2025-03-30 13:13 CEST
trunc_t(x, "h")
## date-time, time zone: Europe/Warsaw [tind]
## [1] 2025-03-30 13:00 CEST
trunc_t(x, "d")
## date [tind]
## [1] 2025-03-30
trunc_t(x, "w")
## week [tind]
## [1] 2025-W13
trunc_t(x, "m")
## month [tind]
## [1] 2025-03
trunc_t(x, "q")
## quarter [tind]
## [1] 2025Q1
trunc_t(x, "y")
## year [tind]
## [1] 2025
It is common to define dates of movable holidays or observances as
the first, second, third, fourth, or last occurrence of a particular day
of week in a given month. In order to determine dates of such
observances two functions can be used: nth_dw_in_month()
and last_dw_in_month()
. Days of week are numbered 1–7 with
1 denoting Monday and 7 Sunday (as in ISO 8601).
Thanksgiving in the US is observed on the fourth Thursday of November, which in 2019 was on:
nth_dw_in_month(4, 4, 201911)
## date [tind]
## [1] 2019-11-28
Black Friday is the day after Thanksgiving:
nth_dw_in_month(4, 4, 201911) + 1
## date [tind]
## [1] 2019-11-29
Daylight Saving Time in the EU begins (at least for now) on the last Sunday in March and ends on the last Sunday of October. In 2019 the two dates were:
last_dw_in_month(7, 201903)
## date [tind]
## [1] 2019-03-31
last_dw_in_month(7, 201910)
## date [tind]
## [1] 2019-10-27
During change to DST, the day is one hour shorter and during change back one hour longer:
hours_in_day(last_dw_in_month(7, 201903), "Europe/Warsaw")
## [1] 23
hours_in_day(last_dw_in_month(7, 201910), "Europe/Warsaw")
## [1] 25
In the Christian world, Easter is a very important feast and other
many observances are set relative to it. Easter date in a given year can
be determined using easter()
function.
easter(2020:2025)
## date [tind]
## [1] 2020-04-12 2021-04-04 2022-04-17 2023-04-09 2024-03-31 2025-04-20
The functions shown above can be used to create custom calendar functions, which can later be used for pretty printing calendars or calculations involving business days.
It is expected that a calendar function:
If a calendar function returns a list and second or third logical
vector is named, the names are used by function calendar()
when pretty printing calendar.
Two examples of calendar functions are provided below and can be used as templates for creating calendar functions for any country, area, or specific applications like trading days or shopping days.
Public holidays in the US have either fixed dates or are on nth or last day of week in a month.
The calendar function below returns a two-element list (business days and holidays). A programming trick (marked in the code) is used to name holidays.
<- function(dd)
calendar_US
{<- as.tind(dd)
dd <- year(dd)
y <- month(dd)
m <- day(dd)
d <- (m == 1) & (d == 1)
newyear <- (y >= 2000) & (m == 1) & (dd == nth_dw_in_month(3, 1, dd))
martinlking <- (m == 2) & (dd == nth_dw_in_month(3, 1, dd))
presidentsday <- (m == 5) & (dd == last_dw_in_month(1, dd))
memorialday <- (y >= 2021) & (m == 6) & (d == 19)
juneteenth <- (m == 7) & (d == 4)
independence <- (m == 9) & (dd == nth_dw_in_month(1, 1, dd))
labor <- (m == 10) & (dd == nth_dw_in_month(2, 1, dd))
columbus <- (m == 11) & (d == 11)
veterans <- (m == 11) & (dd == nth_dw_in_month(4, 4, dd))
thanksgiving <- (m == 12) & (d == 25)
christmas <- newyear | martinlking | presidentsday |
holiday | juneteenth | independence |
memorialday | columbus | veterans | thanksgiving |
labor
christmas# holiday names - a programming trick
# names of holnms should be the same as names of logical vectors above
names(holiday) <- rep("", length(holiday))
<- c(newyear = "New Year's Day",
holnms martinlking = "Birthday of Martin Luther King, Jr.",
presidentsday = "Washington's Birthday",
memorialday = "Memorial Day",
juneteenth = "Juneteenth National Independence Day",
independence = "Independence Day",
labor = "Labor Day",
columbus = "Columbus Day",
veterans = "Veterans Day",
thanksgiving = "Thanksgiving Day",
christmas = "Christmas Day")
lapply(names(holnms), function(nm) names(holiday)[get(nm)] <<- holnms[nm])
# business days
<- !holiday & (day_of_week(dd) %in% 1:5)
business return (list(business = business, holiday = holiday))
}
Now we can use our function to print the calendar. Note that to
obtain coloured output you have to have package crayon
installed.
calendar(2020, calendar_US)
## 2020
## Jan Feb Mar
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 01 1 2 3 4 5 05 1 2 09 1
## 02 6 7 8 9 10 11 12 06 3 4 5 6 7 8 9 10 2 3 4 5 6 7 8
## 03 13 14 15 16 17 18 19 07 10 11 12 13 14 15 16 11 9 10 11 12 13 14 15
## 04 20 21 22 23 24 25 26 08 17 18 19 20 21 22 23 12 16 17 18 19 20 21 22
## 05 27 28 29 30 31 09 24 25 26 27 28 29 13 23 24 25 26 27 28 29
## 14 30 31
## Apr May Jun
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 14 1 2 3 4 5 18 1 2 3 23 1 2 3 4 5 6 7
## 15 6 7 8 9 10 11 12 19 4 5 6 7 8 9 10 24 8 9 10 11 12 13 14
## 16 13 14 15 16 17 18 19 20 11 12 13 14 15 16 17 25 15 16 17 18 19 20 21
## 17 20 21 22 23 24 25 26 21 18 19 20 21 22 23 24 26 22 23 24 25 26 27 28
## 18 27 28 29 30 22 25 26 27 28 29 30 31 27 29 30
## Jul Aug Sep
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 27 1 2 3 4 5 31 1 2 36 1 2 3 4 5 6
## 28 6 7 8 9 10 11 12 32 3 4 5 6 7 8 9 37 7 8 9 10 11 12 13
## 29 13 14 15 16 17 18 19 33 10 11 12 13 14 15 16 38 14 15 16 17 18 19 20
## 30 20 21 22 23 24 25 26 34 17 18 19 20 21 22 23 39 21 22 23 24 25 26 27
## 31 27 28 29 30 31 35 24 25 26 27 28 29 30 40 28 29 30
## 36 31
## Oct Nov Dec
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 40 1 2 3 4 44 1 49 1 2 3 4 5 6
## 41 5 6 7 8 9 10 11 45 2 3 4 5 6 7 8 50 7 8 9 10 11 12 13
## 42 12 13 14 15 16 17 18 46 9 10 11 12 13 14 15 51 14 15 16 17 18 19 20
## 43 19 20 21 22 23 24 25 47 16 17 18 19 20 21 22 52 21 22 23 24 25 26 27
## 44 26 27 28 29 30 31 48 23 24 25 26 27 28 29 53 28 29 30 31
## 49 30
calendar(as.year(today()), calendar_US)
## 2025
## Jan Feb Mar
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 01 1 2 3 4 5 05 1 2 09 1 2
## 02 6 7 8 9 10 11 12 06 3 4 5 6 7 8 9 10 3 4 5 6 7 8 9
## 03 13 14 15 16 17 18 19 07 10 11 12 13 14 15 16 11 10 11 12 13 14 15 16
## 04 20 21 22 23 24 25 26 08 17 18 19 20 21 22 23 12 17 18 19 20 21 22 23
## 05 27 28 29 30 31 09 24 25 26 27 28 13 24 25 26 27 28 29 30
## 14 31
## Apr May Jun
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 14 1 2 3 4 5 6 18 1 2 3 4 22 1
## 15 7 8 9 10 11 12 13 19 5 6 7 8 9 10 11 23 2 3 4 5 6 7 8
## 16 14 15 16 17 18 19 20 20 12 13 14 15 16 17 18 24 9 10 11 12 13 14 15
## 17 21 22 23 24 25 26 27 21 19 20 21 22 23 24 25 25 16 17 18 19 20 21 22
## 18 28 29 30 22 26 27 28 29 30 31 26 23 24 25 26 27 28 29
## 27 30
## Jul Aug Sep
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 27 1 2 3 4 5 6 31 1 2 3 36 1 2 3 4 5 6 7
## 28 7 8 9 10 11 12 13 32 4 5 6 7 8 9 10 37 8 9 10 11 12 13 14
## 29 14 15 16 17 18 19 20 33 11 12 13 14 15 16 17 38 15 16 17 18 19 20 21
## 30 21 22 23 24 25 26 27 34 18 19 20 21 22 23 24 39 22 23 24 25 26 27 28
## 31 28 29 30 31 35 25 26 27 28 29 30 31 40 29 30
## Oct Nov Dec
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 40 1 2 3 4 5 44 1 2 49 1 2 3 4 5 6 7
## 41 6 7 8 9 10 11 12 45 3 4 5 6 7 8 9 50 8 9 10 11 12 13 14
## 42 13 14 15 16 17[18]19 46 10 11 12 13 14 15 16 51 15 16 17 18 19 20 21
## 43 20 21 22 23 24 25 26 47 17 18 19 20 21 22 23 52 22 23 24 25 26 27 28
## 44 27 28 29 30 31 48 24 25 26 27 28 29 30 01 29 30 31
calendar("2020-01", calendar_US)
## Jan 2020
## Mo Tu We Th Fr Sa Su
## 01 1 2 3 4 5 | 1 - New Year's Day
## 02 6 7 8 9 10 11 12
## 03 13 14 15 16 17 18 19
## 04 20 21 22 23 24 25 26 | 20 - Birthday of Martin Luther King, Jr.
## 05 27 28 29 30 31
calendar(calendar = calendar_US)
## Oct 2025
## Mo Tu We Th Fr Sa Su
## 40 1 2 3 4 5
## 41 6 7 8 9 10 11 12
## 42 13 14 15 16 17[18]19 | 13 - Columbus Day
## 43 20 21 22 23 24 25 26
## 44 27 28 29 30 31
## Nov 2025
## Mo Tu We Th Fr Sa Su
## 44 1 2
## 45 3 4 5 6 7 8 9
## 46 10 11 12 13 14 15 16 | 11 - Veterans Day
## 47 17 18 19 20 21 22 23
## 48 24 25 26 27 28 29 30 | 27 - Thanksgiving Day
Public holidays in Poland have either fixed dates or are placed relative to Easter.
The calendar function below returns a three-element list (business days, holidays, and other observances). The same programming trick as before is used to name holidays and other observances.
<- function(dd)
calendar_PL
{<- as.tind(dd)
dd <- year(dd)
y <- month(dd)
m <- day(dd)
d # public holidays
<- (m == 1L) & (d == 1L)
newyear <- (y >= 2011L) & (m == 1L) & (d == 6L)
epiphany <- easter(dd) == dd
easterd <- easter(dd) + 1L == dd
eastermon <- (m == 5L) & (d == 1L)
labour <- (m == 5L) & (d == 3L)
constitution <- easter(dd) + 49L == dd
pentecost <- easter(dd) + 60L == dd
corpuschristi <- (m == 8L) & (d == 15L)
assumption <- (m == 11L) & (d == 1L)
allsaints <- (m == 11L) & (d == 11L)
independence <- (m == 12L) & (d == 24L) & (y >= 2025)
christmaseve <- (m == 12L) & (d == 25L)
christmas <- (m == 12L) & (d == 26L)
christmas2 <- newyear | epiphany |
holiday | eastermon |
easterd | constitution |
labour | corpuschristi |
pentecost |
assumption | independence |
allsaints | christmas | christmas2
christmaseve # holiday names
names(holiday) <- rep("", length(holiday))
<- c(newyear = "New Year", epiphany = "Epiphany",
holnms easterd = "Easter", eastermon = "Easter Monday",
labour = "Labour Day", constitution = "Constitution Day",
pentecost = "Pentecost", corpuschristi = "Corpus Christi",
assumption = "Assumption of Mary",
allsaints = "All Saints Day", independence = "Independence Day",
christmaseve = "Christmas Eve",
christmas = "Christmas", christmas2 = "Christmas (2nd day)")
lapply(names(holnms), function(nm) names(holiday)[get(nm)] <<- holnms[nm])
# working/business days
<- !holiday & (day_of_week(dd) <= 5L)
work # other observances
<- easter(dd) - 52L == dd
fatthursday <- easter(dd) - 47L == dd
shrovetuesday <- easter(dd) - 46L == dd
ashwednesday <- easter(dd) - 2L == dd
goodfriday <- (m == 4L) & (d == 1L)
primaaprilis <- (m == 5L) & (d == 2L)
flagday <- (m == 5L) & (d == 26L)
mothersday <- (m == 6L) & (d == 1L)
childrensday <- (m == 6L) & (d == 23L)
saintjohnseve <- (m == 11L) & (d == 2L)
allsoulsday <- (m == 11L) & (d == 29L)
saintandrewseve <- (m == 12L) & (d == 6L)
saintnicholasday <- (m == 12L) & (d == 24L) & (y < 2025)
christmaseve <- (m == 12L) & (d == 31L)
newyeareve <- fatthursday | shrovetuesday | ashwednesday |
other |
goodfriday |
primaaprilis |
flagday | childrensday | saintjohnseve |
mothersday |
allsoulsday |
saintandrewseve | christmaseve |
saintnicholasday
newyearevenames(other) <- rep("", length(other))
<- c(fatthursday = "Fat Thursday",
othernms shrovetuesday = "Shrove Tuesday",
ashwednesday = "Ash Wednesday",
goodfriday = "Good Friday",
primaaprilis = "All Fool's Day",
flagday = "Flag Day",
mothersday = "Mother's Day",
childrensday = "Children's Day",
saintjohnseve = "Saint John's Eve",
allsoulsday = "All Souls' Day",
saintandrewseve = "Saint Andrew's Eve",
saintnicholasday = "Saint Nicholas Day",
christmaseve = "Christmas Eve",
newyeareve = "New Year's Eve")
lapply(names(othernms), function(nm) names(other)[get(nm)] <<- othernms[nm])
return (list(work = work, holiday = holiday, other = other))
}
calendar(2020, calendar_PL)
## 2020
## Jan Feb Mar
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 01 1 2 3 4 5 05 1 2 09 1
## 02 6 7 8 9 10 11 12 06 3 4 5 6 7 8 9 10 2 3 4 5 6 7 8
## 03 13 14 15 16 17 18 19 07 10 11 12 13 14 15 16 11 9 10 11 12 13 14 15
## 04 20 21 22 23 24 25 26 08 17 18 19 20 21 22 23 12 16 17 18 19 20 21 22
## 05 27 28 29 30 31 09 24 25 26 27 28 29 13 23 24 25 26 27 28 29
## 14 30 31
## Apr May Jun
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 14 1 2 3 4 5 18 1 2 3 23 1 2 3 4 5 6 7
## 15 6 7 8 9 10 11 12 19 4 5 6 7 8 9 10 24 8 9 10 11 12 13 14
## 16 13 14 15 16 17 18 19 20 11 12 13 14 15 16 17 25 15 16 17 18 19 20 21
## 17 20 21 22 23 24 25 26 21 18 19 20 21 22 23 24 26 22 23 24 25 26 27 28
## 18 27 28 29 30 22 25 26 27 28 29 30 31 27 29 30
## Jul Aug Sep
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 27 1 2 3 4 5 31 1 2 36 1 2 3 4 5 6
## 28 6 7 8 9 10 11 12 32 3 4 5 6 7 8 9 37 7 8 9 10 11 12 13
## 29 13 14 15 16 17 18 19 33 10 11 12 13 14 15 16 38 14 15 16 17 18 19 20
## 30 20 21 22 23 24 25 26 34 17 18 19 20 21 22 23 39 21 22 23 24 25 26 27
## 31 27 28 29 30 31 35 24 25 26 27 28 29 30 40 28 29 30
## 36 31
## Oct Nov Dec
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 40 1 2 3 4 44 1 49 1 2 3 4 5 6
## 41 5 6 7 8 9 10 11 45 2 3 4 5 6 7 8 50 7 8 9 10 11 12 13
## 42 12 13 14 15 16 17 18 46 9 10 11 12 13 14 15 51 14 15 16 17 18 19 20
## 43 19 20 21 22 23 24 25 47 16 17 18 19 20 21 22 52 21 22 23 24 25 26 27
## 44 26 27 28 29 30 31 48 23 24 25 26 27 28 29 53 28 29 30 31
## 49 30
calendar(as.year(today()), calendar_PL)
## 2025
## Jan Feb Mar
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 01 1 2 3 4 5 05 1 2 09 1 2
## 02 6 7 8 9 10 11 12 06 3 4 5 6 7 8 9 10 3 4 5 6 7 8 9
## 03 13 14 15 16 17 18 19 07 10 11 12 13 14 15 16 11 10 11 12 13 14 15 16
## 04 20 21 22 23 24 25 26 08 17 18 19 20 21 22 23 12 17 18 19 20 21 22 23
## 05 27 28 29 30 31 09 24 25 26 27 28 13 24 25 26 27 28 29 30
## 14 31
## Apr May Jun
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 14 1 2 3 4 5 6 18 1 2 3 4 22 1
## 15 7 8 9 10 11 12 13 19 5 6 7 8 9 10 11 23 2 3 4 5 6 7 8
## 16 14 15 16 17 18 19 20 20 12 13 14 15 16 17 18 24 9 10 11 12 13 14 15
## 17 21 22 23 24 25 26 27 21 19 20 21 22 23 24 25 25 16 17 18 19 20 21 22
## 18 28 29 30 22 26 27 28 29 30 31 26 23 24 25 26 27 28 29
## 27 30
## Jul Aug Sep
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 27 1 2 3 4 5 6 31 1 2 3 36 1 2 3 4 5 6 7
## 28 7 8 9 10 11 12 13 32 4 5 6 7 8 9 10 37 8 9 10 11 12 13 14
## 29 14 15 16 17 18 19 20 33 11 12 13 14 15 16 17 38 15 16 17 18 19 20 21
## 30 21 22 23 24 25 26 27 34 18 19 20 21 22 23 24 39 22 23 24 25 26 27 28
## 31 28 29 30 31 35 25 26 27 28 29 30 31 40 29 30
## Oct Nov Dec
## Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
## 40 1 2 3 4 5 44 1 2 49 1 2 3 4 5 6 7
## 41 6 7 8 9 10 11 12 45 3 4 5 6 7 8 9 50 8 9 10 11 12 13 14
## 42 13 14 15 16 17[18]19 46 10 11 12 13 14 15 16 51 15 16 17 18 19 20 21
## 43 20 21 22 23 24 25 26 47 17 18 19 20 21 22 23 52 22 23 24 25 26 27 28
## 44 27 28 29 30 31 48 24 25 26 27 28 29 30 01 29 30 31
calendar("2020-06", calendar_PL)
## Jun 2020
## Mo Tu We Th Fr Sa Su
## 23 1 2 3 4 5 6 7 | 1 - Children's Day
## 24 8 9 10 11 12 13 14 | 11 - Corpus Christi
## 25 15 16 17 18 19 20 21
## 26 22 23 24 25 26 27 28 | 23 - Saint John's Eve
## 27 29 30
calendar(calendar = calendar_PL)
## Oct 2025
## Mo Tu We Th Fr Sa Su
## 40 1 2 3 4 5
## 41 6 7 8 9 10 11 12
## 42 13 14 15 16 17[18]19
## 43 20 21 22 23 24 25 26
## 44 27 28 29 30 31
## Nov 2025
## Mo Tu We Th Fr Sa Su
## 44 1 2 | 1 - All Saints Day, 2 - All Souls' Day
## 45 3 4 5 6 7 8 9
## 46 10 11 12 13 14 15 16 | 11 - Independence Day
## 47 17 18 19 20 21 22 23
## 48 24 25 26 27 28 29 30 | 29 - Saint Andrew's Eve
Calendar functions described above can be used for business day
computations. tind
provides the following functions that
can be used in this context:
bizday()
for finding the closest business day (using
different date rolling conventions) if the given day is not a one,bizday_diff()
for computing number of business days
between two dates,first_bizday_in_month()
,
last_bizday_in_month()
,
first_bizday_in_quarter()
,
last_bizday_in_quarter()
,bizdays_in_month()
, bizdays_in_quarter()
,
bizdays_in_year()
.Some examples using bizday()
and calendar functions
presented earlier are provided below (January 16, 2023 was a public
holiday in the US and August 15, 2023 in Poland):
calendar("2023-01", calendar = calendar_US)
## Jan 2023
## Mo Tu We Th Fr Sa Su
## 52 1 | 1 - New Year's Day
## 01 2 3 4 5 6 7 8
## 02 9 10 11 12 13 14 15
## 03 16 17 18 19 20 21 22 | 16 - Birthday of Martin Luther King, Jr.
## 04 23 24 25 26 27 28 29
## 05 30 31
bizday("2023-01-15", "p", calendar_US)
## date [tind]
## [1] 2023-01-13
bizday("2023-01-15", "f", calendar_US)
## date [tind]
## [1] 2023-01-17
bizday("2023-01-15", "mf2", calendar_US)
## date [tind]
## [1] 2023-01-13
calendar("2023-08", calendar = calendar_PL)
## Aug 2023
## Mo Tu We Th Fr Sa Su
## 31 1 2 3 4 5 6
## 32 7 8 9 10 11 12 13
## 33 14 15 16 17 18 19 20 | 15 - Assumption of Mary
## 34 21 22 23 24 25 26 27
## 35 28 29 30 31
bizday("2023-08-15", "p", calendar_PL)
## date [tind]
## [1] 2023-08-14
bizday("2023-08-15", "f", calendar_PL)
## date [tind]
## [1] 2023-08-16
bizday("2023-08-15", "mf2", calendar_PL)
## date [tind]
## [1] 2023-08-14
The code below creates a table summarising the number of business days in months in 2023 in Poland and the US.
<- as.month("2023-01") + 0:11
m data.frame(month = m, PL = bizdays_in_month(m, calendar_PL),
US = bizdays_in_month(m, calendar_US))
## month PL US
## 1 2023-01 21 21
## 2 2023-02 20 19
## 3 2023-03 23 23
## 4 2023-04 19 20
## 5 2023-05 21 22
## 6 2023-06 21 21
## 7 2023-07 21 20
## 8 2023-08 22 23
## 9 2023-09 21 20
## 10 2023-10 22 21
## 11 2023-11 21 21
## 12 2023-12 19 20
year_frac
function returns time indices as year
fractions in the form year + year fraction, where fraction is the number
of periods (quarters, months, weeks, days, seconds) since the beginning
of the year over total number of periods in the year.
<- as.date("2024-05-05")) (d
## date [tind]
## [1] 2024-05-05
year_frac(d)
## [1] 2024.342
year(d) + (day_of_year(d) - 1) / days_in_year(d)
## [1] 2024.342
as.quarter(d)
## quarter [tind]
## [1] 2024Q2
year_frac(as.quarter(d))
## [1] 2024.25
year(d) + (quarter(d) - 1) / 4
## [1] 2024.25
as.month(d)
## month [tind]
## [1] 2024-05
year_frac(as.month(d))
## [1] 2024.333
year(d) + (month(d) - 1) / 12
## [1] 2024.333
as.week(d)
## week [tind]
## [1] 2024-W18
year_frac(as.week(d))
## [1] 2024.327
year(d) + (week(d) - 1) / weeks_in_year(d)
## [1] 2024.327
daycount_frac
allows to compute accrual factor using
different day count conventions. Below we create a sequence of 5
consecutive International Money Market days and compute accrual factors
between the first and the following four using different
conventions:
<- nth_dw_in_month(3, 3, tind(y = 2025, m = 12) + 3 * (0:4))) (imm
## date [tind]
## [1] 2025-12-17 2026-03-18 2026-06-17 2026-09-16 2026-12-16
daycount_frac(imm[1L], imm[-1L], "30/360")
## [1] 0.2527778 0.5000000 0.7472222 0.9972222
daycount_frac(imm[1L], imm[-1L], "30E/360")
## [1] 0.2527778 0.5000000 0.7472222 0.9972222
daycount_frac(imm[1L], imm[-1L], "ACT/ACT")
## [1] 0.2493151 0.4986301 0.7479452 0.9972603
daycount_frac(imm[1L], imm[-1L], "ACT/365F")
## [1] 0.2493151 0.4986301 0.7479452 0.9972603
daycount_frac(imm[1L], imm[-1L], "ACT/360")
## [1] 0.2527778 0.5055556 0.7583333 1.0111111