Matt B
Matt B

Reputation: 37

Date values between two times for each day of the month

I have a task where I need to extract data from an API. I need to specify to only collect data between 7am and 9pm for every day in a given month.

This will be a Bash script that will run at 00:01 on the 1st of each month using cron.

The API will only accept times in Epoch time. The script needs to be flexible enough so I don't have to code in every single day of a year.

I am having problems wrapping my head around this issue. I can get the first day of a month with the epoch time at 7am and the epoch time at 9pm, the API will accept these two epoch values and looks between the 2 times.

I can also get last day of the month with the epoch time at 7am and again at 9pm.

What I cannot figure out are the days between the first and last day of the month for 7am epoch and 9pm epoch.

START_LAST_MONTH=$(date "+%Y-%m-01" -d "-1 Month");
START_DAY_SEVEN_AM_EPOCH_DATE=$(date +%s -d"$START_LAST_MONTH 7am");
START_DAY_NINE_PM_EPOCH_DATE=$(date +%s -d"$START_LAST_MONTH 9pm");


END_LAST_MONTH=$(date "+%Y-%m-%d" -d "$START_LAST_MONTH +1 month -1 day");
END_DAY_SEVEN_AM_EPOCH_DATE=$(date +%s -d"$END_LAST_MONTH 7am");
END_DAY_NINE_PM_EPOCH_DATE=$(date +%s -d"$END_LAST_MONTH 9pm");

I am thinking a way to achieve this is to add a 86400 seconds to the 7am and 9pm START_DAY variables, creating new variables by doing so, then increment upwards a day until the END_DAY 7am and 9pm Epoch time variables are hit. This should be flexible then for each month, since the number of days in a month vary.

But this is beyond my bash scripting skills and I am looking to learn how to achieve this so any help would be appreciated, another angle to look at this from is also fine.

UPDATE:

I now have this in a bash script

#!/bin/sh -x

START_LAST_MONTH=$(date "+%Y-%m-01" -d "-1 Month");
START_DAY_SEVEN_AM_EPOCH_DATE=$(date +%s -d"$START_LAST_MONTH 7am");
START_DAY_NINE_PM_EPOCH_DATE=$(date +%s -d"$START_LAST_MONTH 9pm");


END_LAST_MONTH=$(date "+%Y-%m-%d" -d "$START_LAST_MONTH +1 month -1 day");
END_DAY_SEVEN_AM_EPOCH_DATE=$(date +%s -d"$END_LAST_MONTH 7am");
END_DAY_NINE_PM_EPOCH_DATE=$(date +%s -d"$END_LAST_MONTH 9pm");

until [ $END_DAY_SEVEN_AM_EPOCH_DATE ]
do
let ADD_ONE_DAY=$START_DAY_SEVEN_AM_EPOCH_DATE+86400
echo $ADD_ONE_DAY
done


But its not echoing the ADD_ONE_DAY variable at all. When debugging using -X it gets to here: until [ $END_DAY_SEVEN_AM_EPOCH_DATE ] and doesnt do anything further.

Upvotes: 0

Views: 62

Answers (1)

acran
acran

Reputation: 9018

The problem with your updated example code is that in the loop condition you are effectively only checking $END_DAY_SEVEN_AM_EPOCH_DATE not to be empty - which is just set two lines above, therefore the loop body is never executed.

To make your example work as intended try these modifications:

#!/bin/sh -x

START_LAST_MONTH=$(date "+%Y-%m-01" -d "-1 Month");
START_DAY_SEVEN_AM_EPOCH_DATE=$(date +%s -d"$START_LAST_MONTH 7am");
START_DAY_NINE_PM_EPOCH_DATE=$(date +%s -d"$START_LAST_MONTH 9pm");


END_LAST_MONTH=$(date "+%Y-%m-%d" -d "$START_LAST_MONTH +1 month -1 day");
END_DAY_SEVEN_AM_EPOCH_DATE=$(date +%s -d"$END_LAST_MONTH 7am");
END_DAY_NINE_PM_EPOCH_DATE=$(date +%s -d"$END_LAST_MONTH 9pm");

ADD_ONE_DAY=$START_DAY_SEVEN_AM_EPOCH_DATE
until [ "$ADD_ONE_DAY" -gt "$END_DAY_SEVEN_AM_EPOCH_DATE" ]
do
let ADD_ONE_DAY=$ADD_ONE_DAY+86400
echo $ADD_ONE_DAY
done
  1. adjust the loop condition to test whether $ADD_ONE_DAY is greater than $END_DAY_SEVEN_AM_EPOCH_DATE
  2. initialize $ADD_ONE_DAY with before the loop $START_DAY_SEVEN_AM_EPOCH_DATE
  3. within the loop increment $ADD_ONE_DAY by one day (instead of $START_DAY_SEVEN_AM_EPOCH_DATE, which results in always the same value, i.e. an endless loop)

Another solution in order to loop through all days of a month using the seq command could be:

#!/bin/bash

START_LAST_MONTH=$(date "+%Y-%m-01" -d "-1 Month")
END_LAST_MONTH=$(date "+%Y-%m-%d" -d "$START_LAST_MONTH +1 month -1 day")

CURRENT_YEAR=$(date +%Y -d "-1 Month")
CURRENT_MONTH=$(date +%m -d "-1 Month")
LAST_DAY_OF_MONTH=$(date +%d -d "$END_LAST_MONTH");

for CURRENT_DAY in $(seq -w 1 "$LAST_DAY_OF_MONTH"); do
    CURRENT_DATE="$CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DAY"
    CURRENT_DAY_SEVEN_AM_EPOCH=$(date +%s -d"$CURRENT_DATE 7am")
    CURRENT_DAY_NINE_PM_EPOCH=$(date +%s -d"$CURRENT_DATE 9pm")

    echo "$CURRENT_DAY_SEVEN_AM_EPOCH - $CURRENT_DAY_NINE_PM_EPOCH"
done

Here seq -w 1 "$LAST_DAY_OF_MONTH" will generate a sequence from 1 to the last day of the respective month, the -w outputs the numbers with equal width filling in 0s if necessary, i.e. "01", "02", ...

Upvotes: 2

Related Questions