Author: Alexey Seleznev
Date: 2026-05-12

# Intro to timeperiodsR

#### Alexey Seleznev

#### 2026-05-12

# Цель пакета timeperiodsR

Зачастую при создании скриптов которые в последствии будут запускаться по расписанию нам необходимо определить некий отчётный период. Как правило, таким периодом может быть прошлая неделя, прошлый месяц, либо какое-то количество прошлых дней. Пакет timeperiodsR предоставляет вам набор функций которые автоматически будут вычислять такой период от заданной даты. Все функции пакета возвращают период в виде объекта класса tpr. В этой виньетке мы подробно разберём все функции пакета `timeperiodsR`, а также компоненты и методы класса tpr.

# Содержание

- Простой пример использования
- Функции пакета
- Компоненты класса tpr
- Аргументы
- Методы
- Операторы
- Конвертация других объектов в класс tpr
- Пользовательские выходные дни

Помимо данной виньетки к пакету `timeperiodsR` есть видео инструкция, ознакомится с которой можно по этой ссылке.

# Простой пример использования

Как я уже писал выше, основная цель `timeperiodsR` упростить процесс определения относительного периода. Если у вас есть скрипт который запускается по рассписанию, и собирает данные за прошлый месяц, то вы можете получить прошлый месяц следующим образом:

    library(timeperiodsR)
    #>
    #> ---------------------
    #> Welcome to timeperiodsR version 0.7.7
    #>
    #> Author:           Alexey Seleznev (Head of analytics dept at Netpeak).
    #> Telegram channel: https://t.me/R4marketing
    #> Email:            selesnow@gmail.com
    #> Blog:             https://alexeyseleznev.wordpress.com
    #> Facebook:         https://facebook.com/selesnown
    #> Linkedin:         https://www.linkedin.com/in/selesnow
    #>
    #> Type ?timeperiodsR for the main documentation.
    #> The github page is: https://github.com/selesnow/timeperiodsR/
    #>
    #> Suggestions and bug-reports can be submitted at: https://github.com/selesnow/timeperiodsR/issues
    #> Or contact: <selesnow@gmail.com>
    #>
    #>  To suppress this message use:  suppressPackageStartupMessages(library(timeperiodsR))
    #> ---------------------

    # получаем прошлый месяц
    period <- previous_month()

    # получаем начальную и конечную дату прошлого месяца
    start <- period$start # первый день прошлого месяца
    end   <- period$end   # последний день прошлого месяца

Код определения временно периода с помощью `timeperiodsR` компактен и легко читаем, таким же бразом вы можете определять и любые другие периоды, о чём вы более подробно узнаете из данной статьи.

# Функции пакета timeperiodsR

Текущая версия пакета состоит из 24 функций, по названию каждой из функций можно определить какой временной интервал она возвращает. Название состоит из префикса `last` / `previous` / `this` / `next` и временной единицы `day` / `week` / `month` / `quarter` / `year`. Нижнее подчёркивание `_` является разделителем слов в названиях функций.

## Список функций

- `last_n_days()`
- `last_n_weeks()`
- `last_n_months()`
- `last_n_quarters()`
- `last_n_years()`
- `previous_week()`
- `previous_month()`
- `previous_quarter()`
- `previous_year()`
- `this_week()`
- `this_month()`
- `this_quarter()`
- `this_year()`
- `next_week()`
- `next_month()`
- `next_quarter()`
- `next_year()`
- `next_n_days()`
- `next_n_weeks()`
- `next_n_months()`
- `next_n_quarters()`
- `next_n_years()`
- `custom_period()`
- `as_timeperiod()`
- `check_dayoffs()`

## Компоненты получаемых объектов

Любая из функций пакета возвращает объект класса `tpr` состоящий из следующих компонентов:

Обязательные компоненты

- start - начальная дата;
- end - конечная дата;
- first_workday - первый рабочий день;
- last_workday - последний рабочий день;
- first_weekend - первый выходной день;
- last_weekend - последний выходной день;
- sequence - последовательность дат;
- workdays - последовательность будних дней;
- weekends - последовательность выходных дней;
- length - количество дней входящих в период;
- workdays_length - количество будних дней входящих в период;
- weekends_length - количество выходных дней входящих в период;

Дополнительные компоненты

- official_workdays - Официальные рабочие дни;
- official_first_workday - Первый официальный рабочий день;
- official_last_workday - Последний официальный рабочий день;
- official_day_offs - официальные выходные дни в выбранной стране, по умолчанию России;
- custom_day_offs - пользовательские выходные дни;
- dayoffs_marks - пометки о том, какой статус имеет день в официальном календаре страны;
- custom_day_offs - пользовательские выходные.

