---
title: "Assette Get Begin & End Date Data Block"
description: "*The Assette Get Begin & End Date (ast_fn_GetBeginEndDates) Data Block is a Demo Data Block and may be edited.* The Assette Get Begin & End Date (ast_fn_GetBeginEndDates) Data Block is a Demo Data Block which processes different period codes, such…"
url: "https://learn.assette.com/docs/assette-period-date-calculation-data-block/"
updated: "2024-09-24"
category: Developers / Data Blocks / Data Blocks by Category / Transform Data Blocks
---

# Assette Get Begin & End Date Data Block

*The Assette Get Begin & End Date (ast_fn_GetBeginEndDates) Data Block is a Demo Data Block and may be edited.*

The Assette Get Begin & End Date (ast_fn_GetBeginEndDates) Data Block is a Demo Data Block which processes different period codes, such as MTD, QTD, YTD, etc., and calculates the appropriate begin_date and end_date for each code. It reads the period universe data and uses various date patterns and logic to determine the start and end dates for a given period code. After calculating the dates, the Assette Get Begin & End Date (ast_fn_GetBeginEndDates) Data Block formats them and returns the result. As an open-source demo Data Block, this Data Block may be edited as needed.

**Period Code**:
The period code is retrieved from the parameter "PeriodCode" and used to determine which time period to calculate (e.g., MTD, QTD, YTD, etc.).

**AsOfDate**:
The date from which the period calculations are based is retrieved from parameter "AsofDate".

