Skip to content

Dimension.Date

The below code is used to create a Date dimension.

Process Code

vb

var dim = "Date";

var hierDefault = "Default";
var hierDateList = "Date List"
var hierNoDate = "No Date"
var hierCTD = "Cumulative to Date"
var hierYTD = "Year to Date";
var hierMonthYTD = "Month Year to Date"
var hierMonth12M = "Rolling 12 Months";
var hierMTD = "Month to Date"
var hierMonthAssumption = "Month Assumption";
var hierWeekList = "Week List"

var hiers = [hierDefault, hierDateList, hierWeekList, hierNoDate, hierCTD, hierYTD, hierMonthYTD, hierMonth12M, hierMTD, hierMonthAssumption]

var dateFrom = null;
var dateTo = null;
var monthsCal = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];

function pre() {
    //this function is called once before the processes is executed.
    //Use this to setup prompts.
    script.log('process pre-execution parameters parsed.');

    var yearFrom = ""
    var yearTo = ""

    let rootElms = hierarchy.rootElements("Time", "Calender Year List");
    if (canBeArray(rootElms)) {//there are elms returned from rootElms
        rootElms = JSON.parse(rootElms);
        yearFrom = rootElms[0].substring(2);
        yearTo = (Number(rootElms[rootElms.length - 1].substring(2)) + 1).toString() //going through to 2026 means we only have months up to 2025 and thus need to add a month to get to what period we want
    } else {
        var d = new Date();
        yearFrom = (d.getFullYear() - 3) + "";
        yearTo = (d.getFullYear() + 1) + "";
    }


    script.prompt("Year From", "yearFrom", yearFrom);
    script.prompt("Year To", "yearTo", yearTo);


}

function begin() {
    //this function is called once at the start of the process

    script.log('process execution started.');
    dimension.createOrWipe(dim, "Standard");

    for (let hier of hiers) {
        hierarchy.createOrWipe(dim, hier)
    }

    hierarchy.group(dim, hierNoDate, "", hierNoDate);


    let dateVariableFrom = yearFrom + "-01-01"

    let variableTo = (Number(yearTo) - 1).toString() + "-12-31"

    if (dateVariableFrom == "") {
        console.log("The variable \"model.Time.Start\" used to denote the start of the date dimension is not populated.");
        script.abort("The variable \"model.Time.Start\" used to denote the start of the date dimension is not populated.");
    }

    if (variableTo == "") {
        console.log("The variable \"model.Time.Finish\" used to denote the start of the date dimension is not populated.");
        script.abort("The variable \"model.Time.Finish\" used to denote the start of the date dimension is not populated.");
    }



    dateFrom = new Date(dateVariableFrom);
    dateTo = new Date(variableTo);
    console.log(dateVariableFrom, variableTo)

    alias.createOrWipe(dim, "Week starting");

    let dateListing = getDates(dateFrom, dateTo);
    let YTDStr = "";
    let YTDItems = [];
    let TTDItems = [];

    let MTDStr = "";
    let MTDItems = [];
    var weekAlias = "";


    for (let i = 0; i < dateListing.length; i++) {
        let sDate = dateListing[i]
        let yearString = sDate.getFullYear() + "";
        let monthString = sDate.getMonthName();
        let dateString = sDate.getName();
        let finYearString = yearString;

        hierarchy.structure(dim, hierMonthAssumption, "All Month Assumptions", finYearString + " Assumption")

        hierarchy.group(dim, hierMonthAssumption, finYearString + " Assumption", monthString + " Assumption")


 

        hierarchy.group(dim, hierDateList, "", dateString);

        hierarchy.structure(dim, hierDefault, "All Dates", finYearString);
        hierarchy.structure(dim, hierDefault, finYearString, monthString);
        hierarchy.group(dim, hierDefault, monthString, dateString);



        //update weeks
        let weekString = sDate.getFullYear() + " - Wk " + sDate.getWeek();
        let weekYearString = yearString;
        let clearWeek;

        if (sDate.getWeek() == 53 && yearString != "2022") {
            //belongs to the next year.
            if (sDate.getFullYear() + 1 <= dateListing[dateListing.length - 1].getFullYear()) {
                weekString = sDate.getFullYear() + 1 + " - Wk 1";
                weekYearString = (sDate.getFullYear() + 1) + "";
            } else {
                //week doesnt exist in our date dimension
                weekString = null;
            }
        }

        if (sDate.getWeek() == 0) {
            //belongs to the next year.
            weekString = sDate.getFullYear() - 1 + " - Wk 53";
            weekYearString = (sDate.getFullYear() - 1) + "";
        }

        TTDItems.push(dateString);

        if (weekString != null) {
            hierarchy.structure(dim, "Week List", "All Weeks", weekString);
            //hierarchy.structure(dim, "Week List", "WK-" + weekYearString, weekString);
            hierarchy.group(dim, "Week List", weekString, dateString);
            if (hierarchy.childByIndex(dim, "Week List", weekString, 0) == dateString) {
                weekAlias = "WS " + dateString;
                alias.set(dim, "Week starting", weekString, weekAlias);
            }

        }


        // Get the starting month and year for grouping
        let startYear = sDate.getFullYear();
        let startMonth = sDate.getMonth(); // 0-based index for months

        // Loop through 12 months
        for (let j = 0; j < 12; j++) {
            // Calculate the current month and year for the group
            let groupYear = startYear;
            let groupMonth = startMonth + j;

            // Handle year overflow when month exceeds 11
            if (groupMonth > 11) {
                groupMonth -= 12;
                groupYear += 1;
            }

            // Generate the group name in the format "YYYY - MMM"
            let groupDate = new Date(groupYear, groupMonth, 1); // Create a date for this group
            let groupName = `${groupDate.getMonthName()} L12M`;

            // Add the sDate to the group

            let parentDate = new Date(dateString);
            let parentElm = parentDate.getMonthName()
            hierarchy.structure(dim, hierMonth12M, groupName, parentElm);
            hierarchy.group(dim, hierMonth12M, parentElm, dateString);

        }

        //update YTD's
        if (YTDStr != yearString) {
            YTDItems = [];
        }
        YTDStr = yearString;
        YTDItems.push(dateString);

        for (let k = 0; k < YTDItems.length; k++) {
            hierarchy.group(dim, hierYTD, dateString + " - YTD", YTDItems[k]);
        }

        for (let k = 0; k < TTDItems.length; k++) {
            hierarchy.group(dim, hierCTD, dateString + " - CTD", TTDItems[k]);
        }

        if (MTDStr != monthString) {
            MTDItems = [];
        }
        MTDStr = monthString;
        MTDItems.push(dateString);
        for (let k = 0; k < MTDItems.length; k++) {
            hierarchy.group(dim, hierMTD, dateString + " - MTD", YTDItems[k]);
        }

        for (let k = 0; k < YTDItems.length; k++) {
            hierarchy.group(dim, hierMonthYTD, MTDStr + " - YTD", YTDItems[k]);
        }
        if (i % 250 == 0) {
            console.log(`Dates Processed: ${i}`)
        }

    }

}