Начиная с версии `timeperiodsR 0.5.0` в пакет была интегрирована поддержка API производственного календаря isDayOff. Этот API позволяет получить официальные праздничные дни в следующих странах: Россия, Украина, Казахстан и Белоруссия.

Для активации дополнительных компонентов вам необходимо установить пакет `httr`.

    install.packages("httr")

По умолчанию дополнительные компоненты приведённые выше выключены, т.к. они нужны не всем пользователям пакета, а пакет с использованием API работает значительно медленнее.

Для расширения класса `tpr` дополнительными компонентами вы можете воспользоваться опциями или переменными среды.

#### Опции для включения дополнительных компонентов

- timeperiodsR.official_day_offs - включение дополнительных компонентов, по умолчанию имеет значение `FALSE`;
- timeperiodsR.official_day_offs_country - установить страну для которой будет запрашиваться список официальных выходных дней:
  - ru - Россия, значение по умолчанию;
  - ua - Украина
  - by - Белоруссия
  - kz - Казахстан
- timeperiodsR.official_day_offs_pre - распознавать, что день предпраздничный, т.е. сокращённым:
  - 0 - без вывода сокращённых дней (по умолчанию)
  - 1 - распознавать, что день предпраздничный (сокращённый)

Пример установки опций:

    options("timeperiodsR.official_day_offs" = TRUE,
            "timeperiodsR.official_day_offs_country" = "ua",
            "timeperiodsR.official_day_offs_pre" = 1)

#### Переменные среды для включения дополнительных компонентов

Опции удобны для работы, но их необходимо задавать при каждом новом сеансе работы с R, если все указанные в опциях параметры в большинстве случаев у вас статичны, то лучше задать их на уровне операционной системы.

О том как создавать переменные среды можно узнать из этого видео.

Задайте следующие переменные среды для того, что бы не указывать опции в каждом сеансе:

- TPR_DAY_OFFS - TRUE, для активации дополнительных компонентов;
- TPR_COUNTRY - Страна: ru, ua, by или kz;
- TPR_PRE - Включать в компонент official_day_offs сокращённые рабочие дни, в компоненте dayoffs_marks они будут помечены числом 2.

После того как вы установите значения для переменных среды пакет автоматически будет считывать их при подключении.

## Аргументы

В функциях пакета timeperiodsR присутствуют следующие аргументы:

- x - Объект даты, от которой будет вычисляться интервал, по умолчанию это текущий день;
- n - Количество временных интервалов на которое необходимо сместится от даты указанной в аргументе x;
- part - Какую часть объекта вам необходимо получить:
  - “all” - объект со всеми доступными компонентами;
  - “start” - начальную дату;
  - “end” - конечную дату;
  - “first_workday” - первый рабочий день периода;
  - “last_workday” - последний рабочий день периода;
  - “first_weekend” - первый выходной день периода;
  - “last_weekend” - последний выходной день периода;
  - “sequence” - последовательность дат;
  - “workdays” - последовательность будних дней в периоде;
  - “weekends” - последовательность выходных дней в периоде;
  - “length” - количество дней входящих в период;
  - “workdays_length” - количество будних дней входящих в период;
  - “weekends_length” - количество выходных дней входящих в период;
  - “official_workdays” - официальные рабочие дни для указанной страны;
  - “official_first_workday” - первый официальный рабочий день для указанной страны;
  - “official_last_workday” - последний официальный рабочий день для указанной страны;
  - “official_day_offs” - официальные выходные дни для указанной страны;
  - “dayoffs_marks” - пометки для каждого дня;
- week_start - Какой день будет являться началом недели: 1 - понедельник, 7 - воскресенье;
- include_current - Включать ли в период текущий временной объект, TRUE или FALSE.

## Методы

Пакет `timeperiodsR` имеет несколько методов, позволяющих вам извлекать некоторые элементы объектов класса tpr.

- `seq` - получить последовательность дат из объекта класса tpr;
- `length` - получить длительность объекта класса tpr в днях;
- `start` - получить первую дату из объекта класса tpr;
- `end` - получить последнюю дату из объекта класса tpr;
- `first_workday` - получить первый рабочий день из объекта класса tpr;
- `last_workday` - получить последний рабочий день из объекта класса tpr;
- `first_weekend` - получить первый выходной день из объекта класса tpr;
- `last_weekend` - получить последний выходной из объекта класса tpr;
- `workdays` - получить последовательность рабочих дней из объекта класса tpr;
- `weekends` - получить последовательность выходных из объекта класса tpr;
- `workdays_length` - получить из объекта класса tpr;
- `weekends_length` - получить из объекта класса tpr;
- `print` - вывести в консоль информацию о периоде содержащемся в объекте класса tpr.