**Period Universe**:
A dictionary of predefined period is read from the [System Period Information (sys_period_information) Data Block](https://learn.assette.com/docs/system-period-information-data-block/).

Based on the PeriodCode, various date ranges are calculated using datetime and calendar to determine the start (period_begin_date) and end (period_end_date) dates. The logic handles multiple period codes like MTD (Month-to-Date), QTD (Quarter-to-Date), YTD (Year-to-Date), fiscal periods (FYTD, MRQ), prior quarters (PQ1, PQ2), prior years (PY1, PY2), and inception-to-date (ITD). Depending on the period code, specific adjustments are made to month, year, and day values to compute the correct date range.

## General Info

*The following table shows the default fields of the Data Block*.

| Field | Value |
| --- | --- |
| Name | ast_fn_GetBeginEndDates |
| Block Category | Transform |
| Block Type | Python |
| Data Category | None |
| Output Type | Data Table |
| Editable | True |

## Dependencies

*The following table shows the default dependencies of the Data Block*.

| Data Block | Description |
| --- | --- |
| Calculation_Python_Env | The Imports (Imports) Data Block defines the required Python libraries to be imported for the script. Each library is imported with or without an alias, depending on its usage within the code. This Data Block ensures that the necessary libraries are available for handling data manipulation, date operations, JSON parsing, and other tasks. This Data Block is not edited. [[Link](https://learn.assette.com/docs/calculation-python-environment-data-block/)] |
| PythonEnvForDateCalculation | The Python Environment for Date Calculation (PythonEnvForDateCalculation) Data Block is used to import Python libraries and modules for date calculations. [[Link](https://learn.assette.com/docs/python-environment-for-date-calculation-data-block/)] |
| sys_period_information | The *System Period Information (sys_period_information)* Data Block defines a set of periods using period codes and their respective details, such as the display name, number of years, months, and quarters for each period. Each period is categorized based on its duration, such as month-to-date, quarter-to-date, year-to-date, prior years, or prior quarters. This Data Block is used to manage the calculation and display of time periods for various financial or reporting purposes. This Data Block is open-source and may be edited as needed. [[Link](https://learn.assette.com/docs/system-period-information-data-block/)] |

## Columns

*The following columns are the default columns for the Data Object, all columns are optional unless marked otherwise. Please see footnotes for additional information.*

| Name | Data Type | Example | Description |
| --- | --- | --- | --- |
| begin_date | Date | 2020-10-31 | The begin date for the given period |
| end_date | Date | 2021-01-31 | The end date for the given period |

* Indicates a mandatory column

## Example Definition

```
period_universe = read("sys_period_information")
# print(period_universe)
date_pattern = ""
period_code = params["PeriodCode"].strip()
as_of_date = params["AsofDate"]
if "DatePattern" in params.keys():
    date_pattern = params["DatePattern"].strip()

if len(date_pattern) == 0:
    date_pattern = '%Y-%m-%d'

period_begin_date = as_of_date
period_end_date = as_of_date

date_obj_begin = datetime.datetime.strptime(as_of_date, date_pattern)
date_obj_end = datetime.datetime.strptime(as_of_date, date_pattern)

if period_code == "MTD":
    month = date_obj_begin.month
    period_begin_year = date_obj_begin.year
    period_begin_month = month - 1
    if period_begin_month <= 0:
        period_begin_month = 12 + period_begin_month
        period_begin_year = date_obj_begin.year - 1

    res = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_begin_year, period_begin_month)], 30)
    period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month, day=res)
    period_end_date = date_obj_end

if period_code == "QTD":
    month = date_obj_begin.month
    year = date_obj_begin.year
    period_begin_month = month
    period_begin_year = year

    if month <= 3:
        period_begin_month = 12
        period_begin_year = year - 1
    elif 3 < month <= 6:
        period_begin_month = 3
    elif 6 < month <= 9:
        period_begin_month = 6
    elif 9 < month <= 12:
        period_begin_month = 9

    res = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_begin_year, period_begin_month)], 30)
    period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month, day=res)
    period_end_date = date_obj_end

if period_code == "YTD":
    year = date_obj_begin.year
    period_begin_month = 12
    period_begin_year = year - 1

    res = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_begin_year, period_begin_month)], 30)
    period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month, day=res)
    period_end_date = date_obj_end

if period_code == "MRQ":
    month = date_obj_begin.month
    year = date_obj_begin.year
    day = date_obj_begin.day

    period_begin_month = month
    period_begin_year = year

    period_end_month = month
    period_end_year = year

    if (month <= 2 and day <= 31) or (month == 3 and day < 30):
        period_begin_month = 9
        period_end_month = 12
        period_begin_year = year - 1
        period_end_year = year - 1

    elif (3 <= month <= 5 and day <= 31) or (month == 6 and day < 30):
        period_begin_month = 12
        period_end_month = 3
        period_begin_year = year - 1

    elif (6 <= month <= 8 and day <= 31) or (month == 9 and day < 29):
        period_begin_month = 3
        period_end_month = 6

    elif (9 <= month <= 11 and day <= 30) or (month == 12 and day < 30):
        period_begin_month = 6
        period_end_month = 9

    elif month == 12 and day == 31:
        period_begin_month = 9
        period_end_month = 12

    res_begin = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_begin_year, period_begin_month)], 30)
    res_end = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_end_year, period_end_month)], 30)
    period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month, day=res_begin)
    period_end_date = date_obj_end.replace(year=period_end_year, month=period_end_month, day=res_end)

if period_code.startswith("PQ"):
    period_details = period_universe[period_code]
    num_quarters = int(period_details['Quarters'])

    month = date_obj_begin.month
    year = date_obj_begin.year
    day = date_obj_begin.day

    period_begin_month = month
    period_begin_year = year

    period_end_month = month
    period_end_year = year

    month_delta = num_quarters * 3

    # Calculate MRQ Begin and end dates
    if (month <= 2 and day <= 31) or (month == 3 and day < 30):
        period_begin_month = 9
        period_end_month = 12
        period_begin_year = year - 1
        period_end_year = year - 1

    elif (3 <= month <= 5 and day <= 31) or (month == 6 and day < 30):
        period_begin_month = 12
        period_end_month = 3
        period_begin_year = year - 1

    elif (6 <= month <= 8 and day <= 31) or (month == 9 and day < 29):
        period_begin_month = 3
        period_end_month = 6

    elif (9 <= month <= 11 and day <= 30) or (month == 12 and day < 30):
        period_begin_month = 6
        period_end_month = 9

    elif month == 12 and day == 31:
        period_begin_month = 9
        period_end_month = 12

    res_begin = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_begin_year, period_begin_month)], 30)
    res_end = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_end_year, period_end_month)], 30)
    period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month, day=res_begin)
    period_end_date = date_obj_end.replace(year=period_end_year, month=period_end_month, day=res_end)
    ####

    begin_year = period_begin_date.year
    begin_month = period_begin_date.month

    end_year = period_end_date.year
    end_month = period_end_date.month

    begin_month = begin_month - month_delta
    end_month = end_month - month_delta

    if begin_month <= 0:
        begin_month = 12 + begin_month
        begin_year = begin_year - 1

    if end_month <= 0:
        end_month = 12 + end_month
        end_year = end_year - 1

    begin_day = ft.reduce(lambda x, y: y[1], [calendar.monthrange(begin_year, begin_month)], 30)
    end_day = ft.reduce(lambda x, y: y[1], [calendar.monthrange(end_year, end_month)], 30)

    period_begin_date = date_obj_begin.replace(year=begin_year, month=begin_month, day=begin_day)
    period_end_date = date_obj_end.replace(year=end_year, month=end_month, day=end_day)

if period_code.startswith("PY"):
    period_details = period_universe[period_code]
    num_years = int(period_details['Years'])

    month = date_obj_begin.month
    year = date_obj_begin.year
    day = date_obj_begin.day

    period_begin_year = year
    period_begin_month = month

    period_end_year = year
    period_end_month = month
    period_end_day = day

    if period_end_month == 12 and period_end_day == 31:
        period_begin_year -= (num_years + 1)
        period_end_year -= num_years
    else:
        period_begin_year -= (num_years + 2)
        period_end_year -= (num_years + 1)
        period_begin_month = 12
        period_end_month = 12

    period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month, day=31)
    period_end_date = date_obj_end.replace(year=period_end_year, month=period_end_month, day=31)

if period_code == "MRFQ":
    month = date_obj_begin.month
    year = date_obj_begin.year

    period_begin_year = year
    period_end_year = year

    fiscal_year_end = params["FiscalYearEnd"]
    fiscal_year_end_obj = datetime.datetime.strptime(fiscal_year_end, '%m-%d')

    fiscal_quarter_end_list = []

    for delta in range(1, 5):
        ym = fiscal_year_end_obj.month + 3*delta
        if ym > 12:
            ym = ym - 12
        fiscal_quarter_end_list.append(ym)

    most_recent_fiscal_quarter_end_month = fiscal_year_end_obj.month
    for item in fiscal_quarter_end_list:
        for i in range(1,4):
            temp_month = item + i
            if temp_month > 12:
                temp_month = 12 - temp_month
                if temp_month == month:
                    most_recent_fiscal_quarter_end_month = temp_month
                    period_end_year = year - 1
            elif temp_month == month:
                most_recent_fiscal_quarter_end_month = item

    most_recent_fiscal_quarter_begin_month = most_recent_fiscal_quarter_end_month - 3

    if most_recent_fiscal_quarter_begin_month <= 0:
        most_recent_fiscal_quarter_begin_month = most_recent_fiscal_quarter_begin_month + 12
        period_begin_year = period_begin_year - 1

    res_begin = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_begin_year, most_recent_fiscal_quarter_begin_month)], 30)
    res_end = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_end_year, most_recent_fiscal_quarter_end_month)], 30)

    period_begin_date = date_obj_begin.replace(year=period_begin_year, month=most_recent_fiscal_quarter_begin_month, day=res_begin)
    period_end_date = date_obj_end.replace(year=period_end_year, month=most_recent_fiscal_quarter_end_month, day=res_end)

if period_code.startswith("PFQ"):
    # Calculate most recent fiscal quarter first
    month = date_obj_begin.month
    year = date_obj_begin.year

    period_begin_year = year
    period_end_year = year

    fiscal_year_end = params["FiscalYearEnd"]
    fiscal_year_end_obj = datetime.datetime.strptime(fiscal_year_end, '%m-%d')

    fiscal_quarter_end_list = []

    for delta in range(1, 5):
        ym = fiscal_year_end_obj.month + 3 * delta
        if ym > 12:
            ym = ym - 12
        fiscal_quarter_end_list.append(ym)

    most_recent_fiscal_quarter_end_month = fiscal_year_end_obj.month
    for item in fiscal_quarter_end_list:
        for i in range(1, 4):
            temp_month = item + i
            if temp_month > 12:
                temp_month = 12 - temp_month
                if temp_month == month:
                    most_recent_fiscal_quarter_end_month = temp_month
                    period_end_year = year - 1
            elif temp_month == month:
                most_recent_fiscal_quarter_end_month = item

    most_recent_fiscal_quarter_begin_month = most_recent_fiscal_quarter_end_month - 3

    if most_recent_fiscal_quarter_begin_month <= 0:
        most_recent_fiscal_quarter_begin_month += 12
        period_begin_year = period_begin_year - 1

    ###
    ## Calculate the prior fiscal quarter periods
    period_details = period_universe[period_code]
    num_quarters = int(period_details['Quarters'])

    most_recent_fiscal_quarter_end_month = most_recent_fiscal_quarter_end_month - 3*num_quarters
    if most_recent_fiscal_quarter_end_month <=0 :
        most_recent_fiscal_quarter_end_month += 12
        period_end_year -= 1

    most_recent_fiscal_quarter_begin_month = most_recent_fiscal_quarter_end_month - 3
    if most_recent_fiscal_quarter_begin_month <=0 :
        most_recent_fiscal_quarter_begin_month += 12
        period_begin_year -= 1

    res_begin = ft.reduce(lambda x, y: y[1],
                            [calendar.monthrange(period_begin_year, most_recent_fiscal_quarter_begin_month)], 30)
    res_end = ft.reduce(lambda x, y: y[1],
                        [calendar.monthrange(period_end_year, most_recent_fiscal_quarter_end_month)], 30)

    period_begin_date = date_obj_begin.replace(year=period_begin_year, month=most_recent_fiscal_quarter_begin_month,
                                                day=res_begin)
    period_end_date = date_obj_end.replace(year=period_end_year, month=most_recent_fiscal_quarter_end_month,
                                            day=res_end)

if period_code.startswith("PFY"):
    period_details = period_universe[period_code]
    num_years = int(period_details['Years'])

    fiscal_year_end = params["FiscalYearEnd"]
    fiscal_year_end_obj = datetime.datetime.strptime(fiscal_year_end, '%m-%d')

    year = date_obj_begin.year

    begin_year = year - num_years - 1
    begin_month = fiscal_year_end_obj.month

    end_year = year - num_years
    end_month = fiscal_year_end_obj.month

    end_day = ft.reduce(lambda x, y: y[1], [calendar.monthrange(end_year, end_month)], 30)

    period_begin_date = date_obj_begin.replace(year=begin_year, month=begin_month, day=end_day)
    period_end_date = date_obj_end.replace(year=end_year, month=end_month, day=end_day)

if period_code == "FYTD":
    month = date_obj_begin.month
    year = date_obj_begin.year

    fiscal_year_end = params["FiscalYearEnd"]
    fiscal_year_end_obj = datetime.datetime.strptime(fiscal_year_end, '%m-%d')

    period_begin_month = fiscal_year_end_obj.month
    period_begin_day = fiscal_year_end_obj.day
    period_begin_year = year

    period_end_month = month
    if period_end_month <= period_begin_month:
        period_begin_year = year - 1

    period_begin_date = date_obj_begin.replace(year = period_begin_year, month = period_begin_month, day = period_begin_day)
    period_end_date = date_obj_end

if period_code.endswith("MT"):
    period_details = period_universe[period_code]
    num_months = int(period_details['Months'])

    month = date_obj_begin.month
    year = date_obj_begin.year
    day = date_obj_begin.day

    period_begin_month = month
    period_begin_year = year

    period_end_month = month
    period_end_year = year

    res_end = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_end_year, period_end_month)], 30)
    if res_end == day:
        period_begin_month = period_begin_month - num_months
        if period_begin_month <= 0:
            period_begin_year = period_begin_year - 1
            period_begin_month = 12 + period_begin_month
        res_begin = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_begin_year, period_begin_month)], 30)
        period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month, day=res_begin)
    else:
        period_begin_month = period_begin_month - num_months
        if period_begin_month <= 0:
            period_begin_year = period_begin_year - 1
            period_begin_month = 12 + period_begin_month
        res_begin = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_begin_year, period_begin_month)], 30)
        if period_begin_month == 2:
            if day > res_begin:
                period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month,
                                                            day=res_begin)
            else:
                period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month,
                                                            day=day)
        else:
            period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month,
                                                            day=day)
    period_end_date = date_obj_end

if period_code.endswith("YC") or period_code.endswith("YA"):
    period_details = period_universe[period_code]
    num_years = int(period_details['Years'])

    month = date_obj_begin.month
    year = date_obj_begin.year
    day = date_obj_begin.day

    period_begin_month = month
    period_begin_year = year

    period_end_month = month
    period_end_year = year

    res_end = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_end_year, period_end_month)], 30)
    if res_end == day:
        period_begin_year = period_begin_year - num_years
        res_begin = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_begin_year, period_begin_month)], 30)
        period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month, day=res_begin)
    else:
        period_begin_year = period_begin_year - num_years
        res_begin = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_begin_year, period_begin_month)], 30)
        if period_begin_month == 2:
            if day > res_begin:
                period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month,
                                                            day=res_begin)
            else:
                period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month,
                                                            day=day)
        else:
            period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month,
                                                        day=day)
    period_end_date = date_obj_end

if period_code == "ITDA" or period_code == "ITD":
    date_obj_begin = datetime.datetime.strptime(params["InceptionDate"], '%Y-%m-%d')
    period_begin_date = date_obj_begin
    period_end_date = date_obj_end

if period_code.startswith("MRM"):
    month = date_obj_begin.month
    year = date_obj_begin.year
    day = date_obj_begin.day

    period_begin_month = month
    period_begin_year = year

    period_end_month = month
    period_end_year = year
    period_end_day = day

    if period_end_day == ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_end_year, period_end_month)], 30):
        period_begin_month -= 1
        if period_begin_month == 0:
            period_begin_year -= 1
            period_begin_month = 12
        period_begin_day = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_begin_year, period_begin_month)], 30)
    else:
        period_begin_month -= 2
        period_end_month -= 1
        if period_begin_month <= 0:
            period_begin_year -= 1
            period_begin_month = 12 + period_begin_month
        period_begin_day = ft.reduce(lambda x, y: y[1],
                                        [calendar.monthrange(period_begin_year, period_begin_month)], 30)
        if period_end_month == 0:
            period_end_year -= 1
            period_end_month = 12
        period_end_day = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_end_year, period_end_month)], 30)

    period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month,
                                                day=period_begin_day)
    period_end_date = date_obj_end.replace(year=period_end_year, month=period_end_month,
                                                day=period_end_day)

if period_code.startswith("PM"):
    period_details = period_universe[period_code]
    num_months = int(period_details['Months'])

    month = date_obj_begin.month
    year = date_obj_begin.year
    day = date_obj_begin.day

    period_begin_month = month
    period_begin_year = year

    period_end_month = month
    period_end_year = year
    period_end_day = day

    if period_end_day == ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_end_year, period_end_month)], 30):
        period_begin_month -= (num_months + 1)
        period_end_month -= (num_months)
        if period_begin_month <= 0:
            period_begin_year -= 1
            period_begin_month += 12
        period_begin_day = ft.reduce(lambda x, y: y[1],
                                        [calendar.monthrange(period_begin_year, period_begin_month)], 30)
        if period_end_month <= 0:
            period_end_year -= 1
            period_end_month = 12
        period_end_day = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_end_year, period_end_month)], 30)
    else:
        period_begin_month -= (num_months + 2)
        period_end_month -= (num_months + 1)
        if period_begin_month <= 0:
            period_begin_year -= 1
            period_begin_month = 12 + period_begin_month
        period_begin_day = ft.reduce(lambda x, y: y[1],
                                        [calendar.monthrange(period_begin_year, period_begin_month)], 30)
        if period_end_month == 0:
            period_end_year -= 1
            period_end_month = 12
        period_end_day = ft.reduce(lambda x, y: y[1], [calendar.monthrange(period_end_year, period_end_month)], 30)

    period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month,
                                                day=period_begin_day)
    period_end_date = date_obj_end.replace(year=period_end_year, month=period_end_month,
                                            day=period_end_day)
if period_code.startswith("MRY"):
    month = date_obj_begin.month
    year = date_obj_begin.year
    day = date_obj_begin.day

    period_begin_year = year
    period_begin_month = month

    period_end_year = year
    period_end_month = month
    period_end_day = day

    if period_end_month == 12 and period_end_day == 31:
        period_begin_year -= 1
    else:
        period_begin_year -= 2
        period_end_year -= 1
        period_begin_month = 12
        period_end_month = 12

    period_begin_date = date_obj_begin.replace(year=period_begin_year, month=period_begin_month,
                                                day=31)
    period_end_date = date_obj_end.replace(year=period_end_year, month=period_end_month,
                                            day=31)
period_begin_date = period_begin_date.strftime('%Y-%m-%d')
period_end_date = period_end_date.strftime('%Y-%m-%d')

response['data'] = [{"begin_date": period_begin_date, "end_date": period_end_date}]
```

## Example Request

*The following code shows an example request using the default values of the Data Block*.

```
{
    "AsofDate": "2021-05-31",
    "PeriodCode":"PFQ1",
    "FiscalYearEnd": "04-30",
    "InceptionDate": "2015-09-08",
    "DatePattern": "%Y-%m-%d"
}
```

## Example Response

*The following code shows an example response using the default values of the Data Block. The default data source is the Assette Snowflake Demo Instance. The response may be shortened for brevity*.

```
{
    "data": [
        {
            "begin_date": "2020-10-31",
            "end_date": "2021-01-31"
        }
    ],
    "errors": [],
    "success": true,
    "logs": []
}
```
