Changeset 7046 in josm
- Timestamp:
- 2014-05-02T01:40:37+02:00 (11 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/data/validator/opening_hours.js
r6489 r7046 1 1 (function (root, factory) { 2 //====================================================================== 3 // Constants 4 //====================================================================== 2 // constants (holidays, error correction) {{{ 3 // holidays {{{ 5 4 var holidays = { 6 5 'fr': { … … 1104 1103 }, 1105 1104 }, 1105 'ca': { 1106 'PH': { // https://en.wikipedia.org/wiki/Public_holidays_in_Canada 1107 "New Year's Day" : [ 1, 1 ], 1108 "Good Friday" : [ 'easter', -2 ], 1109 "Canada Day" : [ 'canadaDay', 0 ], 1110 "Labour Day" : [ 'firstSeptemberMonday', 0 ], 1111 "Christmas Day" : [ 12, 25 ] 1112 }, 1113 'Alberta': { 1114 'PH': { 1115 "New Year's Day" : [ 1, 1 ], 1116 "Alberta Family Day" : [ 'firstFebruaryMonday', 14 ], 1117 "Good Friday" : [ 'easter', -2 ], 1118 "Easter Monday" : [ 'easter', 1 ], 1119 "Victoria Day" : [ 'victoriaDay', 0 ], 1120 "Canada Day" : [ 'canadaDay', 0 ], 1121 "Heritage Day" : [ 'firstAugustMonday', 0 ], 1122 "Labour Day" : [ 'firstSeptemberMonday', 0 ], 1123 "Thanksgiving" : [ 'firstOctoberMonday', 7 ], 1124 "Remembrance Day" : [ 11, 11 ], 1125 "Christmas Day" : [ 12, 25 ], 1126 "Boxing Day" : [ 12, 26 ] 1127 }, 1128 }, 1129 'British Columbia': { 1130 'PH': { 1131 "New Year's Day" : [ 1, 1 ], 1132 "Family Day" : [ 'firstFebruaryMonday', 7 ], 1133 "Good Friday" : [ 'easter', -2 ], 1134 "Victoria Day" : [ 'victoriaDay', 0 ], 1135 "Canada Day" : [ 'canadaDay', 0 ], 1136 "British Columbia Day" : [ 'firstAugustMonday', 0 ], 1137 "Labour Day" : [ 'firstSeptemberMonday', 0 ], 1138 "Thanksgiving" : [ 'firstOctoberMonday', 7 ], 1139 "Remembrance Day" : [ 11, 11 ], 1140 "Christmas Day" : [ 12, 25 ] 1141 }, 1142 }, 1143 'Manitoba': { 1144 'PH': { 1145 "New Year's Day" : [ 1, 1 ], 1146 "Louis Riel Day" : [ 'firstFebruaryMonday', 14 ], 1147 "Good Friday" : [ 'easter', -2 ], 1148 "Victoria Day" : [ 'victoriaDay', 0 ], 1149 "Canada Day" : [ 'canadaDay', 0 ], 1150 "Civic Holiday" : [ 'firstAugustMonday', 0 ], 1151 "Labour Day" : [ 'firstSeptemberMonday', 0 ], 1152 "Thanksgiving" : [ 'firstOctoberMonday', 7 ], 1153 "Remembrance Day" : [ 11, 11 ], 1154 "Christmas Day" : [ 12, 25 ] 1155 }, 1156 }, 1157 'New Brunswick': { 1158 'PH': { 1159 "New Year's Day" : [ 1, 1 ], 1160 "Good Friday" : [ 'easter', -2 ], 1161 "Victoria Day" : [ 'victoriaDay', 0 ], 1162 "Canada Day" : [ 'canadaDay', 0 ], 1163 "New Brunswick Day" : [ 'firstAugustMonday', 0 ], 1164 "Labour Day" : [ 'firstSeptemberMonday', 0 ], 1165 "Thanksgiving" : [ 'firstOctoberMonday', 7 ], 1166 "Remembrance Day" : [ 11, 11 ], 1167 "Christmas Day" : [ 12, 25 ], 1168 "Boxing Day" : [ 12, 26 ] 1169 }, 1170 }, 1171 'Newfoundland and Labrador': { 1172 'PH': { 1173 "New Year's Day" : [ 1, 1 ], 1174 "Saint Patrick's Day" : [ 3, 17 ], 1175 "Good Friday" : [ 'easter', -2 ], 1176 "Saint George's Day" : [ 4, 23 ], 1177 "Discovery Day" : [ 6, 24 ], 1178 "Memorial Day" : [ 7, 1 ], 1179 "Orangemen's Day" : [ 7, 12 ], 1180 "Labour Day" : [ 'firstSeptemberMonday', 0 ], 1181 "Armistice Day" : [ 11, 11 ], 1182 "Christmas Day" : [ 12, 25 ] 1183 }, 1184 }, 1185 'Northwest Territories': { 1186 'PH': { 1187 "New Year's Day" : [ 1, 1 ], 1188 "Good Friday" : [ 'easter', -2 ], 1189 "Victoria Day" : [ 'victoriaDay', 0 ], 1190 "National Aboriginal Day" : [ 6, 21 ], 1191 "Canada Day" : [ 'canadaDay', 0 ], 1192 "Civic Holiday" : [ 'firstAugustMonday', 0 ], 1193 "Labour Day" : [ 'firstSeptemberMonday', 0 ], 1194 "Thanksgiving" : [ 'firstOctoberMonday', 7 ], 1195 "Remembrance Day" : [ 11, 11 ], 1196 "Christmas Day" : [ 12, 25 ] 1197 }, 1198 }, 1199 'Nova Scotia': { 1200 'PH': { 1201 "New Year's Day" : [ 1, 1 ], 1202 "Good Friday" : [ 'easter', -2 ], 1203 "Victoria Day" : [ 'victoriaDay', 0 ], 1204 "Canada Day" : [ 'canadaDay', 0 ], 1205 "Natal Day" : [ 'firstAugustMonday', 0 ], 1206 "Labour Day" : [ 'firstSeptemberMonday', 0 ], 1207 "Thanksgiving" : [ 'firstOctoberMonday', 7 ], 1208 "Remembrance Day" : [ 11, 11 ], 1209 "Christmas Day" : [ 12, 25 ], 1210 "Boxing Day" : [ 12, 26 ] 1211 }, 1212 }, 1213 'Nunavut': { 1214 'PH': { 1215 "New Year's Day" : [ 1, 1 ], 1216 "Good Friday" : [ 'easter', -2 ], 1217 "Victoria Day" : [ 'victoriaDay', 0 ], 1218 "Canada Day" : [ 'canadaDay', 0 ], 1219 "Nunavut Day" : [ 7, 9 ], 1220 "Civic Holiday" : [ 'firstAugustMonday', 0 ], 1221 "Labour Day" : [ 'firstSeptemberMonday', 0 ], 1222 "Thanksgiving" : [ 'firstOctoberMonday', 7 ], 1223 "Remembrance Day" : [ 11, 11 ], 1224 "Christmas Day" : [ 12, 25 ] 1225 }, 1226 }, 1227 'Ontario': { 1228 'PH': { 1229 "New Year's Day" : [ 1, 1 ], 1230 "Family Day" : [ 'firstFebruaryMonday', 14 ], 1231 "Good Friday" : [ 'easter', -2 ], 1232 "Victoria Day" : [ 'victoriaDay', 0 ], 1233 "Canada Day" : [ 'canadaDay', 0 ], 1234 "August Civic Public Holiday" : [ 'firstAugustMonday', 0 ], 1235 "Labour Day" : [ 'firstSeptemberMonday', 0 ], 1236 "Thanksgiving" : [ 'firstOctoberMonday', 7 ], 1237 "Remembrance Day" : [ 11, 11 ], 1238 "Christmas Day" : [ 12, 25 ], 1239 "Boxing Day" : [ 12, 26 ] 1240 }, 1241 }, 1242 'Prince Edward Island': { 1243 'PH': { 1244 "New Year's Day" : [ 1, 1 ], 1245 "Islander Day" : [ 'firstFebruaryMonday', 14 ], 1246 "Good Friday" : [ 'easter', -2 ], 1247 "Easter Monday" : [ 'easter', 1 ], 1248 "Victoria Day" : [ 'victoriaDay', 0 ], 1249 "Canada Day" : [ 'canadaDay', 0 ], 1250 "Civic Holiday" : [ 'firstAugustMonday', 0 ], 1251 "Gold Cup Parade Day" : [ 'firstAugustMonday', 18 ], 1252 "Labour Day" : [ 'firstSeptemberMonday', 0 ], 1253 "Thanksgiving" : [ 'firstOctoberMonday', 7 ], 1254 "Remembrance Day" : [ 11, 11 ], 1255 "Christmas Day" : [ 12, 25 ], 1256 "Boxing Day" : [ 12, 26 ] 1257 }, 1258 }, 1259 'Quebec': { 1260 'PH': { 1261 "Jour de l'an" : [ 1, 1 ], 1262 "Vendredi saint" : [ 'easter', -2 ], 1263 "Lundi de Pâques" : [ 'easter', 1 ], 1264 "Journée nationale des patriotes" : [ 'victoriaDay', 0 ], 1265 "Fête nationale du Québec" : [ 6, 24 ], 1266 "Fête du Canada" : [ 'canadaDay', 0 ], 1267 "Fête du Travail" : [ 'firstSeptemberMonday', 0 ], 1268 "Jour de l'Action de grâce" : [ 'firstOctoberMonday', 7 ], 1269 "Noël" : [ 12, 25 ] 1270 }, 1271 }, 1272 'Saskatchewan': { 1273 'PH': { 1274 "New Year's Day" : [ 1, 1 ], 1275 "Family Day" : [ 'firstFebruaryMonday', 14 ], 1276 "Good Friday" : [ 'easter', -2 ], 1277 "Victoria Day" : [ 'victoriaDay', 0 ], 1278 "Canada Day" : [ 'canadaDay', 0 ], 1279 "Saskatchewan Day" : [ 'firstAugustMonday', 0 ], 1280 "Labour Day" : [ 'firstSeptemberMonday', 0 ], 1281 "Thanksgiving" : [ 'firstOctoberMonday', 7 ], 1282 "Remembrance Day" : [ 11, 11 ], 1283 "Christmas Day" : [ 12, 25 ] 1284 }, 1285 }, 1286 'Yukon': { 1287 'PH': { 1288 "New Year's Day" : [ 1, 1 ], 1289 "Heritage Day" : [ 'lastFebruarySunday', -2 ], 1290 "Good Friday" : [ 'easter', -2 ], 1291 "Easter Monday" : [ 'easter', 1 ], 1292 "Victoria Day" : [ 'victoriaDay', 0 ], 1293 "Canada Day" : [ 'canadaDay', 0 ], 1294 "Discovery Day" : [ 'firstAugustMonday', 14 ], 1295 "Labour Day" : [ 'firstSeptemberMonday', 0 ], 1296 "Thanksgiving" : [ 'firstOctoberMonday', 7 ], 1297 "Remembrance Day" : [ 11, 11 ], 1298 "Christmas Day" : [ 12, 25 ], 1299 "Boxing Day" : [ 12, 26 ] 1300 }, 1301 }, 1302 }, 1303 'ua': { 1304 'PH': { // http://uk.wikipedia.org/wiki/%D0%A1%D0%B2%D1%8F%D1%82%D0%B0_%D1%82%D0%B0_%D0%BF%D0%B0%D0%BC%27%D1%8F%D1%82%D0%BD%D1%96_%D0%B4%D0%BD%D1%96_%D0%B2_%D0%A3%D0%BA%D1%80%D0%B0%D1%97%D0%BD%D1%96 1305 "Новий рік" : [ 1, 1 ], 1306 "Різдво" : [ 1, 7 ], 1307 "Міжнародний жіночий день" : [ 3, 8 ], 1308 "Великдень" : [ 'orthodox easter', 1 ], 1309 "День Праці 1" : [ 5, 1 ], 1310 "День Праці 2" : [ 5, 2 ], 1311 "День Перемоги" : [ 5, 9 ], 1312 "День Конституції України" : [ 6, 28 ], 1313 "День Незалежності України" : [ 8, 24 ], 1314 } 1315 }, 1316 'si': { 1317 'PH': { // http://www.vlada.si/o_sloveniji/politicni_sistem/prazniki/ 1318 'novo leto' : [ 1, 1 ], 1319 'Prešernov dan, slovenski kulturni praznik' : [ 2, 8 ], 1320 'velikonočna nedelja' : [ 'easter', 0 ], 1321 'velikonočni ponedeljek' : [ 'easter', 1 ], 1322 'dan upora proti okupatorju' : [ 4, 27 ], 1323 'praznik dela 1' : [ 5, 1 ], 1324 'praznik dela 2' : [ 5, 2 ], 1325 'binkoštna nedelja - binkošti' : [ 'easter', 49 ], 1326 'dan državnosti' : [ 6, 25 ], 1327 'Marijino vnebovzetje' : [ 8, 15 ], 1328 'dan reformacije' : [ 10, 31 ], 1329 'dan spomina na mrtve' : [ 11, 1 ], 1330 'božič' : [ 12, 25 ], 1331 'dan samostojnosti in enotnosti' : [ 12, 26 ], 1332 }, 1333 }, 1106 1334 }; 1107 1108 //---------------------------------------------------------------------------- 1109 // error correction1110 // 1111 // 1335 // }}} 1336 1337 // error correction {{{ 1338 // Taken form http://www.netzwolf.info/j/osm/time_domain.js 1339 // Credits go to Netzwolf 1112 1340 // 1113 // Key to word_error_correction is the token name except wrong_words 1114 //---------------------------------------------------------------------------- 1341 // Key to word_error_correction is the token name except wrong_words 1115 1342 var word_error_correction = { 1116 1343 wrong_words: { 1117 1344 'Assuming "<ok>" for "<ko>"': { 1118 spring: 'Mar-May', 1119 summer: 'Jun-Aug', 1120 autumn: 'Sep-Nov', 1121 winter: 'Dec-Feb', 1345 spring: 'Mar-May', 1346 summer: 'Jun-Aug', 1347 autumn: 'Sep-Nov', 1348 winter: 'Dec-Feb', 1349 // morning: '08:00-12:00', 1350 // evening: '13:00-18:00', 1351 '_': '-', 1352 'daytime': 'sunrise-sunset', 1122 1353 }, 'Bitte benutze die englische Schreibweise "<ok>" für "<ko>".': { 1123 1354 sommer: 'summer', 1355 'werktag': 'Mo-Fr', 1356 'werktags': 'Mo-Fr', 1124 1357 }, 'Bitte benutze "<ok>" für "<ko>". Beispiel: "Mo-Fr 08:00-12:00; Tu off"': { 1125 1358 ruhetag: 'off', 1126 1359 ruhetage: 'off', 1127 1360 geschlossen: 'off', 1361 ausser: 'off', 1362 außer: 'off', 1363 }, 'Neem de engelse afkorting "<ok>" voor "<ko>" alstublieft.': { 1364 'gesloten': 'off', 1365 'feestdag': 'PH', 1128 1366 }, 'Assuming "<ok>" for "<ko>". Please avoid using "workday": http://wiki.openstreetmap.org/wiki/Talk:Key:opening_hours#need_syntax_for_holidays_and_workingdays': { 1129 1367 // // Used around 260 times but the problem is, that work day might be different in other countries. 1130 wd: 'Mo-Fr', 1131 weekday: 'Mo-Fr', 1132 weekdays: 'Mo-Fr', 1368 'wd': 'Mo-Fr', 1369 'weekday': 'Mo-Fr', 1370 'weekdays': 'Mo-Fr', 1371 'vardagar': 'Mo-Fr', 1372 }, 'Please use notation something like "Mo off" instead "<ko>".': { 1373 except: 'off', 1133 1374 }, 'Please ommit "<ko>" or use a colon instead: "12:00-14:00".': { 1134 1375 h: '', … … 1138 1379 hrs: '', 1139 1380 hours: '', 1140 }, 'Please ommit "<ko>". You might want to express open end which can be specified as "12:00+" for example': { 1381 }, 'Please ommit "<ko>". The key must not be in the value.': { 1382 'opening_hours=': '', 1383 }, 'Please ommit "<ko>". You might want to express open end which can be specified as "12:00+" for example.': { 1141 1384 from: '', 1385 }, 'You can use notation "<ok>" for "<ko>". You might want to express open end which can be specified as "12:00+" for example.': { 1386 '-late': '+', 1142 1387 }, 'Please use notation "<ok>" for "<ko>". If the times are unsure or vary consider a comment e.g. 12:00-14:00 "only on sunshine".': { 1143 1388 '~': '-', 1144 1389 '~': '-', 1390 }, 'Please use notation "<ok>" for "<ko>". Fallback rule: 12:00-14:00 || "call us"': { 1391 'otherwise': '||', 1392 }, 'You can use notation "<ok>" for "<ko>" temporally if the syntax will still be valid.': { 1393 '?': 'unknown "please add this if known"', 1145 1394 }, 'Please use notation "<ok>" for "<ko>".': { 1395 '→': '-', 1146 1396 '–': '-', 1147 'ー': '-', 1397 '−': '-', 1398 '=': '-', 1399 'ー': '-', 1148 1400 to: '-', 1149 till: '-', 1401 'до': '-', 1402 a: '-', // language unknown 1403 as: '-', // language unknown 1404 'á': '-', // language unknown 1405 'ás': '-', // language unknown 1406 'à': '-', // language unknown 1407 'às': '-', // language unknown 1408 'ate': '-', // language unknown 1409 'till': '-', 1410 'til': '-', 1411 'until': '-', 1412 'through': '-', 1150 1413 and: ',', 1151 1414 '&': ',', 1152 1415 ':': ':', 1153 daily: 'Mo-Su', 1154 everyday: 'Mo-Su', 1416 '°°': ':00', 1417 'daily': 'Mo-Su', 1418 'everyday': 'Mo-Su', 1419 'every day': 'Mo-Su', 1155 1420 always: '24/7', 1156 1421 nonstop: '24/7', 1157 midnight: '00:00', 1422 '24x7': '24/7', 1423 'anytime': '24/7', 1424 'all day': '24/7', 1425 'all days': 'Mo-Su', 1426 'every day': 'Mo-Su', 1427 '7days': 'Mo-Su', 1428 '7j/7': 'Mo-Su', // I guess that it means that 1429 '7/7': 'Mo-Su', // I guess that it means that 1430 '7 days': 'Mo-Su', 1431 '7 days a week': 'Mo-Su', 1432 'midnight': '00:00', 1158 1433 holiday: 'PH', 1159 1434 holidays: 'PH', 1435 'public holidays': 'PH', 1436 'public holiday': 'PH', 1160 1437 // summerholiday: 'SH', 1161 1438 // summerholidays: 'SH', 1162 }, 'Please use time format in 24 hours notation ("<ko>").': { 1163 pm: '', 1164 am: '', 1439 weekend: 'Sa,Su', 1440 weekends: 'Sa,Su', 1441 'daylight': 'sunrise-sunset', 1442 'оff': 'off', // Russian o 1443 }, 'Please use time format in 24 hours notation ("<ko>"). If PM is used you might have to convert the hours to the 24 hours notation.': { 1444 'pm': '', 1445 'рм': '', 1446 'am': '', 1447 'ам': '', 1165 1448 }, 'Bitte verzichte auf "<ko>".': { 1166 uhr: '', 1449 'uhr': '', 1450 'geöffnet': '', 1167 1451 }, 'Bitte verzichte auf "<ko>". Sie möchten eventuell eine Öffnungszeit ohne vorgegebenes Ende angeben. Beispiel: "12:00+"': { 1168 1452 ab: '', … … 1183 1467 'et': ',', 1184 1468 'à': '-', 1469 'jours fériés': 'PH', 1185 1470 }, 'Neem de engelse afkorting "<ok>" voor "<ko>" alstublieft.': { 1186 1471 feestdag: 'PH', … … 1204 1489 dec: 11, 1205 1490 }, 'Please use the English abbreviation "<ok>" for "<ko>".': { 1491 'jänner': 0, // Austria 1206 1492 january: 0, 1207 1493 february: 1, … … 1281 1567 wednesdays: 3, 1282 1568 thu: 4, 1569 thur: 4, 1283 1570 thursday: 4, 1284 1571 thursdays: 4, … … 1294 1581 son: 0, 1295 1582 sonntag: 0, 1583 'sonn-': 0, 1296 1584 sonntags: 0, 1297 1585 montag: 1, … … 1334 1622 zo: 0, 1335 1623 zon: 0, 1336 zontag: 0, 1624 zontag: 0, // correct? 1625 zondag: 0, 1337 1626 maandag: 1, 1338 1627 din: 2, … … 1380 1669 'senin': 6, 1381 1670 // Swedish 1382 'söndag': 0, 1383 'måndag': 1, 1384 ma: 1, 1385 'tisdag': 2, 1386 'onsdag': 3, 1387 'torsdag': 4, 1388 'fredag': 5, 1389 'lördag': 6, 1671 'söndag': 0, 1672 'söndagar': 0, 1673 'måndag': 1, 1674 'ma': 1, 1675 'tisdag': 2, 1676 'onsdag': 3, 1677 'torsdag': 4, 1678 'fredag': 5, 1679 'lördag': 6, 1680 'lördagar': 6, 1390 1681 // Polish 1391 1682 'niedziela': 0, 'niedz': 0, 'n': 0, 'ndz': 0, … … 1396 1687 'piątek': 5, 'piatek': 5, 'pt': 5, 1397 1688 'sobota': 6, 'sob': 6, // 'so': 6 // abbreviation also used in German 1689 // Russian 1690 'воскресенье' : 0, 1691 'Вс' : 0, 1692 "voskresen'ye": 0, 1693 'понедельник' : 1, 1694 'Пн' : 1, 1695 "ponedel'nik" : 1, 1696 'вторник' : 2, 1697 'vtornik' : 2, 1698 'среда' : 3, 1699 'sreda' : 3, 1700 'четверг' : 4, 1701 'chetverk' : 4, 1702 'пятница' : 5, 1703 'pyatnitsa' : 5, 1704 'суббота' : 6, 1705 'subbota' : 6, 1706 // Danish 1707 'søndag' : 0, 1708 'mandag' : 1, 1709 'tirsdag': 2, 1710 'onsdag' : 3, 1711 'torsdag': 4, 1712 'fredag' : 5, 1713 'lørdag' : 6, 1398 1714 }, 1399 1715 }, … … 1401 1717 timevar: { // Special time variables which actual value depends on the date and the position of the facility. 1402 1718 'default': { 1403 sunrise: 'sunrise',1404 sunset: 'sunset',1405 dawn: 'dawn',1406 dusk: 'dusk',1719 'sunrise': 'sunrise', 1720 'sunset': 'sunset', 1721 'dawn': 'dawn', 1722 'dusk': 'dusk', 1407 1723 }, 'Please use notation "<ok>" for "<ko>".': { 1408 sundown:'sunset',1724 'sundown': 'sunset', 1409 1725 }, 'Bitte benutze die Schreibweise "<ok>" für "<ko>".': { 1410 1726 'morgendämmerung': 'dawn', 1411 1727 'abenddämmerung': 'dusk', 1412 sonnenaufgang:'sunrise',1413 sonnenuntergang: ',',1728 'sonnenaufgang': 'sunrise', 1729 'sonnenuntergang': 'sunset', 1414 1730 }, 1415 1731 }, … … 1417 1733 'event': { // variable events 1418 1734 'default': { 1419 easter: 'easter',1735 'easter': 'easter', 1420 1736 }, 'Bitte benutze die Schreibweise "<ok>" für "<ko>".': { 1421 ostern: 'easter',1737 'ostern': 'easter', 1422 1738 }, 1423 1739 }, 1424 1740 }; 1425 1741 // }}} 1742 // }}} 1743 1744 // make the library accessible for the outside world {{{ 1426 1745 if (typeof exports === 'object') { 1427 1746 // For nodejs … … 1432 1751 root.opening_hours = factory(root.SunCalc, holidays, word_error_correction); 1433 1752 } 1753 /// }}} 1434 1754 }(this, function (SunCalc, holidays, word_error_correction) { 1435 1755 return function(value, nominatiomJSON, oh_mode) { 1756 // short constants {{{ 1436 1757 var word_value_replacement = { // if the correct values can not be calculated 1437 1758 dawn : 60 * 5 + 30, … … 1456 1777 var msec_in_day = 1000 * 60 * minutes_in_day; 1457 1778 var msec_in_week = msec_in_day * 7; 1458 1779 // }}} 1780 1781 // The big picture -- How does this library work? {{{ 1459 1782 //====================================================================== 1460 1783 // Constructor - entry to parsing code … … 1476 1799 // - Tokenize 1477 1800 // Foreach block: 1478 // - Run top level (block) parser1479 // - Which calls sub parser for specific selector types1801 // - Run top-level (block) parser 1802 // - Which calls sub parser for specific selector types 1480 1803 // - Which produce selector functions 1481 1482 1804 // }}} 1805 1806 // constructor parameters {{{ 1483 1807 // Evaluate additional information which can be given. They are 1484 // required to reasonably calculate 'sunrise' and so on and to use the1485 // correctholidays.1808 // required to reasonably calculate 'sunrise' and to use the correct 1809 // holidays. 1486 1810 var location_cc, location_state, lat, lon; 1487 1811 if (typeof nominatiomJSON != 'undefined') { … … 1498 1822 } 1499 1823 1500 // 0: time ranges ( opening_hours, lit, …) default1501 // 1: points in time (collection_times, service_times, …)1502 // 2: both (time ranges and points in time) 1824 // 0: time ranges (default), tags: opening_hours, lit, … 1825 // 1: points in time 1826 // 2: both (time ranges and points in time), tags: collection_times, service_times 1503 1827 if (typeof oh_mode == 'undefined') { 1504 1828 oh_mode = 0; … … 1506 1830 throw 'The third constructor parameter is oh_mode and must be a number (0, 1 or 2)' 1507 1831 } 1508 1832 // }}} 1833 1834 // put tokenized blocks into list {{{ 1509 1835 if (value.match(/^(\s*;?\s*)+$/)) 1510 1836 throw 'Value contains nothing meaningful which can be parsed'; … … 1516 1842 // console.log(JSON.stringify(tokens, null, '\t')); 1517 1843 var prettified_value = ''; 1518 var used_subparsers = {}; // Used sub parsers for one block, will be asdreset for each block. Declared as global, because it is manipulation inside muchsub parsers.1844 var used_subparsers = {}; // Used sub parsers for one block, will be reset for each block. Declared as global, because it is manipulation inside various sub parsers. 1519 1845 var week_stable = true; 1520 1846 … … 1576 1902 selectors.date.push(selectors.weekday); 1577 1903 1904 // console.log('weekday: ' + JSON.stringify(selectors.weekday, null, '\t')); 1578 1905 blocks.push(selectors); 1579 1906 … … 1605 1932 } while (continue_at) 1606 1933 } 1607 1608 // Tokenization function: Splits string into parts. 1934 // }}} 1935 1936 // Tokenization function: Splits string into parts. {{{ 1609 1937 // output: array of arrays of pairs [content, type] 1610 1938 function tokenize(value) { … … 1616 1944 while (value != '') { 1617 1945 var tmp; 1618 if (tmp = value.match(/^(?:week\b|open |unknown)/i)) {1946 if (tmp = value.match(/^(?:week\b|open\b|unknown)/i)) { 1619 1947 // reserved word 1620 1948 curr_block_tokens.push([tmp[0].toLowerCase(), tmp[0].toLowerCase(), value.length ]); … … 1636 1964 curr_block_tokens.push([tmp[0].toLowerCase(), 'calcday', value.length ]); 1637 1965 value = value.substr(tmp[0].length); 1638 } else if (tmp = value.match(/^(&| –|ー|~|~|:|[a-zA-ZäÄàÀéÉ]+\b)\.?/i)) {1966 } else if (tmp = value.match(/^(&|_|→|–|−|=|opening_hours=|ー|\?|~|~|:|°°|25x7|7[ ]?days( a week|)|all days?|every day|-late|public holidays?|7j?\/7|every day|до|рм|ам|jours fériés|sonn-|[a-zäößàáéøčěíúýřПнВсо]+\b)\.?/i)) { 1639 1967 // Handle all remaining words with error tolerance 1640 1968 var correct_val = returnCorrectWordOrToken(tmp[1].toLowerCase(), value.length); … … 1702 2030 return all_tokens; 1703 2031 } 1704 1705 // error correction/tolerance 2032 // }}} 2033 2034 // error correction/tolerance function {{{ 2035 // Go through word_error_correction hash and get correct value back. 1706 2036 function returnCorrectWordOrToken(word, value_length) { 1707 2037 for (var token_name in word_error_correction) { … … 1718 2048 for (correct_abbr in word_error_correction[token_name]['default']) { 1719 2049 if (word_error_correction[token_name]['default'][correct_abbr] == val) 1720 break; 2050 break; // FIXME 1721 2051 } 2052 // FIXME 1722 2053 if (token_name != 'timevar') { // normally written in lower case 1723 2054 correct_abbr = correct_abbr.charAt(0).toUpperCase() + correct_abbr.slice(1); … … 1733 2064 } 1734 2065 } 1735 2066 // }}} 2067 2068 // return warnings as list {{{ 1736 2069 function getWarnings(it) { 1737 1738 2070 if (typeof it == 'object') { // getWarnings was called in a state without critical errors. We can do extended tests. 1739 2071 1740 // Check if 24/7 is used and it does not mean 24/7 because there are other rules. This can be avoided.2072 // Check if 24/7 is used and it does not mean 24/7 because there are other blocks. 1741 2073 var has_advanced = it.advance(); 1742 2074 … … 1756 2088 return warnings; 1757 2089 } 1758 1759 // Function to check token array for specific pattern 2090 // }}} 2091 2092 // Function to check token array for specific pattern {{{ 1760 2093 function matchTokens(tokens, at /*, matches... */) { 1761 2094 if (at + arguments.length - 2 > tokens.length) … … 1768 2101 return true; 1769 2102 } 1770 2103 // }}} 2104 2105 // Generate selector wrapper with time offset {{{ 1771 2106 function generateDateShifter(func, shift) { 1772 2107 return function(date) { … … 1778 2113 } 1779 2114 } 1780 1781 //====================================================================== 1782 // Top-level parser 1783 //====================================================================== 2115 // }}} 2116 2117 // Top-level parser {{{ 1784 2118 function parseGroup(tokens, at, selectors, nblock, conf) { 1785 2119 var prettified_group_value = ''; … … 1793 2127 at = parseWeekdayRange(tokens, at, selectors); 1794 2128 } else if (matchTokens(tokens, at, '24/7')) { 1795 //selectors.time.push(function(date) { return [true]; });2129 selectors.time.push(function(date) { return [true]; }); 1796 2130 // Not needed. If there is no selector it automatically matches everything. 2131 // WRONG: This only works if there is no other selector in this selector group ... 1797 2132 at++; 1798 2133 } else if (matchTokens(tokens, at, 'holiday')) { … … 1826 2161 // This provides compatibility with the syntax proposed by Netzwolf: 1827 2162 // http://wiki.openstreetmap.org/wiki/Key:opening_hours:specification 1828 if (!done_with_warnings && matchTokens(tokens, at-1, 'weekday') || matchTokens(tokens, at-1, 'holiday'))2163 if (!done_with_warnings && (matchTokens(tokens, at-1, 'weekday') || matchTokens(tokens, at-1, 'holiday'))) 1829 2164 parsing_warnings.push([nblock, at, 'Please don’t use ":" after ' + tokens[at-1][1] + '.']); 1830 2165 … … 1836 2171 || matchTokens(tokens, at, '(', 'timevar') 1837 2172 || matchTokens(tokens, at, 'number', '-')) { 1838 at = parseTimeRange(tokens, at, selectors );2173 at = parseTimeRange(tokens, at, selectors, false); 1839 2174 1840 2175 used_subparsers['time ranges'].push(at); … … 1881 2216 } 1882 2217 } else { // block starts with comment 1883 //selectors.time.push(function(date) { return [true]; });2218 selectors.time.push(function(date) { return [true]; }); 1884 2219 // Not needed. If there is no selector it automatically matches everything. 2220 // WRONG: This only works if there is no other selector in this selector group ... 1885 2221 selectors.meaning = false; 1886 2222 selectors.unknown = true; … … 1935 2271 + ' Equal selector types can (and should) always be written in conjunction separated by comma or something.' 1936 2272 + ' Example for time ranges "12:00-13:00,15:00-18:00".' 2273 + ' Example for weekdays "Mo-We,Fr".' 1937 2274 ) 1938 2275 + ' Rules can be separated by ";".' ] … … 1944 2281 return at; 1945 2282 } 1946 1947 //====================================================================== 1948 // Time range parser (10:00-12:00,14:00-16:00) 1949 //====================================================================== 1950 function parseTimeRange(tokens, at, selectors) { 2283 // }}} 2284 2285 // helper functions for sub parser {{{ 2286 // for given date, returns date moved to the start of specified day minute 2287 function dateAtDayMinutes(date, minutes) { 2288 return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, minutes); 2289 } 2290 2291 // for given date, returns date moved to the specific day of week 2292 function dateAtNextWeekday(date, day) { 2293 var delta = day - date.getDay(); 2294 return new Date(date.getFullYear(), date.getMonth(), date.getDate() + delta + (delta < 0 ? 7 : 0)); 2295 } 2296 2297 function indexOf(needle) { 2298 if(typeof Array.prototype.indexOf === 'function') { 2299 indexOf = Array.prototype.indexOf; 2300 } else { 2301 indexOf = function(needle) { 2302 var i = -1, index = -1; 2303 for(i = 0; i < this.length; i++) { 2304 if(this[i] === needle) { 2305 index = i; 2306 break; 2307 } 2308 } 2309 return index; 2310 }; 2311 } 2312 return indexOf.call(this, needle); 2313 } 2314 2315 // Numeric list parser (1,2,3-4,-1), used in weekday parser above 2316 function parseNumRange(tokens, at, func) { 2317 for (; at < tokens.length; at++) { 2318 if (matchTokens(tokens, at, 'number', '-', 'number')) { 2319 // Number range 2320 func(tokens[at][0], tokens[at+2][0], at); 2321 at += 3; 2322 } else if (matchTokens(tokens, at, '-', 'number')) { 2323 // Negative number 2324 func(-tokens[at+1][0], -tokens[at+1][0], at); 2325 at += 2 2326 } else if (matchTokens(tokens, at, 'number')) { 2327 // Single number 2328 func(tokens[at][0], tokens[at][0], at); 2329 at++; 2330 } else { 2331 throw formatWarnErrorMessage(nblock, at + matchTokens(tokens, at, '-'), 2332 'Unexpected token in number range: ' + tokens[at][1]); 2333 } 2334 2335 if (!matchTokens(tokens, at, ',')) 2336 break; 2337 } 2338 2339 return at; 2340 } 2341 2342 function getConstrainedWeekday(tokens, at) { 2343 var number = 0; 2344 var endat = parseNumRange(tokens, at, function(from, to, at) { 2345 2346 // bad number 2347 if (from == 0 || from < -5 || from > 5) 2348 throw formatWarnErrorMessage(nblock, at, 2349 'Number between -5 and 5 (except 0) expected'); 2350 2351 if (from == to) { 2352 if (number != 0) 2353 throw formatWarnErrorMessage(nblock, at, 2354 'You can not use a more than one constrained weekday in a month range'); 2355 number = from; 2356 } else { 2357 throw formatWarnErrorMessage(nblock, at+2, 2358 'You can not use a range of constrained weekdays in a month range'); 2359 } 2360 }); 2361 2362 if (!matchTokens(tokens, endat, ']')) 2363 throw formatWarnErrorMessage(nblock, endat, '"]" expected.'); 2364 2365 return [ number, endat + 1 ]; 2366 } 2367 2368 // Check if period is ok. Period 0 or 1 don’t make much sense. 2369 function checkPeriod(at, period, period_type, parm_string) { 2370 if (done_with_warnings) 2371 return; 2372 2373 if (period === 0) { 2374 throw formatWarnErrorMessage(nblock, at, 2375 'You can not use '+ period_type +' ranges with period equals zero.'); 2376 } else if (period === 1) { 2377 if (typeof parm_string == 'string' && parm_string == 'no_end_year') 2378 parsing_warnings.push([nblock, at, 2379 'Please don’t use '+ period_type +' ranges with period equals one.' 2380 + ' If you want to express that a facility is open starting from a year without limit use "<year>+".']); 2381 else 2382 parsing_warnings.push([nblock, at, 2383 'Please don’t use '+ period_type +' ranges with period equals one.']); 2384 } 2385 } 2386 2387 function getDateForConstrainedWeekday(year, month, weekday, constrained_weekday, add_days) { 2388 var tmp_date = dateAtNextWeekday( 2389 new Date(year, month + (constrained_weekday[0] > 0 ? 0 : 1), 1), weekday); 2390 2391 tmp_date.setDate(tmp_date.getDate() + (constrained_weekday[0] + (constrained_weekday[0] > 0 ? -1 : 0)) * 7); 2392 2393 if (typeof add_days != 'undefined' && add_days[1]) 2394 tmp_date.setDate(tmp_date.getDate() + add_days[0]); 2395 2396 return tmp_date; 2397 } 2398 2399 function formatWarnErrorMessage(nblock, at, message) { 2400 var pos = 0; 2401 if (nblock == -1) { // Usage of block index not required because we do have access to value.length. 2402 pos = value.length - at; 2403 } else { // Issue accrued at a later time, position in string needs to be reconstructed. 2404 if (typeof tokens[nblock][0][at] == 'undefined') { 2405 pos = value.length; 2406 if (typeof tokens[nblock][0][tokens[nblock][0].length-1] != 'undefined') { 2407 // pos -= tokens[nblock][0][tokens[nblock][0].length-1][2]; 2408 console.warn("FIXME"); 2409 } 2410 } else { 2411 pos = value.length; 2412 if (typeof tokens[nblock][0][at+1] != 'undefined') { 2413 pos -= tokens[nblock][0][at+1][2]; 2414 } else if (typeof tokens[nblock][2] != 'undefined') { 2415 pos -= tokens[nblock][2]; 2416 } else { 2417 } 2418 } 2419 } 2420 return value.substring(0, pos) + ' <--- (' + message + ')'; 2421 } 2422 2423 // check if date is valid 2424 function isValidDate(month, day, nblock, at) { 2425 // month == 0 is Jan 2426 2427 // May use this instead. Does not say, what is wrong as good was implementation below. 2428 // var testDate = new Date(year, month, day); 2429 // if (testDate.getDate() != day || testDate.getMonth() != month || testDate.getFullYear() != year) { 2430 // console.error('date not valid'); 2431 // } 2432 2433 // https://en.wikipedia.org/wiki/Month#Julian_and_Gregorian_calendars 2434 if (day < 1 || day > 31) 2435 throw formatWarnErrorMessage(nblock, at, 'Day must be between 1 and 31.'); 2436 if ((month==3 || month==5 || month==8 || month==10) && day==31) 2437 throw formatWarnErrorMessage(nblock, at, 'Month ' + months[month] + " doesn't have 31 days.!"); 2438 if (month == 1 && day == 30) 2439 throw formatWarnErrorMessage(nblock, at, 'Month ' + months[1]+ " either has 28 or 29 days (leap years)."); 2440 } 2441 // }}} 2442 2443 // Time range parser (10:00-12:00,14:00-16:00) {{{ 2444 // 2445 // extended_open_end: <time> - <time> + 2446 // at is here A (if extended_open_end is true) 2447 function parseTimeRange(tokens, at, selectors, extended_open_end) { 1951 2448 for (; at < tokens.length; at++) { 1952 2449 var has_time_var_calc = [], has_normal_time = []; // element 0: start time, 1: end time … … 1959 2456 var has_open_end = false; // default no open end 1960 2457 var timevar_add = [ 0, 0 ]; 1961 var timevar_string = [];// capture timevar string like 'sunrise' to calculate it for the current date.2458 var timevar_string = []; // capture timevar string like 'sunrise' to calculate it for the current date. 1962 2459 1963 2460 // minutes_from … … 1980 2477 } else { 1981 2478 if (oh_mode == 0) { 1982 throw formatWarnErrorMessage(nblock, at+(has_normal_time[0] ? 3 : (has_time_var_calc[0] ? 2 : 1)), 2479 throw formatWarnErrorMessage(nblock, at+( 2480 has_normal_time[0] ? ( 2481 typeof tokens[at+3] == 'object' ? 3 : 2 2482 ) : ( 2483 has_time_var_calc[0] ? 2 : 1 2484 ) 2485 ), 1983 2486 'hyphen (-) or open end (+) in time range ' 1984 2487 + (has_time_var_calc[0] ? 'calculation ' : '') + 'expected.' … … 2041 2544 2042 2545 is_point_in_time = true; 2546 } else if (matchTokens(tokens, at, '+')) { 2547 parseTimeRange(tokens, at_end_time, selectors, true); 2548 at++; 2043 2549 } else if (oh_mode == 1 && !is_point_in_time) { 2044 2550 throw formatWarnErrorMessage(nblock, at_end_time, … … 2054 2560 2055 2561 // normalize minutes into range 2056 if ( minutes_from >= minutes_in_day)2562 if (!extended_open_end && minutes_from >= minutes_in_day) 2057 2563 throw formatWarnErrorMessage(nblock, at_end_time - 1, 2058 2564 'Time range starts outside of the current day'); … … 2060 2566 minutes_to += minutes_in_day; 2061 2567 if (minutes_to > minutes_in_day * 2) 2062 throw formatWarnErrorMessage(nblock, at_end_time + (has_normal_time[1] ? 3 : (has_time_var_calc[1] ? 7 : 1)) - 1,2568 throw formatWarnErrorMessage(nblock, at_end_time + (has_normal_time[1] ? 4 : (has_time_var_calc[1] ? 7 : 1)) - 2, 2063 2569 'Time spanning more than two midnights not supported'); 2064 2570 … … 2176 2682 }}(minutes_from, minutes_to, timevar_string, timevar_add, has_open_end, is_point_in_time, point_in_time_period)); 2177 2683 } 2684 } else { 2685 selectors.time.push(function(date) { return [true]; }); 2178 2686 } 2179 } else if (matchTokens(tokens, at, 'number', '-', 'number')) { // "Mo 09-18" -> "Mo 09:00-18:00". Please don’t use this 2687 2688 } else if (matchTokens(tokens, at, 'number', '-', 'number')) { // "Mo 09-18" (Please don’t use this) -> "Mo 09:00-18:00". 2180 2689 var minutes_from = tokens[at][0] * 60; 2181 2690 var minutes_to = tokens[at+2][0] * 60; … … 2227 2736 } else { // additional block 2228 2737 if (matchTokens(tokens, at, '(')) 2229 throw formatWarnErrorMessage(nblock, at +1, 'Missing variable time (e.g. sunrise) after: "' + tokens[at][1] + '"');2738 throw formatWarnErrorMessage(nblock, at, 'Missing variable time (e.g. sunrise) after: "' + tokens[at][1] + '"'); 2230 2739 if (matchTokens(tokens, at, 'number', 'timesep')) 2231 2740 throw formatWarnErrorMessage(nblock, at+2, 'Missing minutes in time range after: "' + tokens[at+1][1] + '"'); … … 2242 2751 } 2243 2752 2244 // for given date, returns date moved to the start of specified day minute 2245 function dateAtDayMinutes(date, minutes) { 2246 return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, minutes); 2247 } 2248 2249 // extract the added or subtracted time of "(sunrise-01:30)" 2250 // returns in minutes e.g. -90 2753 // get time in minutes from <hour>:<minute> {{{ 2754 // Only used if throwing an error is wanted. 2755 function getMinutesByHoursMinutes(tokens, nblock, at) { 2756 if (tokens[at+2][0] > 59) 2757 throw formatWarnErrorMessage(nblock, at+2, 2758 'Minutes are greater than 59.'); 2759 return tokens[at][0] * 60 + tokens[at+2][0]; 2760 } 2761 // }}} 2762 2763 // get time in minutes from "(sunrise-01:30)" {{{ 2764 // Extract the added or subtracted time from "(sunrise-01:30)" 2765 // returns time in minutes e.g. -90 2251 2766 function parseTimevarCalc(tokens, at) { 2252 2767 if (matchTokens(tokens, at+2, '+') || matchTokens(tokens, at+2, '-')) { … … 2254 2769 if (matchTokens(tokens, at+6, ')')) { 2255 2770 var add_or_subtract = tokens[at+2][0] == '+' ? '1' : '-1'; 2256 var minutes = (tokens[at+3][0] * 60 + tokens[at+5][0]) * add_or_subtract;2771 var minutes = getMinutesByHoursMinutes(tokens, nblock, at+3) * add_or_subtract; 2257 2772 if (minutes == 0) 2258 2773 parsing_warnings.push([ nblock, at+5, 'Adding zero in a variable time calculation does not change the variable time.' … … 2274 2789 'Calculcation with variable time is not in the right syntax' + error[1]); 2275 2790 } 2276 2277 // Only used if throwing an error is wanted. 2278 function getMinutesByHoursMinutes(tokens, nblock, at) { 2279 if (tokens[at+2][0] > 59) 2280 throw formatWarnErrorMessage(nblock, at+2, 2281 'Minutes are greater than 59.'); 2282 return tokens[at][0] * 60 + tokens[at+2][0]; 2283 } 2284 2285 //====================================================================== 2286 // Weekday range parser (Mo,We-Fr,Sa[1-2,-1]) 2287 //====================================================================== 2791 // }}} 2792 // }}} 2793 2794 // Weekday range parser (Mo,We-Fr,Sa[1-2,-1],PH) {{{ 2288 2795 function parseWeekdayRange(tokens, at, selectors) { 2289 2796 for (; at < tokens.length; at++) { … … 2422 2929 2423 2930 if (weekday_to < weekday_from) { // handle full range 2424 //selectors.weekday.push(function(date) { return [true]; });2931 selectors.weekday.push(function(date) { return [true]; }); 2425 2932 // Not needed. If there is no selector it automatically matches everything. 2933 // WRONG: This only works if there is no other selector in this selector group ... 2426 2934 } else { 2427 2935 selectors.weekday.push(function(weekday_from, weekday_to, inside) { return function(date) { … … 2452 2960 else 2453 2961 used_subparsers['weekdays'].push(at); 2454 2455 return at;2456 }2457 2458 // Numeric list parser (1,2,3-4,-1), used in weekday parser above2459 function parseNumRange(tokens, at, func) {2460 for (; at < tokens.length; at++) {2461 if (matchTokens(tokens, at, 'number', '-', 'number')) {2462 // Number range2463 func(tokens[at][0], tokens[at+2][0], at);2464 at += 3;2465 } else if (matchTokens(tokens, at, '-', 'number')) {2466 // Negative number2467 func(-tokens[at+1][0], -tokens[at+1][0], at);2468 at += 22469 } else if (matchTokens(tokens, at, 'number')) {2470 // Single number2471 func(tokens[at][0], tokens[at][0], at);2472 at++;2473 } else {2474 throw formatWarnErrorMessage(nblock, at + matchTokens(tokens, at, '-'),2475 'Unexpected token in number range: ' + tokens[at][1]);2476 }2477 2478 if (!matchTokens(tokens, at, ','))2479 break;2480 }2481 2962 2482 2963 return at; … … 2500 2981 return add_days; 2501 2982 } 2502 2503 2504 // for given date, returns date moved to the specific day of week 2505 function dateAtNextWeekday(date, day) { 2506 var delta = day - date.getDay(); 2507 return new Date(date.getFullYear(), date.getMonth(), date.getDate() + delta + (delta < 0 ? 7 : 0)); 2508 } 2509 2510 //====================================================================== 2511 // Holiday parser for public and school holidays (PH,SH) 2983 // }}} 2984 2985 // Holiday parser for public and school holidays (PH,SH) {{{ 2512 2986 // push_to_weekday will push the selector into the weekday selector array which has the desired side effect of working in conjunction with the weekday selectors (either the holiday match or the weekday), which is the normal and expected behavior. 2513 //======================================================================2514 2987 function parseHoliday(tokens, at, selectors, push_to_weekday) { 2515 2988 for (; at < tokens.length; at++) { … … 2661 3134 } 2662 3135 3136 // Helpers for holiday parsers {{{ 2663 3137 // Returns a number for a date which can then be used to compare just the dates (without the time). 2664 3138 // This is necessary because a selector could be called for the middle of the day and we need to tell if it matches that day. … … 2746 3220 var D = L + 28 - 31*Math.floor(M/4); 2747 3221 3222 // calculate orthodox easter 3223 var oA = Y % 4; 3224 var oB = Y % 7; 3225 var oC = Y % 19; 3226 var oD = (19*oC + 15) % 30; 3227 var oE = (2*oA+4*oB - oD + 34) % 7; 3228 var oF = oD+oE 3229 3230 if (oF < 9) {oDate = new Date(Y, 4-1, oF+4);} 3231 else {if ((oF+4)<31) {oDate = new Date(Y, 4-1, oF+4);} 3232 else {oDate = new Date(Y, 5-1, oF-26);}} 3233 3234 // calculate last Sunday in February 3235 var lastFebruaryDay = new Date(Y, 2, 0); 3236 var lastFebruarySunday = lastFebruaryDay.getDate() - lastFebruaryDay.getDay(); 3237 3238 // calculate Victoria Day. last Monday before or on May 24 3239 var may_24 = new Date(Y, 4, 24); 3240 var victoriaDay = 24 - ((6 + may_24.getDay()) % 7); 3241 3242 // calculate Canada Day. July 1st unless 1st is on Sunday, then July 2. 3243 var july_1 = new Date(Y, 6, 1); 3244 var canadaDay = july_1.getDay() === 0 ? 2 : 1; 3245 3246 // calculate first Monday for each month 3247 var firstMondays = {}; 3248 for (var i = 0; i < 12; i++) { 3249 var first = new Date(Y, i, 1); 3250 var firstMonday = 1 + ((8 - first.getDay()) % 7); 3251 firstMondays[i] = firstMonday; 3252 }; 3253 2748 3254 return { 3255 'firstFebruaryMonday': new Date(Y, 1, firstMondays[1]), 3256 'lastFebruarySunday': new Date(Y, 1, lastFebruarySunday), 2749 3257 'easter': new Date(Y, M - 1, D), 3258 'victoriaDay': new Date(Y, 4, victoriaDay), 3259 'canadaDay': new Date(Y, 6, canadaDay), 3260 'firstAugustMonday': new Date(Y, 7, firstMondays[7]), 3261 'firstSeptemberMonday': new Date(Y, 8, firstMondays[8]), 3262 'firstOctoberMonday': new Date(Y, 9, firstMondays[9]), 3263 'orthodox easter' : oDate, 2750 3264 }; 2751 }2752 2753 function indexOf(needle) {2754 if(typeof Array.prototype.indexOf === 'function') {2755 indexOf = Array.prototype.indexOf;2756 } else {2757 indexOf = function(needle) {2758 var i = -1, index = -1;2759 for(i = 0; i < this.length; i++) {2760 if(this[i] === needle) {2761 index = i;2762 break;2763 }2764 }2765 return index;2766 };2767 }2768 return indexOf.call(this, needle);2769 3265 } 2770 3266 … … 2809 3305 return sorted_holidays; 2810 3306 } 2811 2812 // ======================================================================2813 // Year range parser (2013,2016-2018,2020/2) 2814 // ======================================================================3307 // }}} 3308 // }}} 3309 3310 // Year range parser (2013,2016-2018,2020/2) {{{ 2815 3311 function parseYearRange(tokens, at) { 2816 3312 for (; at < tokens.length; at++) { … … 2820 3316 var is_range = true; 2821 3317 var has_period = true; 2822 if (!done_with_warnings && tokens[at+4][0] == 1)2823 parsing_warnings.push([nblock, at+1+3, 'Please don’t use year ranges with period equals one (see README)']);3318 var period = parseInt(tokens[at+4][0]); 3319 checkPeriod(at+4, period, 'year'); 2824 3320 } else { 2825 3321 var is_range = matchTokens(tokens, at+1, '-', 'year'); 2826 3322 var has_period = matchTokens(tokens, at+1, '/', 'number'); 3323 if (has_period) { 3324 var period = parseInt(tokens[at+2][0]); 3325 checkPeriod(at+2, period, 'year', 'no_end_year'); 3326 } else if (matchTokens(tokens, at+1, '+')) { 3327 var period = 1; 3328 has_period = 2; 3329 } 2827 3330 } 2828 3331 2829 selectors.year.push(function(tokens, at, is_range, has_period) { return function(date) { 3332 var year_from = parseInt(tokens[at][0]); 3333 // error checking {{{ 3334 if (is_range && tokens[at+2][0] <= year_from) { 3335 // handle reversed range 3336 if (tokens[at+2][0] == year_from) 3337 throw formatWarnErrorMessage(nblock, at, 3338 'A year range in which the start year is equal to the end year does not make sense.' 3339 + ' Please remove the end year. E.g. "' + year_from + ' May 23"'); 3340 else 3341 throw formatWarnErrorMessage(nblock, at, 3342 'A year range in which the start year is greater than the end year does not make sense.' 3343 + ' Please turn it over.'); 3344 } 3345 // }}} 3346 3347 selectors.year.push(function(tokens, at, year_from, is_range, has_period, period) { return function(date) { 2830 3348 var ouryear = date.getFullYear(); 2831 var year_from = tokens[at][0]; 2832 var year_to = is_range ? tokens[at+2][0] : year_from; 2833 2834 // handle reversed range 2835 if (year_to < year_from) { 2836 var tmp = year_to; 2837 year_to = year_from; 2838 year_from = tmp; 2839 } 3349 var year_to = is_range ? parseInt(tokens[at+2][0]) : year_from; 2840 3350 2841 3351 if (ouryear < year_from ){ … … 2843 3353 } else if (has_period) { 2844 3354 if (year_from <= ouryear) { 2845 if (is_range) { 2846 var period = tokens[at+4][0]; 2847 2848 if (year_to < ouryear) 2849 return [false]; 2850 } else { 2851 var period = tokens[at+2][0]; 2852 } 3355 if (is_range && year_to < ouryear) 3356 return [false]; 2853 3357 if (period > 0) { 2854 3358 if ((ouryear - year_from) % period == 0) { … … 2860 3364 } 2861 3365 } else if (is_range) { 2862 if ( year_from <= ouryear &&ouryear <= year_to)3366 if (ouryear <= year_to) 2863 3367 return [true, new Date(year_to + 1, 0, 1)]; 2864 3368 } else if (ouryear == year_from) { … … 2868 3372 return [false]; 2869 3373 2870 }}(tokens, at, is_range, has_period));2871 2872 at += 1 + (is_range ? 2 : 0) + (has_period ? 2: 0);3374 }}(tokens, at, year_from, is_range, has_period, period)); 3375 3376 at += 1 + (is_range ? 2 : 0) + (has_period ? (has_period == 2 ? 1 : 2) : 0); 2873 3377 } else { 2874 3378 throw formatWarnErrorMessage(nblock, at, 'Unexpected token in year range: ' + tokens[at][1]); … … 2886 3390 return at; 2887 3391 } 2888 2889 //====================================================================== 2890 // Week range parser (week 11-20, week 1-53/2) 2891 //====================================================================== 3392 // }}} 3393 3394 // Week range parser (week 11-20, week 1-53/2) {{{ 2892 3395 function parseWeekRange(tokens, at) { 2893 3396 for (; at < tokens.length; at++) { … … 2972 3475 return date; 2973 3476 } 2974 2975 //====================================================================== 2976 // Month range parser (Jan,Feb-Mar) 2977 // ======================================================================2978 function parseMonthRange(tokens, at ) {3477 // }}} 3478 3479 // Month range parser (Jan,Feb-Mar) {{{ 3480 // push_to_monthday will push the selector into the monthday selector array which has the desired side effect of working in conjunction with the monthday selectors (either the month match or the monthday). 3481 function parseMonthRange(tokens, at, push_to_monthday) { 2979 3482 for (; at < tokens.length; at++) { 2980 if (matchTokens(tokens, at, 'month')) { 3483 // Use parseMonthdayRange if '<month> <daynum>' and not '<month> <hour>:<minute>' 3484 if (matchTokens(tokens, at, 'month', 'number') && !matchTokens(tokens, at+2, 'timesep', 'number')) { 3485 return parseMonthdayRange(tokens, at, nblock, true); 3486 } else if (matchTokens(tokens, at, 'month')) { 2981 3487 // Single month (Jan) or month range (Feb-Mar) 2982 3488 var is_range = matchTokens(tokens, at+1, '-', 'month'); … … 2993 3499 } 2994 3500 2995 selectors.month.push(function(tokens, at, is_range) { return function(date) {3501 var selector = function(tokens, at, is_range) { return function(date) { 2996 3502 var ourmonth = date.getMonth(); 2997 3503 var month_from = tokens[at][0]; … … 3017 3523 return [inside, dateAtNextMonth(date, month_to + 1)]; 3018 3524 } 3019 }}(tokens, at, is_range)); 3525 }}(tokens, at, is_range); 3526 3527 if (push_to_monthday === true) 3528 selectors.monthday.push(selector); 3529 else 3530 selectors.month.push(selector); 3020 3531 3021 3532 at += is_range ? 3 : 1; … … 3039 3550 return new Date(date.getFullYear(), month < date.getMonth() ? month + 12 : month); 3040 3551 } 3041 3042 function getConstrainedWeekday(tokens, at) { 3043 var number = 0; 3044 var endat = parseNumRange(tokens, at, function(from, to, at) { 3045 3046 // bad number 3047 if (from == 0 || from < -5 || from > 5) 3048 throw formatWarnErrorMessage(nblock, at, 3049 'Number between -5 and 5 (except 0) expected'); 3050 3051 if (from == to) { 3052 if (number != 0) 3053 throw formatWarnErrorMessage(nblock, at, 3054 'You can not use a more than one constrained weekday in a month range'); 3055 number = from; 3056 } else { 3057 throw formatWarnErrorMessage(nblock, at+2, 3058 'You can not use a range of constrained weekdays in a month range'); 3059 } 3060 }); 3061 3062 if (!matchTokens(tokens, endat, ']')) 3063 throw formatWarnErrorMessage(nblock, endat, '"]" expected.'); 3064 3065 return [ number, endat + 1 ]; 3066 } 3067 3068 function getDateForConstrainedWeekday(year, month, weekday, constrained_weekday, add_days) { 3069 var tmp_date = dateAtNextWeekday( 3070 new Date(year, month + (constrained_weekday[0] > 0 ? 0 : 1), 1), weekday); 3071 3072 tmp_date.setDate(tmp_date.getDate() + (constrained_weekday[0] + (constrained_weekday[0] > 0 ? -1 : 0)) * 7); 3073 3074 if (typeof add_days != 'undefined' && add_days[1]) 3075 tmp_date.setDate(tmp_date.getDate() + add_days[0]); 3076 3077 return tmp_date; 3078 } 3079 3080 //====================================================================== 3081 // Month day range parser (Jan 26-31; Jan 26-Feb 26) 3082 //====================================================================== 3083 function parseMonthdayRange(tokens, at, nblock) { 3552 // }}} 3553 3554 // Month day range parser (Jan 26-31; Jan 26-Feb 26) {{{ 3555 // push_to_month will push the selector into the month selector array which has the desired side effect of working in conjunction with the month selectors (either the month match or the monthday). 3556 function parseMonthdayRange(tokens, at, nblock, push_to_month) { 3084 3557 for (; at < tokens.length; at++) { 3085 3558 var has_year = [], has_month = [], has_event = [], has_calc = [], has_constrained_weekday = [], has_calc = []; … … 3116 3589 } 3117 3590 3591 // monthday range like Jan 26-Feb 26 {{{ 3118 3592 if (has_year[0] == has_year[1] && (has_month[1] || has_event[1] || has_constrained_weekday[1])) { 3119 3593 3120 selectors.monthday.push(function(tokens, at, nblock, has_year, has_event, has_calc, at_sec_event_or_month, has_constrained_weekday) { return function(date) { 3594 if (has_month[0]) 3595 isValidDate(tokens[at+has_year[0]][0], tokens[at+has_year[0]+1][0], nblock, at+has_year[0]+1); 3596 if (has_month[1]) 3597 isValidDate(tokens[at_sec_event_or_month][0], tokens[at_sec_event_or_month+1][0], nblock, at+has_year[0]+1); 3598 3599 var selector = function(tokens, at, nblock, has_year, has_event, has_calc, at_sec_event_or_month, has_constrained_weekday) { return function(date) { 3121 3600 var start_of_next_year = new Date(date.getFullYear() + 1, 0, 1); 3122 3601 … … 3210 3689 } 3211 3690 } 3212 }}(tokens, at, nblock, has_year, has_event, has_calc, at_sec_event_or_month, has_constrained_weekday)); 3691 }}(tokens, at, nblock, has_year, has_event, has_calc, at_sec_event_or_month, has_constrained_weekday); 3692 3693 if (push_to_month === true) 3694 selectors.month.push(selector); 3695 else 3696 selectors.monthday.push(selector); 3213 3697 3214 3698 at = (has_constrained_weekday[1] … … 3217 3701 + (typeof has_calc[1] != 'undefined' ? has_calc[1][1] : 0); 3218 3702 3703 // }}} 3704 // Monthday range like Jan 26-31 {{{ 3219 3705 } else if (has_month[0]) { 3220 3706 3221 var is_range = matchTokens(tokens, at+2+has_year[0], '-', 'number'), has_period = false; 3222 if (is_range) 3223 has_period = matchTokens(tokens, at+4+has_year[0], '/', 'number'); 3224 3225 var at_timesep_if_monthRange = at + has_year[0] + 1 // at month number 3226 + (is_range ? 2 : 0) + (has_period ? 2 : 0) 3227 + !(is_range || has_period); // if not range nor has_period, add one 3228 3229 if (matchTokens(tokens, at_timesep_if_monthRange, 'timesep', 'number') 3230 && (matchTokens(tokens, at_timesep_if_monthRange+2, '+') 3231 || matchTokens(tokens, at_timesep_if_monthRange+2, '-'))) 3232 return parseMonthRange(tokens, at); 3233 3234 selectors.monthday.push(function(tokens, at, is_range, has_period, has_year) { return function(date) { 3235 var start_of_next_year = new Date(date.getFullYear() + 1, 0, 1); 3236 3237 var from_date = new Date((has_year ? tokens[at][0] : date.getFullYear()), 3238 tokens[at+has_year][0], tokens[at+1 + has_year][0]); 3239 var to_date = new Date(from_date.getFullYear(), from_date.getMonth(), 3240 tokens[at+(is_range ? 3 : 1)+has_year][0] + 1); 3241 3242 if (date.getTime() < from_date.getTime()) 3243 return [false, from_date]; 3244 else if (date.getTime() >= to_date.getTime()) 3245 return [false, start_of_next_year]; 3246 else if (!has_period) 3247 return [true, to_date]; 3248 3249 var period = tokens[at+has_year+5][0]; 3250 if (!done_with_warnings && period == 1) 3251 parsing_warnings.push([nblock, at+has_year+5, 'Please don’t use day ranges with period equals one (see README)']); 3252 var nday = Math.floor((date.getTime() - from_date.getTime()) / msec_in_day); 3253 var in_period = nday % period; 3254 3255 if (in_period == 0) 3256 return [true, new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1)]; 3707 has_year = has_year[0]; 3708 var year = tokens[at][0]; // Could be month if has no year. Tested later. 3709 var month = tokens[at+has_year][0]; 3710 3711 var first_round = true; 3712 3713 do { 3714 var range_from = tokens[at+1 + has_year][0]; 3715 var is_range = matchTokens(tokens, at+2+has_year, '-', 'number'); 3716 var period = undefined; 3717 var range_to = tokens[at+has_year+(is_range ? 3 : 1)][0] + 1; 3718 if (is_range && matchTokens(tokens, at+has_year+4, '/', 'number')) { 3719 period = tokens[at+has_year+5][0]; 3720 checkPeriod(at+has_year+5, period, 'day'); 3721 } 3722 3723 if (first_round) { 3724 var at_timesep_if_monthRange = at + has_year + 1 // at month number 3725 + (is_range ? 2 : 0) + (period ? 2 : 0) 3726 + !(is_range || period); // if not range nor has period, add one 3727 3728 // Check for '<month> <timespan>' 3729 if (matchTokens(tokens, at_timesep_if_monthRange, 'timesep', 'number') 3730 && (matchTokens(tokens, at_timesep_if_monthRange+2, '+') 3731 || matchTokens(tokens, at_timesep_if_monthRange+2, '-') 3732 || oh_mode != 0)) 3733 return parseMonthRange(tokens, at); 3734 } 3735 3736 // error checking {{{ 3737 if (range_to < range_from) 3738 throw formatWarnErrorMessage(nblock, at+has_year+3, 3739 'Range in wrong order. From day is greater than to day.'); 3740 isValidDate(month, range_from, nblock, at+1 + has_year); 3741 isValidDate(month, range_to - 1 /* added previously */, 3742 nblock, at+has_year+(is_range ? 3 : 1)); 3743 // }}} 3744 3745 var selector = function(year, has_year, month, range_from, range_to, period) { return function(date) { 3746 var start_of_next_year = new Date(date.getFullYear() + 1, 0, 1); 3747 3748 var from_date = new Date(has_year ? year : date.getFullYear(), 3749 month, range_from); 3750 if (month == 1 && range_from != from_date.getDate()) // Only on leap years does this day exist. 3751 return [false]; // If day 29 does not exist, 3752 // then the date object adds one day to date 3753 // and this selector should not match. 3754 var to_date = new Date(from_date.getFullYear(), 3755 month, range_to); 3756 if (month == 1 && is_range && range_to != to_date.getDate()) // Only on leap years does this day exist. 3757 return [false]; 3758 3759 if (date.getTime() < from_date.getTime()) 3760 return [false, from_date]; 3761 else if (date.getTime() >= to_date.getTime()) 3762 return [false, start_of_next_year]; 3763 else if (!period) 3764 return [true, to_date]; 3765 3766 var nday = Math.floor((date.getTime() - from_date.getTime()) / msec_in_day); 3767 var in_period = nday % period; 3768 3769 if (in_period == 0) 3770 return [true, new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1)]; 3771 else 3772 return [false, new Date(date.getFullYear(), date.getMonth(), date.getDate() + period - in_period)]; 3773 3774 }}(year, has_year, month, range_from, range_to, period); 3775 3776 if (push_to_month === true) 3777 selectors.month.push(selector); 3257 3778 else 3258 return [false, new Date(date.getFullYear(), date.getMonth(), date.getDate() + period - in_period)]; 3259 3260 }}(tokens, at, is_range, has_period, has_year[0])); 3261 3262 at += 2 + has_year[0] + (is_range ? 2 : 0) + (has_period ? 2 : 0); 3263 3779 selectors.monthday.push(selector); 3780 3781 at += 2 + has_year + (is_range ? 2 : 0) + (period ? 2 : 0); 3782 3783 first_round = false; 3784 } 3785 while (matchTokens(tokens, at, ',', 'number')) 3786 3787 3788 // }}} 3789 // Only event like easter {{{ 3264 3790 } else if (has_event[0]) { 3265 3791 3266 selectors.monthday.push(function(tokens, at, nblock, has_event, has_year, add_days) { return function(date) {3792 var selector = function(tokens, at, nblock, has_year, add_days) { return function(date) { 3267 3793 3268 3794 // console.log('enter selector with date: ' + date); … … 3289 3815 return [false, new Date(date.getFullYear() + 1, 0, 1)]; 3290 3816 3291 }}(tokens, at, nblock, has_event[0], has_year[0], has_calc[0])); 3817 }}(tokens, at, nblock, has_year[0], has_calc[0]); 3818 3819 if (push_to_month === true) 3820 selectors.month.push(selector); 3821 else 3822 selectors.monthday.push(selector); 3292 3823 3293 3824 at += has_year[0] + has_event[0] + (typeof has_calc[0][1] != 'undefined' && has_calc[0][1] ? 3 : 0); 3825 // }}} 3294 3826 } else if (has_constrained_weekday[0]) { 3295 3827 at = parseMonthRange(tokens, at); 3296 3828 } else if (matchTokens(tokens, at, 'month')) { 3297 return parseMonthRange(tokens, at );3829 return parseMonthRange(tokens, at, true); 3298 3830 } else { 3299 3831 // throw 'Unexpected token in monthday range: "' + tokens[at] + '"'; … … 3312 3844 return at; 3313 3845 } 3314 3315 //====================================================================== 3316 // Main selector traversal function 3317 //====================================================================== 3846 // }}} 3847 3848 // Main selector traversal function (return state array for date) {{{ 3318 3849 this.getStatePair = function(date) { 3319 3850 var resultstate = false; … … 3415 3946 match_block = block; 3416 3947 3417 if (typeof blocks[block].comment != 'undefined') // only use comment if one is specified3948 if (typeof blocks[block].comment == 'string') // only use comment if one is specified 3418 3949 comment = blocks[block].comment; 3419 3950 else if (typeof comment == 'object') // holiday name … … 3434 3965 changedate = res[1]; 3435 3966 3436 break block; // fallback block matched, no need for checking the rest 3967 // break block; // Fallback block matched, no need for checking the rest. 3968 // WRONG: What if 'off' is used after fallback block. 3437 3969 } 3438 3970 } … … 3446 3978 return [ resultstate, changedate, unknown, comment, match_block ]; 3447 3979 } 3448 3449 function formatWarnErrorMessage(nblock, at, message) { 3450 var pos = 0; 3451 if (nblock == -1) { // usage of block index not required because we do have access to value.length 3452 pos = value.length - at; 3453 } else { // Issue accrued at a later time, position in string needs to be reconstructed. 3454 if (typeof tokens[nblock][0][at] == 'undefined') { 3455 pos = value.length; 3456 } else { 3457 pos = value.length; 3458 if (typeof tokens[nblock][0][at+1] != 'undefined') 3459 pos -= tokens[nblock][0][at+1][2]; 3460 else if (typeof tokens[nblock][2] != 'undefined') 3461 pos -= tokens[nblock][2]; 3462 } 3463 } 3464 return value.substring(0, pos) + ' <--- (' + message + ')'; 3465 } 3466 3980 // }}} 3981 3982 // generate prettified value based on tokens {{{ 3467 3983 function prettifySelector(tokens, at, last_at, conf, used_parseTimeRange) { 3468 3984 var value = ''; … … 3527 4043 return value + ' '; 3528 4044 } 4045 // }}} 3529 4046 3530 4047 //====================================================================== 3531 // Public interface 4048 // Public interface {{{ 3532 4049 // All functions below are considered public. 3533 4050 //====================================================================== 3534 4051 3535 4052 //====================================================================== 3536 // Iterator interface 4053 // Iterator interface {{{ 3537 4054 //====================================================================== 3538 4055 this.getIterator = function(date) { … … 3643 4160 }(this); 3644 4161 } 3645 3646 // get parse warnings 3647 // returns an empty string if there are no warnings 4162 // }}} 4163 4164 // Simple API {{{ 4165 4166 // Get parse warnings. 4167 // Returns an empty string if there are no warnings. 3648 4168 this.getWarnings = function() { 3649 4169 var it = this.getIterator(); … … 3651 4171 } 3652 4172 3653 // get a nicely formated value.4173 // Get a nicely formated value. 3654 4174 this.prettifyValue = function(user_conf) { 3655 4175 if (typeof user_conf != 'object') … … 3706 4226 } 3707 4227 3708 // check whether facility is `open' on the given date (or now)4228 // Check whether facility is `open' on the given date (or now). 3709 4229 this.getState = function(date) { 3710 4230 var it = this.getIterator(date); … … 3715 4235 // True will only be returned if the state is false as the getState only 3716 4236 // returns true if the amenity is really open. So you may want to check 3717 // the res oldof getUnknown if getState returned false.4237 // the result of getUnknown if getState returned false. 3718 4238 this.getUnknown = function(date) { 3719 4239 var it = this.getIterator(date); … … 3728 4248 3729 4249 // Returns the comment. 3730 // Most often this will be an empty string as comments are not used that 3731 // often in OSM yet. 4250 // If no comment is specified this function will return undefined. 3732 4251 this.getComment = function(date) { 3733 4252 var it = this.getIterator(date); … … 3735 4254 } 3736 4255 4256 // Return the block which matched thus deterrents the current state. 3737 4257 this.getMatchingRule = function(date) { 3738 4258 var it = this.getIterator(date); … … 3740 4260 } 3741 4261 3742 // returns time of next status change4262 // Returns time of next status change. 3743 4263 this.getNextChange = function(date, maxdate) { 3744 4264 var it = this.getIterator(date); … … 3747 4267 return it.getDate(); 3748 4268 } 4269 4270 // Checks whether open intervals are same for every week. 4271 this.isWeekStable = function() { 4272 return week_stable; 4273 } 4274 // }}} 4275 4276 // High-level API {{{ 3749 4277 3750 4278 // return array of open intervals between two dates … … 3826 4354 return [ open, unknown ]; 3827 4355 } 3828 3829 this.isWeekStable = function() { 3830 return week_stable; 3831 } 4356 // }}} 4357 // }}} 3832 4358 } 3833 4359 })); -
trunk/src/org/openstreetmap/josm/data/validation/tests/OpeningHourTest.java
r7033 r7046 205 205 } 206 206 for (final Object i : getList(((Invocable) ENGINE).invokeMethod(r, "getErrors"))) { 207 errors.add(new OpeningHoursTestError( key + " - " + i.toString().trim(), Severity.ERROR, prettifiedValue));207 errors.add(new OpeningHoursTestError(getErrorMessage(key, i), Severity.ERROR, prettifiedValue)); 208 208 } 209 209 for (final Object i : getList(((Invocable) ENGINE).invokeMethod(r, "getWarnings"))) { 210 errors.add(new OpeningHoursTestError( i.toString().trim(), Severity.WARNING, prettifiedValue));210 errors.add(new OpeningHoursTestError(getErrorMessage(key, i), Severity.WARNING, prettifiedValue)); 211 211 } 212 212 if (!ignoreOtherSeverity && errors.isEmpty() && prettifiedValue != null && !value.equals(prettifiedValue)) { … … 217 217 } 218 218 return errors; 219 } 220 221 /** 222 * Translates and shortens the error/warning message. 223 */ 224 private String getErrorMessage(String key, Object o) { 225 String msg = o.toString().trim() 226 .replace("Unexpected token:", tr("Unexpected token:")) 227 .replace("Unexpected token (school holiday parser):", tr("Unexpected token (school holiday parser):")) 228 .replace("Unexpected token in number range:", tr("Unexpected token in number range:")) 229 .replace("Unexpected token in week range:", tr("Unexpected token in week range:")) 230 .replace("Unexpected token in weekday range:", tr("Unexpected token in weekday range:")) 231 .replace("Unexpected token in month range:", tr("Unexpected token in month range:")) 232 .replace("Unexpected token in year range:", tr("Unexpected token in year range:")) 233 .replace("This means that the syntax is not valid at that point or it is currently not supported.", tr("Invalid/unsupported syntax.")); 234 return key + " - " + msg; 219 235 } 220 236
Note:
See TracChangeset
for help on using the changeset viewer.