Create an array of dates for looping in Azure Data Factory
In today’s article I am going to share a solution on how to create an array of dates to loop through in an Azure Data Factory pipeline. An array like this can be useful when you need to run a set of activities for a specific date, and you need that period to be dynamic. For instance, in one pipeline run you wanted the last week, but in the next you need the whole month.
Aside from an Azure subscription and a Data Factory resource, the things needed are:
- Three pipeline parameters: start date, number of days to include in the array and the time direction (past or future);
- A pipeline array variable to hold the dates;
- A ForEach activity to populate the array variable with the dates.
startDate
is the starting point of the period. The ForEach will start on this date and, depending on the timeDirection
parameter, will either add dates before or after this date. daysToGet
specifies the number of days to include in the array.
The way the rest of the logic in this demo pipeline is set up, timeDirection
can be a hyphen (-) to signify that we want dates before startdate
, or any other character to get dates after instead. Note startDate
is written in UTC format to simplify the code later on. The array is actually an array of UTC timestamps, but we are only interested in the date portions.
As an example, with the default values I included in the previous screenshot the pipeline would have an array with the week (last seven days) before March 1st 2021.
And here is the array variable, that defaults to an empty array:
Now let’s dive into the pipeline. We need a single ForEach activity to populate the initially empty array of dates with all the dates needed:
This one-activity demo pipeline uses a ForEach to append each day to the array but, in a real pipeline, you would follow this up with a second ForEach to loop through that array and actually use the dates.
This “Create date range” activity is looping through the values from zero until daysToGet
so the array has the number of dates needed.
@range(0, pipeline().parameters.daysToGet)
Inside the loop there is a single Append variable activity. This activity is enough to process the logic to get a date and append it to the array:
Diving into the dynamic content:
@addDays(
pipeline().parameters.startDate,
mul(
item(),
if(
equals(pipeline().parameters.timeDirection, '-'),
-1,
1
)
)
)
We have a couple of nested function calls to make sure we move as many days forward or backward as needed in each iteration of the loop. This piece of code does three things (starting from the if
):
- Returns -1 if we want to move backwards from the
startDate
or 1 if we want to move forward, by checking if thetimeDirection
‘s value is a hyphen; - Then it multiplies the current value of the numeric loop by the value returned by
if
(e.g. in the first iteration with an hyphen fortimeDirection
, this multiplication would be 0 times -1, the second 1 times -1 and so on); - Lastly, it adds as many days to the
startdate
as the result of the multiplication, thanks to theaddDays
function. Again, with atimeDirection
poiting to the past, the first iteration of the loop would have a multiplication result of 0, so thestartDate
is appended to the array, the second iteration appends the previous day (startDate
minus one day), the third iteration append the day before that, and so on.
Below is a table with the values for a full run of this ForEach activity for four days:
And this is pretty much everything I had to show. That second ForEach activity I mentioned earlier could be used like this:
(note the Sequential setting keeps the order of the items in the array, but it means you can’t have multiple loop iterations running in parallel)
As a last note, here’s the complete JSON for this pipeline.