I have a Cloud function that runs everyday, every 10 mins. It calculates some numbers regarding orders and customers for each restaurant branch.
Every branch has working hours, for example:
06:00 - 03:00 (24H) This means from 6:00 Tuesday to 3:00 Wednesday.
I made the function so that it handles the current day hours and whatever that is left of the previous day.
Tuesday(remaining 3 hours for Monday):
00:00 - 03:00
Tuesday:
06:00 - 23:59:59:999
Here's how the code handles generating the ranges:
const getRangeForOneDay = async (forPreviousDay = false) => {
const lowerBound = "06:00"
const upperBound = "03:00";
const lowerBoundSplit = ["06", "00"];
const startOfToday = new Date();
startOfToday.setHours(
forPreviousDay ? 0 : parseInt(lowerBoundSplit[0]),
forPreviousDay ? 0 : parseInt(lowerBoundSplit[1]),
0,
0
);
const upperBoundSplit = ["03", "00"];
const endOfToday = new Date();
endOfToday.setHours(
forPreviousDay ? parseInt(upperBoundSplit[0]) : 23,
forPreviousDay ? parseInt(upperBoundSplit[1]) : 59,
forPreviousDay ? 0 : 59,
forPreviousDay ? 0 : 999
);
return [startOfToday, endOfToday];
};
const rangeToday = getRangeForOneDay(false);
const rangeYesterday = getRangeForOneDay(true);
const ranges = [rangeToday, rangeYesterday];
const branchId = "some real id";
for (const range of ranges) {
const [startOfToday, endOfToday] = range;
const orders = await admin
.firestore()
.collection("Orders")
.where("branch_id", "==", branchId)
.where("create_on", ">=", startOfToday)
.where("create_on", "<=", endOfToday)
.orderBy("create_on", "desc")
.get();
console.log(`Orders length = ${orders.size}`);
}
Here's how the ranges would look like:
Current Day(Tuesday):
From Date = 2022-11-08T06:00:00.000Z
To Date = 2022-11-08T23:59:59.999Z
Previous Day(Monday remaining hours data):
From Date = 2022-11-08T00:00:00.000Z
To Date = 2022-11-08T03:00:00.000Z
Both ranges are correct. You can see that the second range is for the previous day calculations, yet it takes place during the first 3 hours of the current day(Monday), which is also what I want.
My problem is that, for the second range, the query always returns 0. Despite creating an order between 12AM and 3AM Today(Tuesday) Nov 11th.
The order I created was at 12:44:33 AM
, but still it does not show up!
What am I doing wrong in the ranges?
I just want the code to work for this exact case. The normal case(first range), should work fine I think.
By the way, the timezone I am in is Toronto(-5). Though I don't think it matters since Firestore saves dates in UTC, just displays them on the Cloud Firestore in local timezone.
CodePudding user response:
The time ranges in output are in UTC
(notice the Z
instead of -05:00
). If the time range is supposed to be Toronto time then you'll have to convert it first. Try using luxon and refactoring to code as shown below:
import { DateTime } from "luxon";
const getRangeForOneDay = () => {
const today = DateTime.now().setZone("America/Toronto").startOf("day");
return [
[today.toJSDate(), today.plus({ hour: 3 }).toJSDate()],
[today.set({ hour: 6 }).toJSDate(), today.endOf("day").toJSDate()],
];
};
The time ranges that you've mentioned are technically on the same day of your timezone or I renamed the var names above.
const ranges = getRangeForOneDay();
console.log('>>> ranges', ranges)
const branchId = "some real id";
for (const range of ranges) {
const [startOfToday, endOfToday] = range;
const orders = await admin
.firestore()
.collection("Orders")
.where("branch_id", "==", branchId)
.where("create_on", ">=", startOfToday)
.where("create_on", "<=", endOfToday)
.orderBy("create_on", "desc")
.get();
console.log(`Orders length = ${orders.size}`);
}
Now document with time 00:44
should fall in 00:00 - 03:00 UTC-5
time range.