function data(record) {
    //this function is called once for each line of data on the second cycle
    //use this to build dimensions and push data into cubes

}

function end() {
    //this function is called once at the end of the process
    script.log('process execution finished.');

}
/*
Date.prototype.getWeekNumber = function(){
  var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
  var dayNum = d.getUTCDay() || 7;
  d.setUTCDate(d.getUTCDate() + 4 - dayNum);
  var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
  return Math.ceil((((d - yearStart) / 86400000) + 1)/7)
};
*/
Date.prototype.addDays = function (days) {
    var dat = new Date(this.valueOf())
    dat.setDate(dat.getDate() + days);
    return dat;
}
Date.prototype.removeDays = function (days) {
    var dat = new Date(this.valueOf())
    dat.setDate(dat.getDate() - days);
    return dat;
}
Date.prototype.getWeek = function () {
    var onejan = new Date(this.getFullYear(), 0, 1);
    return Math.ceil((((this - onejan) / 86400000) + onejan.getDay()) / 7);
}

Date.prototype.getName = function () {
    let yr = this.getFullYear();
    let mth = this.getMonth() + 1;
    let da = this.getDate();

    let mthStr = mth + "";
    if (mthStr.length == 1) {
        mthStr = "0" + mthStr;
    }

    let daStr = da + "";
    if (daStr.length == 1) {
        daStr = "0" + daStr;
    }

    return yr + "-" + mthStr + "-" + daStr;

}

Date.prototype.getMonthName = function () {
    let yr = this.getFullYear();
    let mth = monthsCal[this.getMonth()];
    return yr + " - " + mth;
}


Date.prototype.getName = function () {
    let yr = this.getFullYear();
    let mth = this.getMonth() + 1;
    let da = this.getDate();

    let mthStr = mth + "";
    if (mthStr.length == 1) {
        mthStr = "0" + mthStr;
    }

    let daStr = da + "";
    if (daStr.length == 1) {
        daStr = "0" + daStr;
    }

    return yr + "-" + mthStr + "-" + daStr;

}

function getDates(startDate, stopDate) {
    var dateArray = new Array();
    var currentDate = startDate;
    while (currentDate <= stopDate) {
        dateArray.push(currentDate)
        currentDate = currentDate.addDays(1);
    }
    return dateArray;
}



function canBeArray(input) {
    try {
        // Attempt to parse the input as JSON
        const parsed = JSON.parse(input);

        // Check if the parsed value is an array
        return Array.isArray(parsed);
    } catch (error) {
        // If parsing fails, it's not valid JSON, hence not an array
        return false;
    }
}