diff --git a/OsmAnd-java/src/net/osmand/util/OpeningHoursParser.java b/OsmAnd-java/src/net/osmand/util/OpeningHoursParser.java index 9bfc24476c..0155310818 100644 --- a/OsmAnd-java/src/net/osmand/util/OpeningHoursParser.java +++ b/OsmAnd-java/src/net/osmand/util/OpeningHoursParser.java @@ -29,8 +29,8 @@ public class OpeningHoursParser { private static final String[] localMothsStr; private static final int LOW_TIME_LIMIT = 120; - private static final int HIGH_TIME_LIMIT = 300; private static final int WITHOUT_TIME_LIMIT = -1; + private static final int CURRENT_DAY_TIME_LIMIT = -2; static { DateFormatSymbols dateFormatSymbols = DateFormatSymbols.getInstance(Locale.US); @@ -203,7 +203,7 @@ public class OpeningHoursParser { } public String getOpeningTime(Calendar cal) { - return getTime(cal, HIGH_TIME_LIMIT, true); + return getTime(cal, CURRENT_DAY_TIME_LIMIT, true); } public String getNearToClosingTime(Calendar cal) { @@ -865,11 +865,11 @@ public class OpeningHoursParser { for (int i = 0; i < startTimes.size(); i++) { int startTime = startTimes.get(i); int endTime = endTimes.get(i); - if (opening) { + if (opening != off) { if (startTime < endTime || endTime == -1) { if (days[d] && !checkAnotherDay) { int diff = startTime - time; - if (limit == WITHOUT_TIME_LIMIT || ((time <= startTime) && (diff <= limit))) { + if (limit == WITHOUT_TIME_LIMIT || (time <= startTime && (diff <= limit || limit == CURRENT_DAY_TIME_LIMIT))) { formatTime(startTime, sb); break; } @@ -881,7 +881,7 @@ public class OpeningHoursParser { } else if (time > endTime && days[ad] && checkAnotherDay) { diff = 24 * 60 - endTime + time; } - if (limit == WITHOUT_TIME_LIMIT || ((diff != -1) && (diff <= limit))) { + if (limit == WITHOUT_TIME_LIMIT || (diff != -1 && diff <= limit || limit == CURRENT_DAY_TIME_LIMIT)) { formatTime(startTime, sb); break; } @@ -890,7 +890,7 @@ public class OpeningHoursParser { if (startTime < endTime && endTime != -1) { if (days[d] && !checkAnotherDay) { int diff = endTime - time; - if (limit == WITHOUT_TIME_LIMIT || ((time <= endTime) && (diff <= limit))) { + if ((limit == WITHOUT_TIME_LIMIT && diff >= 0) || (time <= endTime && diff <= limit)) { formatTime(endTime, sb); break; } @@ -900,9 +900,9 @@ public class OpeningHoursParser { if (time <= endTime && days[d] && !checkAnotherDay) { diff = 24 * 60 - time + endTime; } else if (time < endTime && days[ad] && checkAnotherDay) { - diff = startTime - time; + diff = endTime - time; } - if (limit == WITHOUT_TIME_LIMIT || ((diff != -1) && (diff <= limit))) { + if (limit == WITHOUT_TIME_LIMIT || (diff != -1 && diff <= limit)) { formatTime(endTime, sb); break; } @@ -1486,6 +1486,66 @@ public class OpeningHoursParser { } } + /** + * test if the calculated opening hours are what you expect + * + * @param time the time to test in the format "dd.MM.yyyy HH:mm" + * @param hours the OpeningHours object + * @param expected the expected string in format: + * "Open from HH:mm" - open in 5 hours + * "Will open at HH:mm" - open in 2 hours + * "Open till HH:mm" - close in 5 hours + * "Will close at HH:mm" - close in 2 hours + * "Will open on HH:mm (Mo,Tu,We,Th,Fr,Sa,Su)" - open in >5 hours + * "Open 24/7" - open 24/7 + */ + private static void testInfo(String time, OpeningHours hours, String expected) throws ParseException + { + Calendar cal = Calendar.getInstance(); + cal.setTime(new SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.US).parse(time)); + + boolean opened24_calc = false; + boolean openFrom_calc = false; + boolean willOpenAt_calc = false; + boolean openTill_calc = false; + boolean willCloseAt_calc = false; + boolean willOpenOn_calc = false; + + boolean opened = hours.isOpenedForTimeV2(cal); + if (opened) { + opened24_calc = hours.isOpened24_7(); + openTill_calc = !Algorithms.isEmpty(hours.getClosingTime(cal)); + willCloseAt_calc = !Algorithms.isEmpty(hours.getNearToClosingTime(cal)); + } else { + openFrom_calc = !Algorithms.isEmpty(hours.getOpeningTime(cal)); + willOpenAt_calc = !Algorithms.isEmpty(hours.getNearToOpeningTime(cal)); + willOpenOn_calc = !Algorithms.isEmpty(hours.getOpeningDay(cal)); + } + + String description = "Unknown"; + if (opened24_calc) { + description = "Open 24/7"; + } else if (willOpenAt_calc) { + description = "Will open at " + hours.getNearToOpeningTime(cal); + } else if (openFrom_calc) { + description = "Open from " + hours.getOpeningTime(cal); + } else if (willCloseAt_calc) { + description = "Will close at " + hours.getNearToClosingTime(cal); + } else if (openTill_calc) { + description = "Open till " + hours.getClosingTime(cal); + } else if (willOpenOn_calc) { + description = "Will open on " + hours.getOpeningDay(cal); + } + + boolean result = expected.equalsIgnoreCase(description); + + System.out.printf(" %sok: Expected %s (%s): %s (rule %s)\n", + (!result ? "NOT " : ""), time, expected, description, hours.getCurrentRuleTime(cal)); + + if (!result) + throw new IllegalArgumentException("BUG!!!"); + } + private static void testParsedAndAssembledCorrectly(String timeString, OpeningHours hours) { String assembledString = hours.toString(); boolean isCorrect = assembledString.equalsIgnoreCase(timeString); @@ -1693,8 +1753,49 @@ public class OpeningHoursParser { String hoursString = "mo-fr 11:00-21:00; PH off"; hours = parseOpenedHoursHandleErrors(hoursString); testParsedAndAssembledCorrectly(hoursString, hours); - + // test open from/till + hours = parseOpenedHours("Mo-Fr 08:30-17:00; 12:00-12:40 off;"); + System.out.println(hours); + testInfo("15.01.2018 09:00", hours, "Open till 12:00"); + testInfo("15.01.2018 11:00", hours, "Will close at 12:00"); + testInfo("15.01.2018 12:00", hours, "Will open at 12:40"); + + hours = parseOpenedHours("Mo-Fr: 9:00-13:00, 14:00-18:00"); + System.out.println(hours); + testInfo("15.01.2018 08:00", hours, "Will open at 09:00"); + testInfo("15.01.2018 09:00", hours, "Open till 13:00"); + testInfo("15.01.2018 12:00", hours, "Will close at 13:00"); + testInfo("15.01.2018 13:10", hours, "Will open at 14:00"); + testInfo("15.01.2018 14:00", hours, "Open till 18:00"); + testInfo("15.01.2018 16:00", hours, "Will close at 18:00"); + testInfo("15.01.2018 18:10", hours, "Will open on 09:00 Tu"); + hours = parseOpenedHours("Mo-Sa 02:00-10:00; Th off"); + System.out.println(hours); + testInfo("15.01.2018 23:00", hours, "Will open on 02:00 Tu"); + + hours = parseOpenedHours("Mo-Sa 23:00-02:00; Th off"); + System.out.println(hours); + testInfo("15.01.2018 22:00", hours, "Will open at 23:00"); + testInfo("15.01.2018 23:00", hours, "Open till 02:00"); + testInfo("16.01.2018 00:30", hours, "Will close at 02:00"); + testInfo("16.01.2018 02:00", hours, "Open from 23:00"); + + hours = parseOpenedHours("Mo-Sa 08:30-17:00; Th off"); + System.out.println(hours); + testInfo("17.01.2018 20:00", hours, "Will open on 08:30 Fr"); + testInfo("18.01.2018 05:00", hours, "Will open on 08:30 Fr"); + testInfo("20.01.2018 05:00", hours, "Open from 08:30"); + testInfo("21.01.2018 05:00", hours, "Will open on 08:30 Mo"); + testInfo("22.01.2018 02:00", hours, "Open from 08:30"); + testInfo("22.01.2018 04:00", hours, "Open from 08:30"); + testInfo("22.01.2018 07:00", hours, "Will open at 08:30"); + testInfo("23.01.2018 10:00", hours, "Open till 17:00"); + testInfo("23.01.2018 16:00", hours, "Will close at 17:00"); + + hours = parseOpenedHours("24/7"); + System.out.println(hours); + testInfo("24.01.2018 02:00", hours, "Open 24/7"); } }