i have a list of opening hours that more or less are in this kind of format, one value for one entire day:
[
"",
"Closed",
"8:30 AM–7:30 PM",
"9 AM–12:30 PM, 2:30–7:30 PM",
"2:30–7:30 PM",
"3–7 PM",
"10 AM–7 PM",
"8 AM–1 PM, 2:30–7 PM",
"8 AM–1 PM, 2–7 PM",
"8 AM–8:30 PM",
"9 AM–12 PM, 2:30–7 PM",
"Open 24 hours",
]
of course the time value can change, but i need to convert those in morning and afternoon opening, so i need to convert those string in a time element i think and then using 13:00 (1 PM) as the end of morning generating for each line something like this:
[
{morning:"",afternoon:""},
{morning:"closed",afternoon:"closed"},
{morning:"8-13",afternoon:"13-19"},
{morning:"9-12:30",afternoon:"14:30-19:30"},
{morning:"closed",afternoon:"14:30-19:30"},
{morning:"closed",afternoon:"15-19"},
{morning:"10-13",afternoon:"13-19"},
{morning:"8-13",afternoon:"14:30-19"},
{morning:"8-13",afternoon:"14-19"},
{morning:"8-13",afternoon:"13-20:30"},
{morning:"9-12",afternoon:"14:30-19"},
{morning:"0-13",afternoon:"13-0"},
]
in this way it would be easy to split the string with – and convert it to a time to be easy to show and edit in a webpage.
any suggestion on what is a good solution to achieve this?
empty need to remain empty,
open 24 hours i’m not sure it would be good to put 0-13 and 13-0 ..
i add close if part of the day is missing
thanks
Edit:
i’ve made this example of code, with few more cases, what do you think ??
const hours = [
"",
"Closed",
"8:30 AM–7:30 PM",
"2:30–7:30 PM",
"3–7 PM",
"10 AM–7 PM",
"8 AM–8:30 PM",
"8–10:30 AM",
"Open 24 hours",
"9–10:30 AM, 2:30–7:30 PM",
"9 AM–12:30 PM, 2:30–7:30 PM",
"8 AM–1 PM, 2:30–7 PM",
"8 AM–1 PM, 2–7 PM",
"9 AM–12 PM, 2:30–7 PM",
]
let c = []
hours.forEach(x=>{
c.push(convert(x))
})
console.log(c)
function convert(string) {
switch(string) {
case "":
return {morning:'',afternoon:''}
break;
case "Closed":
return {morning:'closed',afternoon:'closed'}
break;
case "Open 24 hours":
return {morning:'0:00-13:00',afternoon:'13:00-0:00'}
break;
}
if (string.includes(',')) {
let a = string.split(',')
let [m1,m2] = totime(a[0])
let [a1,a2] = totime(a[1])
return {morning:m1.format('H:mm')+'-'+m2.format('H:mm'),afternoon:a1.format('H:mm')+'-'+a2.format('H:mm')}
} else {
var endTime = moment('13:00', 'H:mm');
let [res1,res2] = totime(stringa)
if (res1.isBefore(endTime)){
if (res2.isAfter(endTime)) {
return {morning:res1.format('H:mm')+'-13:00',afternoon:'13:00-'+res2.format('H:mm')}
} else {
return {morning:res1.format('H:mm')+'-'+res2.format('H:mm'),afternoon:'closed'}
}
} else {
return {morning:'closed',afternoon:res1.format('H:mm')+'-'+res2.format('H:mm')}
}
}
}
function totime(s){
let b = s.split('–')
if (!(b[0].includes('AM') || b[0].includes('PM'))) {
let p = b[1].trim().split(" ")
b[0] = b[0].trim()+" "+p[1]
}
return [moment(b[0].trim(), ['h:m A', 'h:m']),moment(b[1].trim(), ['h:m A', 'h:m'])]
}
3
Answers
you can use javascript string manipulation and time parsing. you can create a function that takes an array for the opening hours and iterate over each time range, and inside of it you can use the
if
statement to handle different cases like empty strings, closed hours, and open 24 hours. and another function to convert time to 24h format. and you call your function to convert to 24h inside of your function for opening hoursBe careful, it looks like you have Unicode spaces, commas, and hyphens. I converted them into their ASCII equivalents in the
data
array.To make this easier, try to parse each slot into an array of time ranges first. This makes the logic much simpler.
Reversed transformation
You will need to parse each time range into separate hours and minutes.
Once you have done that, you can start to compare the start o the afternoon range with the end of the morning range. This will determine if you are working with one giant range or two smaller sub-ranges.
One possible parsing approach could be based on a combination of regex result, some conditions which operate upon the regex result and a configuration for the not matching special/edge cases.
A
RegExp
pattern allows for more parsing flexibility like covering too many or missing whitespaces, accidentally different separator characters like–
versus-
or (mixed) letter casing likeAM
versusam
.Such a regex pattern could utilize named groups (which are also partially optional) in order to provide meaningful names for captured data which is crucial for the parsing process. Upon the latter one would implement the conditions / clauses for creating different variants of business-hours data.
Any input values which does not match the regex pattern is going to be sanitized and unified in order to serve as key for an object-based configuration that covers all the special cases like empty values, entirely closed or open around the clock.