diff --git a/OsmAnd-java/src/net/osmand/util/OpeningHoursParser.java b/OsmAnd-java/src/net/osmand/util/OpeningHoursParser.java index 3762dade8b..b131da8d40 100644 --- a/OsmAnd-java/src/net/osmand/util/OpeningHoursParser.java +++ b/OsmAnd-java/src/net/osmand/util/OpeningHoursParser.java @@ -291,12 +291,14 @@ public class OpeningHoursParser { } // start from the most specific rule for (int i = rules.size() - 1; i >= 0 ; i--) { - OpeningHoursRule r = rules.get(i); - if (r.contains(cal)) { - boolean open = r.isOpenedForTime(cal); - if (!open && overlap ) { - continue; - } else { + boolean checkNext = false; + OpeningHoursRule rule = rules.get(i); + if (rule.contains(cal)) { + if (i > 0) { + checkNext = !rule.hasOverlapTimes(cal, rules.get(i - 1)); + } + boolean open = rule.isOpenedForTime(cal); + if (open || (!overlap && !checkNext)) { return open; } } @@ -411,10 +413,16 @@ public class OpeningHoursParser { private String getTimeDay(Calendar cal, int limit, boolean opening, int sequenceIndex) { String atTime = ""; ArrayList rules = getRules(sequenceIndex); + OpeningHoursRule prevRule = null; for (OpeningHoursRule r : rules) { if (r.containsDay(cal) && r.containsMonth(cal)) { - atTime = r.getTime(cal, false, limit, opening); + if (atTime.length() > 0 && prevRule != null && !r.hasOverlapTimes(cal, prevRule)) { + return atTime; + } else { + atTime = r.getTime(cal, false, limit, opening); + } } + prevRule = r; } return atTime; } @@ -451,13 +459,17 @@ public class OpeningHoursParser { } // start from the most specific rule for (int i = rules.size() - 1; i >= 0; i--) { - OpeningHoursRule r = rules.get(i); - if (r.contains(cal)) { - boolean open = r.isOpenedForTime(cal); - if (!open && overlap) { - ruleClosed = r.toLocalRuleString(); + boolean checkNext = false; + OpeningHoursRule rule = rules.get(i); + if (rule.contains(cal)) { + if (i > 0) { + checkNext = !rule.hasOverlapTimes(cal, rules.get(i - 1)); + } + boolean open = rule.isOpenedForTime(cal); + if (open || (!overlap && !checkNext)) { + return rule.toLocalRuleString(); } else { - return r.toLocalRuleString(); + ruleClosed = rule.toLocalRuleString(); } } } @@ -587,7 +599,16 @@ public class OpeningHoursParser { * @return true if the rule overlap to the next day */ public boolean hasOverlapTimes(); - + + /** + * Check if r rule times overlap with this rule times at "cal" date. + * + * @param cal the date to check + * @param r the rule to check + * @return true if the this rule times overlap with r times + */ + public boolean hasOverlapTimes(Calendar cal, OpeningHoursRule r); + /** * @param cal * @return true if rule applies for current time @@ -1238,7 +1259,7 @@ public class OpeningHoursParser { @Override public boolean hasOverlapTimes() { - for (int i = 0; i < startTimes.size(); i++) { + for (int i = 0; i < this.startTimes.size(); i++) { int startTime = this.startTimes.get(i); int endTime = this.endTimes.get(i); if (startTime >= endTime && endTime != -1) { @@ -1248,6 +1269,41 @@ public class OpeningHoursParser { return false; } + @Override + public boolean hasOverlapTimes(Calendar cal, OpeningHoursRule r) { + if (off) { + return true; + } + if (r != null && r.contains(cal) && r instanceof BasicOpeningHourRule) { + BasicOpeningHourRule rule = (BasicOpeningHourRule) r; + if (startTimes.size() > 0 && rule.startTimes.size() > 0) { + for (int i = 0; i < this.startTimes.size(); i++) { + int startTime = this.startTimes.get(i); + int endTime = this.endTimes.get(i); + if (endTime == -1) { + endTime = 24 * 60; + } else if (startTime >= endTime) { + endTime = 24 * 60 + endTime; + } + for (int k = 0; k < rule.startTimes.size(); k++) { + int rStartTime = rule.startTimes.get(k); + int rEndTime = rule.endTimes.get(k); + if (rEndTime == -1) { + rEndTime = 24 * 60; + } else if (rStartTime >= rEndTime) { + rEndTime = 24 * 60 + rEndTime; + } + if ((rStartTime >= startTime && rStartTime < endTime) + || (startTime >= rStartTime && startTime < rEndTime)) { + return true; + } + } + } + } + } + return false; + } + private int calculate(Calendar cal) { int month = cal.get(Calendar.MONTH); if (!months[month]) { @@ -1313,6 +1369,11 @@ public class OpeningHoursParser { return false; } + @Override + public boolean hasOverlapTimes(Calendar cal, OpeningHoursRule r) { + return false; + } + @Override public boolean containsDay(Calendar cal) { return false; @@ -2145,19 +2206,29 @@ public class OpeningHoursParser { testOpened("27.01.2018 05:00", hours, true); testOpened("28.01.2018 05:00", hours, true); - testInfo("22.01.2018 05:00", hours, "Will open at 07:00 (Restaurant)", 0); - testInfo("26.01.2018 00:00", hours, "Will close at 01:00 (Restaurant)", 0); - testInfo("22.01.2018 05:00", hours, "Will open at 07:00 (McDrive)", 1); - testInfo("22.01.2018 00:00", hours, "Open till 04:00 (McDrive)", 1); - testInfo("22.01.2018 02:00", hours, "Will close at 04:00 (McDrive)", 1); - testInfo("27.01.2018 02:00", hours, "Open till 24:00 (McDrive)", 1); + testInfo("22.01.2018 05:00", hours, "Will open at 07:00 - Restaurant", 0); + testInfo("26.01.2018 00:00", hours, "Will close at 01:00 - Restaurant", 0); + testInfo("22.01.2018 05:00", hours, "Will open at 07:00 - McDrive", 1); + testInfo("22.01.2018 00:00", hours, "Open till 04:00 - McDrive", 1); + testInfo("22.01.2018 02:00", hours, "Will close at 04:00 - McDrive", 1); + testInfo("27.01.2018 02:00", hours, "Open till 24:00 - McDrive", 1); hours = parseOpenedHours("07:00-03:00 open \"Restaurant\" || 24/7 open \"McDrive\""); System.out.println(hours); testOpened("22.01.2018 02:00", hours, true); testOpened("22.01.2018 17:00", hours, true); - testInfo("22.01.2018 05:00", hours, "Will open at 07:00 (Restaurant)", 0); - testInfo("22.01.2018 04:00", hours, "Open 24/7 (McDrive)", 1); + testInfo("22.01.2018 05:00", hours, "Will open at 07:00 - Restaurant", 0); + testInfo("22.01.2018 04:00", hours, "Open 24/7 - McDrive", 1); + hours = parseOpenedHours("Mo-Fr 12:00-15:00, Tu-Fr 17:00-23:00, Sa 12:00-23:00, Su 14:00-23:00"); + System.out.println(hours); + testOpened("16.02.2018 14:00", hours, true); + testOpened("16.02.2018 16:00", hours, false); + testOpened("16.02.2018 17:00", hours, true); + testInfo("16.02.2018 9:45", hours, "Open from 12:00"); + testInfo("16.02.2018 12:00", hours, "Open till 15:00"); + testInfo("16.02.2018 14:00", hours, "Will close at 15:00"); + testInfo("16.02.2018 16:00", hours, "Will open at 17:00"); + testInfo("16.02.2018 18:00", hours, "Open till 23:00"); } }