This is a nice snippet I got from an ESRI dev that returns what day a location has open in the Pro Symbology Expression Builder. It uses the DaysOpen field in my layer. My field values are like so: Su,M,Tu,W,Th,F,Sa.
Here is the expression:
var days_abbr = ["Su", "M", "Tu", "W", "Th", "F", "Sa"];
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var weekday = Weekday(Today());
If(Find(days_abbr[weekday],$feature.DaysOpen,0)!=-1) {
return "Open (" + days[weekday] + ")";
}
else {
return "Closed";
}
My question here is how to expand on that to include time using the Find() function. I created similar variables to get the time.
Here is one attempt which returns an error (see pseudo text below) on the If() line.
var days_abbr = ["Su", "M", "Tu", "W", "Th", "F", "Sa"];
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var weekday = Weekday(Today());
var hours = ["8","8.5","9","9.5"]; //I also tried ["8","8:30","9","9:30"] which resulted in error
var timeofday = Time(Now()); //this displays the time the way I anticipated it
If(Find(days_abbr[weekday],$feature.DaysOpen,0)!=-1 && Find(hours[timeofday],$feature.Time,0)!=-1) {
return "Open Now";
}
else {
return "Closed";
}
// Error: Invalid expression. Integer index expected.
Solved! Go to Solution.
I found it almost impossible to figure out how to extract the days and times logically in an Arcade script. The only thing I could come up with it to have a string field (LocationHoursByDay) with each day's time span or closed in a concatenated list, where "M - Tr 9:30 AM - 8 PM, F 9:30 AM - 6:30 PM, Sa - 10 AM - 3:30 PM, Su 11 AM - 3:30 PM"
would be represented as "9:30-20, 9:30-20, 9:30-20, 9:30-20, 9:30-18:30, 10-15:30, 11-15:30"
while the line "M,W,F 8:30 AM - 11 AM"
would be "8:30-11, closed, 8:30-11, closed, 8:30-11, closed, closed"
That field would be utilized in this script
function ConvertTime(input) {
var theTime = input;
if (Find(":", theTime) > -1) {
var times = split(theTime, ":");
theTime = Number(times[0]) + Number(times[1]) / 60;
}
return Number(theTime);
}
var current = ConvertTime(Time(Now()));
var fTime = '8:30-11, closed, 8:30-11, closed, 8:30-11, closed, closed'; //$feature.LocationHoursByDay,
var times = Split(fTime, ', ')
var todaysTime = times[Weekday(Today()) - 1];
if (todaysTime == 'closed') return 'Closed'
var todaysTimes = Split(todaysTime, '-')
var start = ConvertTime(todaysTimes[0]);
var end = ConvertTime(todaysTimes[1]);
iif(current >= start && current <= end, 'Open Now', 'Closed')
It may be as simple as you are missing the closing right parenthesis for the IF statement on line 8.
What type of field is "Time": a date field, a string field, or a numeric field? What type of values does it contain?
@KenBuja
Thanks for pointing that out. It's a text field. Same goes for the DaysOpen field.
And what types of values would it contain?
The values would be opening and closing times. For example:
8, 4:30
9,5
1,3
OK, that made it a bit tougher. Here's my solution, with one big assumption. I assumed that there wouldn't be any openings/closings before 6 am or after 6 pm (line 7) to convert it to a 24 hour time. I used the dummy variables "DaysOpen" and "fTime" for testing, which you can replace with your fields.
function ConvertTime(input) {
var theTime = input;
if (Find(":", theTime) > -1) {
var times = split(theTime, ":");
theTime = Number(times[0]) + Number(times[1]) / 60;
}
iif(theTime < 6, Number(theTime) + 12, Number(theTime));
}
var DaysOpen = "Th, F";
var fTime = "8, 2";
var days_abbr = ["Su", "M", "Tu", "W", "Th", "F", "Sa"];
var weekday = Weekday(Today());
var timeofday = Time(Now());
var current = hour(timeofday) + (minute(timeofday)/60);
var opening = Split(fTime, ",");
var start = ConvertTime(opening[0]);
var end = ConvertTime(opening[1]);
if (Find(days_abbr[weekday], DaysOpen, 0) != -1 && (current >= start && current <= end)) {
return "Open Now";
} else {
return "Closed";
}
Thanks for that. I replaced the dummy variables and it verified OK. However, there was only the Closed symbol class showing. It's not returning Open Now. So, it's hard telling where it's going wrong.
var DaysOpen = "Su,M,Tu,W,Th,F,Sa";
var fTime = "8,8:30,9,9:30,10,10:30,11,11:30,12,12:30,1,1:30,2:30,3,3:30,4,4:30,5,5:30,6,6:30,7,7:30,8,8:30,9";
Unfortunately, there are more that a few Time field values that are after 6pm.
You have to replace the test variables with your feature like this:
function ConvertTime(input) {
var theTime = input;
if (Find(":", theTime) > -1) {
var times = split(theTime, ":");
theTime = Number(times[0]) + Number(times[1]) / 60;
}
iif(theTime < 6, Number(theTime) + 12, Number(theTime));
}
//var DaysOpen = "Th, F";
//var fTime = "8, 2";
var days_abbr = ["Su", "M", "Tu", "W", "Th", "F", "Sa"];
var weekday = Weekday(Today());
var timeofday = Time(Now());
var current = hour(timeofday) + (minute(timeofday)/60);
var opening = Split($feature.Time, ",");
var start = ConvertTime(opening[0]);
var end = ConvertTime(opening[1]);
if (Find(days_abbr[weekday], $feature.DaysOpen, 0) != -1 && (current >= start && current <= end)) {
return "Open Now";
} else {
return "Closed";
}
What are the earliest and latest times?
Ah, yes. Thank you. Earlier I changed the values to 24hr times. The earliest is 8:00 and the latest is 21:00. There's also one oddball open 24hr location, which I'll have to work in somehow.