# last_n_*

Функции блока `last_n_*()` позволяют вам получить прошлый период с заданным количеством временных единиц.

Вместо `*` подставьте один из нужных вам временных интервалов: days, weeks, months, quarters, years

Например, допустим, что сегодня 26 сентября 2019 года и вам необходимо получить 2 прошлые недели то используйте функцию `last_n_weeks()`:

    last2weeks <- last_n_weeks(n = 2)

2 прошлые недели

Код захватит даты с 9 по 22 сентября включительно.

После чего у вас появится объект last2weeks класса `tpr`. Из него вы легко можете получить начальную или конечную дату периода, а так же всю последовательность дат которая вошла в этот период, или количество дней вошедших в период.

    # начальная дата
    last2weeks$start
    #> [1] "2026-04-27"
    ## или
    start(last2weeks)
    #> [1] "2026-04-27"

    # конечная дата
    last2weeks$end
    #> [1] "2026-05-10"
    ## или
    end(last2weeks)
    #> [1] "2026-05-10"

    # первый рабочий день
    last2weeks$first_workday
    #> [1] "2026-04-27"
    ## или
    first_workday(last2weeks)
    #> [1] "2026-04-27"

    # последний рабочий день
    last2weeks$last_workday
    #> [1] "2026-05-08"
    ## или
    last_workday(last2weeks)
    #> [1] "2026-05-08"

    # первый выходной день
    last2weeks$first_weekend
    #> [1] "2026-05-02"
    ## или
    first_weekend(last2weeks)
    #> [1] "2026-05-02"

    # последний выходной день
    last2weeks$last_weekend
    #> [1] "2026-05-10"
    ## или
    last_weekend(last2weeks)
    #> [1] "2026-05-10"

    # последовательность дат
    last2weeks$sequence
    #>  [1] "2026-04-27" "2026-04-28" "2026-04-29" "2026-04-30" "2026-05-01"
    #>  [6] "2026-05-02" "2026-05-03" "2026-05-04" "2026-05-05" "2026-05-06"
    #> [11] "2026-05-07" "2026-05-08" "2026-05-09" "2026-05-10"
    ## или
    seq(last2weeks)
    #>  [1] "2026-04-27" "2026-04-28" "2026-04-29" "2026-04-30" "2026-05-01"
    #>  [6] "2026-05-02" "2026-05-03" "2026-05-04" "2026-05-05" "2026-05-06"
    #> [11] "2026-05-07" "2026-05-08" "2026-05-09" "2026-05-10"

    # последовательность будних дней
    last2weeks$workdays
    #>  [1] "2026-04-27" "2026-04-28" "2026-04-29" "2026-04-30" "2026-05-01"
    #>  [6] "2026-05-04" "2026-05-05" "2026-05-06" "2026-05-07" "2026-05-08"
    ## или
    workdays(last2weeks)
    #>  [1] "2026-04-27" "2026-04-28" "2026-04-29" "2026-04-30" "2026-05-01"
    #>  [6] "2026-05-04" "2026-05-05" "2026-05-06" "2026-05-07" "2026-05-08"

    # последовательность выходных дней
    last2weeks$weekends
    #> [1] "2026-05-02" "2026-05-03" "2026-05-09" "2026-05-10"
    # или
    weekends(last2weeks)
    #> [1] "2026-05-02" "2026-05-03" "2026-05-09" "2026-05-10"

    # количество дней вошедших в период
    last2weeks$length
    #> [1] 14
    ## или
    length(last2weeks)
    #> [1] 14

    # количество будних дней в периоде
    last2weeks$workdays_length
    #> [1] 10
    ## или
    workdays_length(last2weeks)
    #> [1] 10

    # количество выходных дней в периоде
    last2weeks$weekends_length
    #> [1] 4
    ## или
    weekends_length(last2weeks)
    #> [1] 4

Во всех функциях предназначенных для работы с неделями т.е. `last_n_weeks()`, `previous_week()`, `this_week()`, `next_week()`, `next_n_weeks()` присутствует аргумент week_start, с его помощью можно указать день недели который будет являться её началом. По умолчанию неделя начинается с понедельника, т.е. `week_start = 1`, но вы можете задать и любой другой день:

1. Понедельник
2. Вторник
3. Среда
4. Четверг
5. Пятница
6. Суббота
7. Воскресенье

Т.е. если вы хотите получить 2 предыдущие недели отталкиваясь от 26 сентября, и при этом необходимо считать началом недели воскресенье то используйте следующий код:

    library(timeperiodsR)

    last2weeks <- last_n_weeks(x = "2019-09-26", n = 2, week_start = 7)

Две предыдущие недели, начало недели воскресенье

# previous_*

Функции блока `previous_*()` позволяют вам получить прошлый период со смещением на заданное количеством временных единиц. Т.е. например получить позапрошлую неделю.

Вместо `*` подставьте один из нужных вам временных интервалов: week, month, quarter, year

Допустим нам необходимо получить позапрошлую неделю отталкиваясь от 26 сентября 2019 года, началом недели должен быть понедельник

    previous2weeks <- previous_week(x = "2019-09-26", n = 2)

Позапрошлая неделя

# this_*

Функции блока `this_*()` позволяют вам получить текущий период.

Вместо `*` подставьте один из нужных вам временных интервалов: week, month, quarter, year

Если вам необходимо получить первую и последнюю дату текущего месяца, и всю последовательность дат которые в него входят, то используйте следующий код:

    this_month()
    #>
    #>  Time period: 2026-05-01 (пятница) - 2026-05-31 (воскресенье)

Текущий месяц

Т.е. если сегодня 26 сентября 2019 года функция `this_month()` захватит весь сентябрь 2019 года.

# next_*

Функции блока `next_*()` противоположный функциям блока `previous_*()`. Т.е. позволяют вам получить будущий период со смещением на заданное количеством временных единиц. Т.е. например получить следующую неделю от 12 сентября.

Вместо `*` подставьте один из нужных вам временных интервалов: week, month, quarter, year

    nextweek_from_12sep <- next_week("2019-09-12")

    nextweek_from_today <- next_week()

Следующая неделя

# next_n_*

Блок `next_n_*` позволяет создать период обратный от того, что создают функции блока `last_n_*`, т.е. получить будущий период с заданным количеством временных единиц.

Вместо `*` подставьте один из нужных вам временных интервалов: days, weeks, months, quarters, years

Например если вам необходимо получить 5 следующих дней воспользуйтесь следующим кодом.

    # получить 5 следующих дней не включая текущую дату
    next5days <- next_n_days(n = 5)

    # получить 5 следующих дней включая текущую дату
    next5days_wt <- next_n_days(n = 5, include_current = T)

# custom_period

Данная функция позволяет создавать объект класса tpr с любым произвольным периодом.

    period1 <- custom_period("2019-09-03", "2019-09-11")

# Операторы

В `timeperiodsR` есть несколько операторов.

- %.in% - проверяет вхождение одного вектора дат, или объекта класса tpr в другой, и возвращает логический вектор.
- %left_out% - сравнивает два объекта класса tpr, и возвращает значение из левого, которые отсутствуют в правом.
- %left_in% - сравнивает два объекта класса tpr, и возвращает даты из левого объекта которые входят в правый
- %right_out% - сравнивает два объекта класса tpr, и возвращает значение из правого, которые отсутствуют в левом.
- %right_in% - сравнивает два объекта класса tpr, и возвращает даты из правого объекта которые присутствуют в левом.

Из представленного описания возможно сложно понять зачем эти операторы нужны, и как именно они работают. Поэтому рассмотрим несколько примеров.

Сначала создадим два объекта tpr класса, относительно 7 ноября 2019 года. Один будет соответствовать текущему месяцу, а второй предыдущей неделе.

    period1 <- this_month("2019-11-07")
    period2 <- previous_week("2019-11-07")

    print(period1)
    #>
    #>  Time period: 2019-11-01 (пятница) - 2019-11-30 (суббота)
    print(period2)
    #>
    #>  Time period: 2019-10-28 (понедельник) - 2019-11-03 (воскресенье)

В таком случае первый период содержит даты с 1 по 30 ноября, а второй с 28 октября по 3 ноября. Т.е. частично эти два периода пересекаются и мы можем фильтровать один из используя значения другого.

    period1 %left_in% period2   # получить даты из period1 которые входят в period2
    #> [1] "2019-11-01" "2019-11-02" "2019-11-03"
    period1 %left_out% period2  # получить даты из period1 которые не входят в period2
    #>  [1] "2019-11-04" "2019-11-05" "2019-11-06" "2019-11-07" "2019-11-08"
    #>  [6] "2019-11-09" "2019-11-10" "2019-11-11" "2019-11-12" "2019-11-13"
    #> [11] "2019-11-14" "2019-11-15" "2019-11-16" "2019-11-17" "2019-11-18"
    #> [16] "2019-11-19" "2019-11-20" "2019-11-21" "2019-11-22" "2019-11-23"
    #> [21] "2019-11-24" "2019-11-25" "2019-11-26" "2019-11-27" "2019-11-28"
    #> [26] "2019-11-29" "2019-11-30"
    period1 %right_in% period2  # получить даты из period2 которые входят в period1
    #> [1] "2019-11-01" "2019-11-02" "2019-11-03"
    period1 %right_out% period2 # получить даты из period2 которые не входят в period2
    #> [1] "2019-10-28" "2019-10-29" "2019-10-30" "2019-10-31"

Такие операторы фильтрации удобно использовать например при проверке наличия данных в базе за какой-то период, в тех случаях когда вы наполняете базу данными из внешних источников на ежедневной основе.

К примеру вы каждый день запрашиваете данные из API Google Analytics, и записываете их в базу. При этом API периодически может давать сбой, и за какой-то день в вашей базе будут отсутствовать данные, тогда вы можете определить проверочный период, например предыдущие 30 дней, с помощью команды `last_n_days(n = 30)`. Далее запрашивать данные за этот из вашей СУБД. После, с помощью приведённых выше операторов фильтрации убрать из общего 30 дневного периода даты которые присутствуют в базе, и по оставшимся датам подгрузить данные.

# Конвертация различных объектов в класс tpr

Вы можете преобразоватьвектор из дат, или строковый вектор состоящий из дат в формате YYYY-MM-DD в объект класса tpr с помощью функции `as_timeperiod()`.

    dates <- c("2019-09-11", "2019-09-02", "2019-10-11", "2019-08-30")
    dates_tpr <- as_timeperiod(dates)
    dates_tpr
    #>
    #>  Time period: 2019-08-30 (пятница) - 2019-10-11 (пятница)

В приведённом выше примере конвертации строкового вектора в объект класса tpr, исходный вектор содержит 4 даты, они идут в произвольном порядке, и в целом между ними много пропущенных дней, т.е. данный вектор не является непрерывной последовательностью дат. В таком случае функция `as_timeperiod()` находит в исходном векторе минимальную и максимальную дату, и создаёт объект класса tpr равный временному интервалу между этими двумя датами.

# Пользовательские выходные дни

Иногда помимо официальных выходных дней вам может понадобиться выделить собственные дополнительные выходные дни, например ваш отпуск. Пакет `timeperiodsR` даёт вам такую возможность с помощью опции или переменной среды.

В опцию `timeperiodsR.custom_day_offs` вы можете передать вектор с датами которые будут помечены как дополнительные выходные дни, такие дни в компоненте dayoffs_marks будут помечены значением 3.

Также вы можете задать переменную среды `TPR_CUSTOM_DAY_OFFS`, в которой укажите даты в формате ГГГГ-ММ-ДД разделённые запятыми или точками с запятой.

Таким образом вы можете помечать дополнительные выходные дни.

    options("timeperiodsR.custom_day_offs" = c("2020-01-14", "2020-01-15", "2020-01-16", "2020-01-17", "2020-02-12"))
    tm <- this_month("2020-01-01")

    # получить ваши пользовательские выходные которые входят в текущий период
    tm$custom_day_offs
    #> [1] "2020-01-14" "2020-01-15" "2020-01-16" "2020-01-17"

    # пользовательские выходные будут помечены 3
    tm$dayoffs_marks
    #> 2020-01-01 2020-01-02 2020-01-03 2020-01-04 2020-01-05 2020-01-06 2020-01-07
    #>        "1"        "0"        "0"        "1"        "1"        "1"        "1"
    #> 2020-01-08 2020-01-09 2020-01-10 2020-01-11 2020-01-12 2020-01-13 2020-01-14
    #>        "0"        "0"        "0"        "2"        "1"        "0"        "3"
    #> 2020-01-15 2020-01-16 2020-01-17 2020-01-18 2020-01-19 2020-01-20 2020-01-21
    #>        "3"        "3"        "3"        "1"        "1"        "0"        "0"
    #> 2020-01-22 2020-01-23 2020-01-24 2020-01-25 2020-01-26 2020-01-27 2020-01-28
    #>        "0"        "0"        "0"        "1"        "1"        "0"        "0"
    #> 2020-01-29 2020-01-30 2020-01-31
    #>        "0"        "0"        "0"