WME Utils - HoursParser Beta

Parses a text string into hours, for use in Waze Map Editor scripts

目前為 2018-02-07 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/38249/249584/WME%20Utils%20-%20HoursParser%20Beta.js

  1. // ==UserScript==
  2. // @name WME Utils - HoursParser Beta
  3. // @namespace WazeDev
  4. // @version 2018.02.07.002
  5. // @description Parses a text string into hours, for use in Waze Map Editor scripts
  6. // @author MapOMatic (originally developed by bmtg)
  7. // @license GNU GPLv3
  8. // ==/UserScript==
  9.  
  10. class HoursParser {
  11. constructor() {
  12. let currLocale = I18n.translations[I18n.currentLocale()];
  13. var I18nDate = currLocale.date;
  14. this.DAYS_OF_THE_WEEK = {
  15. SS: ['saturdays', I18nDate.day_names[6].toLowerCase(), 'satur', I18nDate.abbr_day_names[6].toLowerCase(), 'sa'],
  16. UU: ['sundays', I18nDate.day_names[0].toLowerCase(), I18nDate.abbr_day_names[0].toLowerCase(), 'su'],
  17. MM: ['mondays', I18nDate.day_names[1].toLowerCase(), 'mondy', I18nDate.abbr_day_names[1].toLowerCase(), 'mo'],
  18. TT: ['tuesdays', I18nDate.day_names[2].toLowerCase(), 'tues', I18nDate.abbr_day_names[2].toLowerCase(), 'tu'],
  19. WW: ['wednesdays', I18nDate.day_names[3].toLowerCase(), 'weds', I18nDate.abbr_day_names[3].toLowerCase(), 'we'],
  20. RR: ['thursdays', I18nDate.day_names[4].toLowerCase(), 'thurs', 'thur', I18nDate.abbr_day_names[4].toLowerCase(), 'th'],
  21. FF: ['fridays', I18nDate.day_names[5].toLowerCase(), I18nDate.abbr_day_names[5].toLowerCase(), 'fr']
  22. };
  23. this.MONTHS_OF_THE_YEAR = {
  24. JAN: [I18nDate.month_names[1].toLowerCase(), I18nDate.abbr_month_names[1].toLowerCase()],
  25. FEB: [I18nDate.month_names[2].toLowerCase(), 'febr', I18nDate.abbr_month_names[2].toLowerCase()],
  26. MAR: [I18nDate.month_names[3].toLowerCase(), I18nDate.abbr_month_names[3].toLowerCase()],
  27. APR: [I18nDate.month_names[4].toLowerCase(), I18nDate.abbr_month_names[4].toLowerCase()],
  28. MAY: [I18nDate.month_names[5].toLowerCase(), I18nDate.abbr_month_names[5].toLowerCase()],
  29. JUN: [I18nDate.month_names[6].toLowerCase(), I18nDate.abbr_month_names[6].toLowerCase()],
  30. JUL: [I18nDate.month_names[7].toLowerCase(), I18nDate.abbr_month_names[7].toLowerCase()],
  31. AUG: [I18nDate.month_names[8].toLowerCase(), I18nDate.abbr_month_names[8].toLowerCase()],
  32. SEP: [I18nDate.month_names[9].toLowerCase(), 'sept', I18nDate.abbr_month_names[9].toLowerCase()],
  33. OCT: [I18nDate.month_names[10].toLowerCase(), I18nDate.abbr_month_names[10].toLowerCase()],
  34. NOV: [I18nDate.month_names[11].toLowerCase(), I18nDate.abbr_month_names[11].toLowerCase()],
  35. DEC: [I18nDate.month_names[12].toLowerCase(), I18nDate.abbr_month_names[12].toLowerCase()]
  36. };
  37. debugger;
  38. this.DAY_CODE_VECTOR = ['MM','TT','WW','RR','FF','SS','UU','MM','TT','WW','RR','FF','SS','UU','MM','TT','WW','RR','FF'];
  39. this.THRU_WORDS = ['through','thru',currLocale.element_history.changed_to,'until','till','til','-','~'].map(x => x = "\b" + x + "\b");
  40. }
  41.  
  42. parseHours(inputHours, locale) {
  43. let returnVal = {
  44. hours: [],
  45. parseError: false,
  46. overlappingHours: false,
  47. sameOpenAndCloseTimes: false
  48. };
  49.  
  50. let tfHourTemp, tfDaysTemp, newDayCodeVec = [];
  51. let tempRegex, twix, tsix;
  52. let inputHoursParse = inputHours.toLowerCase().trim();
  53. if (inputHoursParse.length === 0 || inputHoursParse === ',') {
  54. return returnVal;
  55. }
  56. let today = new Date();
  57. let tomorrow = new Date();
  58. tomorrow.setDate(tomorrow.getDate() + 1);
  59. inputHoursParse = inputHoursParse.replace(/\btoday\b/g, today.toLocaleDateString(locale, {weekday:'short'}).toLowerCase())
  60. .replace(/\btomorrow\b/g, tomorrow.toLocaleDateString(locale, {weekday:'short'}).toLowerCase())
  61. .replace(/\u2013|\u2014/g, "-") // long dash replacing
  62. .replace(/[^a-z0-9\:\-\. ~áé]/g, ' ') // replace unnecessary characters with spaces
  63. .replace(/\:{2,}/g, ':') // remove extra colons
  64. .replace(/closed|not open/g, '99:99-99:99') // parse 'closed'
  65. .replace(/by appointment( only)?/g, '99:99-99:99') // parse 'appointment only'
  66. .replace(/weekdays/g, 'mon-fri').replace(/weekends/g, 'sat-sun') // convert weekdays and weekends to days
  67. .replace(/(12(:00)?\W*)?noon/g, "12:00").replace(/(12(:00)?\W*)?mid(night|nite)/g, "00:00") // replace 'noon', 'midnight'
  68. .replace(/every\s*day|daily|(7|seven) days a week/g, "mon-sun") // replace 'seven days a week'
  69. .replace(/(open\s*)?(24|twenty\W*four)\W*h(ou)?rs?|all day/g, "00:00-00:00") // replace 'open 24 hour or similar'
  70. .replace(/(\D:)([^ ])/g, "$1 $2"); // space after colons after words
  71.  
  72. // replace thru type words with dashes
  73. this.THRU_WORDS.forEach(word => {
  74. inputHoursParse = inputHoursParse.replace( new RegExp(word, 'g'), '-');
  75. });
  76.  
  77. inputHoursParse = inputHoursParse.replace(/\-{2,}/g, "-"); // replace any duplicate dashes
  78.  
  79. // kill extra words
  80. let killWords = 'paste|here|business|operation|times|time|walk-ins|walk ins|welcome|dinner|lunch|brunch|breakfast|regular|weekday|weekend|opening|open|now|from|hours|hour|our|are|EST|and|&'.split("|");
  81. for (twix=0; twix<killWords.length; twix++) {
  82. tempRegex = new RegExp('\\b'+killWords[twix]+'\\b', "g");
  83. inputHoursParse = inputHoursParse.replace(tempRegex,'');
  84. }
  85.  
  86. // replace day terms with double caps
  87. for (let dayKey in this.DAYS_OF_THE_WEEK) {
  88. if (this.DAYS_OF_THE_WEEK.hasOwnProperty(dayKey)) {
  89. let tempDayList = this.DAYS_OF_THE_WEEK[dayKey];
  90. for (var tdix=0; tdix<tempDayList.length; tdix++) {
  91. tempRegex = new RegExp(tempDayList[tdix]+'(?!a-z)', "g");
  92. inputHoursParse = inputHoursParse.replace(tempRegex,dayKey);
  93. }
  94. }
  95. }
  96.  
  97. // Replace dates
  98. for (let monthKey in this.MONTHS_OF_THE_YEAR) {
  99. if (this.MONTHS_OF_THE_YEAR.hasOwnProperty(monthKey)) {
  100. let tempMonthList = this.MONTHS_OF_THE_YEAR[monthKey];
  101. for (var tmix=0; tmix<tempMonthList.length; tmix++) {
  102. tempRegex = new RegExp(tempMonthList[tmix]+'\\.? ?\\d{1,2}\\,? ?201\\d{1}', "g");
  103. inputHoursParse = inputHoursParse.replace(tempRegex,' ');
  104. tempRegex = new RegExp(tempMonthList[tmix]+'\\.? ?\\d{1,2}', "g");
  105. inputHoursParse = inputHoursParse.replace(tempRegex,' ');
  106. }
  107. }
  108. }
  109.  
  110. // replace any periods between hours with colons
  111. inputHoursParse = inputHoursParse.replace(/(\d{1,2})\.(\d{2})/g, '$1:$2');
  112. // remove remaining periods
  113. inputHoursParse = inputHoursParse.replace(/\./g, '');
  114. // remove any non-hour colons between letters and numbers and on string ends
  115. inputHoursParse = inputHoursParse.replace(/(\D+)\:(\D+)/g, '$1 $2').replace(/^ *\:/g, ' ').replace(/\: *$/g, ' ');
  116. // replace am/pm with AA/PP
  117. inputHoursParse = inputHoursParse.replace(/ *pm/g,'PP').replace(/ *am/g,'AA');
  118. inputHoursParse = inputHoursParse.replace(/ *p\.m\./g,'PP').replace(/ *a\.m\./g,'AA');
  119. inputHoursParse = inputHoursParse.replace(/ *p\.m/g,'PP').replace(/ *a\.m/g,'AA');
  120. inputHoursParse = inputHoursParse.replace(/ *p/g,'PP').replace(/ *a/g,'AA');
  121. // tighten up dashes
  122. inputHoursParse = inputHoursParse.replace(/\- {1,}/g,'-').replace(/ {1,}\-/g,'-');
  123. inputHoursParse = inputHoursParse.replace(/^(00:00-00:00)$/g,'MM-UU$1');
  124.  
  125. // Change all MTWRFSU to doubles, if any other letters return false
  126. if (inputHoursParse.match(/[bcdeghijklnoqvxyz]/g) !== null) {
  127. returnVal.parseError = true;
  128. return returnVal;
  129. } else {
  130. inputHoursParse = inputHoursParse.replace(/m/g,'MM').replace(/t/g,'TT').replace(/w/g,'WW').replace(/r/g,'RR');
  131. inputHoursParse = inputHoursParse.replace(/f/g,'FF').replace(/s/g,'SS').replace(/u/g,'UU');
  132. }
  133.  
  134. // tighten up spaces
  135. inputHoursParse = inputHoursParse.replace(/ {2,}/g,' ');
  136. inputHoursParse = inputHoursParse.replace(/ {1,}AA/g,'AA');
  137. inputHoursParse = inputHoursParse.replace(/ {1,}PP/g,'PP');
  138. // Expand hours into XX:XX format
  139. for (var asdf=0; asdf<5; asdf++) { // repeat a few times to catch any skipped regex matches
  140. inputHoursParse = inputHoursParse.replace(/([^0-9\:])(\d{1})([^0-9\:])/g, '$10$2:00$3');
  141. inputHoursParse = inputHoursParse.replace(/^(\d{1})([^0-9\:])/g, '0$1:00$2');
  142. inputHoursParse = inputHoursParse.replace(/([^0-9\:])(\d{1})$/g, '$10$2:00');
  143.  
  144. inputHoursParse = inputHoursParse.replace(/([^0-9\:])(\d{2})([^0-9\:])/g, '$1$2:00$3');
  145. inputHoursParse = inputHoursParse.replace(/^(\d{2})([^0-9\:])/g, '$1:00$2');
  146. inputHoursParse = inputHoursParse.replace(/([^0-9\:])(\d{2})$/g, '$1$2:00');
  147.  
  148. inputHoursParse = inputHoursParse.replace(/(\D)(\d{1})(\d{2}\D)/g, '$10$2:$3');
  149. inputHoursParse = inputHoursParse.replace(/^(\d{1})(\d{2}\D)/g, '0$1:$2');
  150. inputHoursParse = inputHoursParse.replace(/(\D)(\d{1})(\d{2})$/g, '$10$2:$3');
  151.  
  152. inputHoursParse = inputHoursParse.replace(/(\D\d{2})(\d{2}\D)/g, '$1:$2');
  153. inputHoursParse = inputHoursParse.replace(/^(\d{2})(\d{2}\D)/g, '$1:$2');
  154. inputHoursParse = inputHoursParse.replace(/(\D\d{2})(\d{2})$/g, '$1:$2');
  155.  
  156. inputHoursParse = inputHoursParse.replace(/(\D)(\d{1}\:)/g, '$10$2');
  157. inputHoursParse = inputHoursParse.replace(/^(\d{1}\:)/g, '0$1');
  158. }
  159.  
  160. // replace 12AM range with 00
  161. inputHoursParse = inputHoursParse.replace( /12(\:\d{2}AA)/g, '00$1');
  162. // Change PM hours to 24hr time
  163. while (inputHoursParse.match(/\d{2}\:\d{2}PP/) !== null) {
  164. tfHourTemp = inputHoursParse.match(/(\d{2})\:\d{2}PP/)[1];
  165. tfHourTemp = parseInt(tfHourTemp) % 12 + 12;
  166. inputHoursParse = inputHoursParse.replace(/\d{2}(\:\d{2})PP/,tfHourTemp.toString()+'$1');
  167. }
  168. // kill the AA
  169. inputHoursParse = inputHoursParse.replace( /AA/g, '');
  170.  
  171. // Side check for tabular input
  172. var inputHoursParseTab = inputHoursParse.replace( /[^A-Z0-9\:-]/g, ' ').replace( / {2,}/g, ' ');
  173. inputHoursParseTab = inputHoursParseTab.replace( /^ +/g, '').replace( / {1,}$/g, '');
  174. if (inputHoursParseTab.match(/[A-Z]{2}\:?\-? [A-Z]{2}\:?\-? [A-Z]{2}\:?\-? [A-Z]{2}\:?\-? [A-Z]{2}\:?\-?/g) !== null) {
  175. inputHoursParseTab = inputHoursParseTab.split(' ');
  176. var reorderThree = [0,7,14,1,8,15,2,9,16,3,10,17,4,11,18,5,12,19,6,13,20];
  177. var reorderTwo = [0,7,1,8,2,9,3,10,4,11,5,12,6,13];
  178. var inputHoursParseReorder = [], reix;
  179. if (inputHoursParseTab.length === 21) {
  180. for (reix=0; reix<21; reix++) {
  181. inputHoursParseReorder.push(inputHoursParseTab[reorderThree[reix]]);
  182. }
  183. } else if (inputHoursParseTab.length === 18) {
  184. for (reix=0; reix<18; reix++) {
  185. inputHoursParseReorder.push(inputHoursParseTab[reorderThree[reix]]);
  186. }
  187. } else if (inputHoursParseTab.length === 15) {
  188. for (reix=0; reix<15; reix++) {
  189. inputHoursParseReorder.push(inputHoursParseTab[reorderThree[reix]]);
  190. }
  191. } else if (inputHoursParseTab.length === 14) {
  192. for (reix=0; reix<14; reix++) {
  193. inputHoursParseReorder.push(inputHoursParseTab[reorderTwo[reix]]);
  194. }
  195. } else if (inputHoursParseTab.length === 12) {
  196. for (reix=0; reix<12; reix++) {
  197. inputHoursParseReorder.push(inputHoursParseTab[reorderTwo[reix]]);
  198. }
  199. } else if (inputHoursParseTab.length === 10) {
  200. for (reix=0; reix<10; reix++) {
  201. inputHoursParseReorder.push(inputHoursParseTab[reorderTwo[reix]]);
  202. }
  203. }
  204.  
  205. if (inputHoursParseReorder.length > 9) {
  206. inputHoursParseReorder = inputHoursParseReorder.join(' ');
  207. inputHoursParseReorder = inputHoursParseReorder.replace(/(\:\d{2}) (\d{2}\:)/g, '$1-$2');
  208. inputHoursParse = inputHoursParseReorder;
  209. }
  210.  
  211. }
  212.  
  213.  
  214. // remove colons after Days field
  215. inputHoursParse = inputHoursParse.replace(/(\D+)\:/g, '$1 ');
  216.  
  217. // Find any double sets
  218. inputHoursParse = inputHoursParse.replace(/([A-Z \-]{2,}) *(\d{2}\:\d{2} *\-{1} *\d{2}\:\d{2}) *(\d{2}\:\d{2} *\-{1} *\d{2}\:\d{2})/g, '$1$2$1$3');
  219. inputHoursParse = inputHoursParse.replace(/(\d{2}\:\d{2}) *(\d{2}\:\d{2})/g, '$1-$2');
  220.  
  221. // remove all spaces
  222. inputHoursParse = inputHoursParse.replace( / */g, '');
  223.  
  224. // Remove any dashes acting as Day separators for 3+ days ("M-W-F")
  225. inputHoursParse = inputHoursParse.replace( /([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})/g, '$1$2$3$4$5$6$7');
  226. inputHoursParse = inputHoursParse.replace( /([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})/g, '$1$2$3$4$5$6');
  227. inputHoursParse = inputHoursParse.replace( /([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})/g, '$1$2$3$4$5');
  228. inputHoursParse = inputHoursParse.replace( /([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})/g, '$1$2$3$4');
  229. inputHoursParse = inputHoursParse.replace( /([A-Z]{2})-([A-Z]{2})-([A-Z]{2})/g, '$1$2$3');
  230.  
  231. // parse any 'through' type terms on the day ranges (MM-RR --> MMTTWWRR)
  232. while (inputHoursParse.match(/[A-Z]{2}\-[A-Z]{2}/) !== null) {
  233. tfDaysTemp = inputHoursParse.match(/([A-Z]{2})\-([A-Z]{2})/);
  234. var startDayIX = this.DAY_CODE_VECTOR.indexOf(tfDaysTemp[1]);
  235. newDayCodeVec = [tfDaysTemp[1]];
  236. for (var dcvix=startDayIX+1; dcvix<startDayIX+7; dcvix++) {
  237. newDayCodeVec.push(this.DAY_CODE_VECTOR[dcvix]);
  238. if (tfDaysTemp[2] === this.DAY_CODE_VECTOR[dcvix]) {
  239. break;
  240. }
  241. }
  242. newDayCodeVec = newDayCodeVec.join('');
  243. inputHoursParse = inputHoursParse.replace(/[A-Z]{2}\-[A-Z]{2}/,newDayCodeVec);
  244. }
  245.  
  246. // split the string between numerical and letter characters
  247. inputHoursParse = inputHoursParse.replace(/([A-Z])\-?\:?([0-9])/g,'$1|$2');
  248. inputHoursParse = inputHoursParse.replace(/([0-9])\-?\:?([A-Z])/g,'$1|$2');
  249. inputHoursParse = inputHoursParse.replace(/(\d{2}\:\d{2})\:00/g,'$1'); // remove seconds
  250. inputHoursParse = inputHoursParse.split("|");
  251.  
  252. var daysVec = [], hoursVec = [];
  253. for (tsix=0; tsix<inputHoursParse.length; tsix++) {
  254. if (inputHoursParse[tsix][0].match(/[A-Z]/) !== null) {
  255. daysVec.push(inputHoursParse[tsix]);
  256. } else if (inputHoursParse[tsix][0].match(/[0-9]/) !== null) {
  257. hoursVec.push(inputHoursParse[tsix]);
  258. } else {
  259. returnVal.parseError = true;
  260. return returnVal;
  261. }
  262. }
  263.  
  264. // check that the dayArray and hourArray lengths correspond
  265. if ( daysVec.length !== hoursVec.length ) {
  266. returnVal.parseError = true;
  267. return returnVal;
  268. }
  269.  
  270. // Combine days with the same hours in the same vector
  271. var newDaysVec = [], newHoursVec = [], hrsIX;
  272. for (tsix=0; tsix<daysVec.length; tsix++) {
  273. if (hoursVec[tsix] !== '99:99-99:99') { // Don't add the closed days
  274. hrsIX = newHoursVec.indexOf(hoursVec[tsix]);
  275. if (hrsIX > -1) {
  276. newDaysVec[hrsIX] = newDaysVec[hrsIX] + daysVec[tsix];
  277. } else {
  278. newDaysVec.push(daysVec[tsix]);
  279. newHoursVec.push(hoursVec[tsix]);
  280. }
  281. }
  282. }
  283.  
  284. var hoursObjectArray = [], hoursObjectArrayMinDay = [], hoursObjectArraySorted = [], hoursObjectAdd, daysObjArray, toFromSplit;
  285. for (tsix=0; tsix<newDaysVec.length; tsix++) {
  286. hoursObjectAdd = {};
  287. daysObjArray = [];
  288. toFromSplit = newHoursVec[tsix].match(/(\d{2}\:\d{2})\-(\d{2}\:\d{2})/);
  289. if (toFromSplit === null) {
  290. returnVal.parseError = true;
  291. return returnVal;
  292. } else { // Check for hours outside of 0-23 and 0-59
  293. var hourCheck = toFromSplit[1].match(/(\d{2})\:/)[1];
  294. if (hourCheck>23 || hourCheck < 0) {
  295. returnVal.parseError = true;
  296. return returnVal;
  297. }
  298. hourCheck = toFromSplit[2].match(/(\d{2})\:/)[1];
  299. if (hourCheck>23 || hourCheck < 0) {
  300. returnVal.parseError = true;
  301. return returnVal;
  302. }
  303. hourCheck = toFromSplit[1].match(/\:(\d{2})/)[1];
  304. if (hourCheck>59 || hourCheck < 0) {
  305. returnVal.parseError = true;
  306. return returnVal;
  307. }
  308. hourCheck = toFromSplit[2].match(/\:(\d{2})/)[1];
  309. if (hourCheck>59 || hourCheck < 0) {
  310. returnVal.parseError = true;
  311. return returnVal;
  312. }
  313. }
  314. // Make the days object
  315. if ( newDaysVec[tsix].indexOf('MM') > -1 ) {
  316. daysObjArray.push(1);
  317. }
  318. if ( newDaysVec[tsix].indexOf('TT') > -1 ) {
  319. daysObjArray.push(2);
  320. }
  321. if ( newDaysVec[tsix].indexOf('WW') > -1 ) {
  322. daysObjArray.push(3);
  323. }
  324. if ( newDaysVec[tsix].indexOf('RR') > -1 ) {
  325. daysObjArray.push(4);
  326. }
  327. if ( newDaysVec[tsix].indexOf('FF') > -1 ) {
  328. daysObjArray.push(5);
  329. }
  330. if ( newDaysVec[tsix].indexOf('SS') > -1 ) {
  331. daysObjArray.push(6);
  332. }
  333. if ( newDaysVec[tsix].indexOf('UU') > -1 ) {
  334. daysObjArray.push(0);
  335. }
  336. // build the hours object
  337. hoursObjectAdd.fromHour = toFromSplit[1];
  338. hoursObjectAdd.toHour = toFromSplit[2];
  339. hoursObjectAdd.days = daysObjArray.sort();
  340. hoursObjectArray.push(hoursObjectAdd);
  341. // track the order
  342. if (hoursObjectAdd.days.length > 1 && hoursObjectAdd.days[0] === 0) {
  343. hoursObjectArrayMinDay.push( hoursObjectAdd.days[1] * 100 + parseInt(toFromSplit[1][0])*10 + parseInt(toFromSplit[1][1]) );
  344. } else {
  345. hoursObjectArrayMinDay.push( (((hoursObjectAdd.days[0]+6)%7)+1) * 100 + parseInt(toFromSplit[1][0])*10 + parseInt(toFromSplit[1][1]) );
  346. }
  347. }
  348. this._sortWithIndex(hoursObjectArrayMinDay);
  349. for (var hoaix=0; hoaix < hoursObjectArrayMinDay.length; hoaix++) {
  350. hoursObjectArraySorted.push(hoursObjectArray[hoursObjectArrayMinDay.sortIndices[hoaix]]);
  351. }
  352. if ( !this._checkHours(hoursObjectArraySorted) ) {
  353. returnVal.hours = hoursObjectArraySorted;
  354. returnVal.overlappingHours = true;
  355. return returnVal;
  356. } else if ( this._hasSameOpenCloseTimes(hoursObjectArraySorted) ) {
  357. returnVal.hours = hoursObjectArraySorted;
  358. returnVal.sameOpenAndCloseTimes = true;
  359. return returnVal;
  360. } else {
  361. for ( var ohix=0; ohix<hoursObjectArraySorted.length; ohix++ ) {
  362. if ( hoursObjectArraySorted[ohix].days.length === 2 && hoursObjectArraySorted[ohix].days[0] === 0 && hoursObjectArraySorted[ohix].days[1] === 1) {
  363. // separate hours
  364. hoursObjectArraySorted.push({days: [0], fromHour: hoursObjectArraySorted[ohix].fromHour, toHour: hoursObjectArraySorted[ohix].toHour});
  365. hoursObjectArraySorted[ohix].days = [1];
  366. }
  367. }
  368. }
  369. returnVal.hours = hoursObjectArray;
  370. return returnVal;
  371. }
  372.  
  373. // function to check overlapping hours
  374. _checkHours(hoursObj) {
  375. if (hoursObj.length === 1) {
  376. return true;
  377. }
  378. var daysObj, fromHourTemp, toHourTemp;
  379. for (var day2Ch=0; day2Ch<7; day2Ch++) { // Go thru each day of the week
  380. daysObj = [];
  381. for ( var hourSet = 0; hourSet < hoursObj.length; hourSet++ ) { // For each set of hours
  382. if (hoursObj[hourSet].days.indexOf(day2Ch) > -1) { // pull out hours that are for the current day, add 2400 if it goes past midnight, and store
  383. fromHourTemp = hoursObj[hourSet].fromHour.replace(/\:/g,'');
  384. toHourTemp = hoursObj[hourSet].toHour.replace(/\:/g,'');
  385. if (toHourTemp <= fromHourTemp) {
  386. toHourTemp = parseInt(toHourTemp) + 2400;
  387. }
  388. daysObj.push([fromHourTemp, toHourTemp]);
  389. }
  390. }
  391. if (daysObj.length > 1) { // If there's multiple hours for the day, check them for overlap
  392. for ( var hourSetCheck2 = 1; hourSetCheck2 < daysObj.length; hourSetCheck2++ ) {
  393. for ( var hourSetCheck1 = 0; hourSetCheck1 < hourSetCheck2; hourSetCheck1++ ) {
  394. if ( daysObj[hourSetCheck2][0] > daysObj[hourSetCheck1][0] && daysObj[hourSetCheck2][0] < daysObj[hourSetCheck1][1] ) {
  395. return false;
  396. }
  397. if ( daysObj[hourSetCheck2][1] > daysObj[hourSetCheck1][0] && daysObj[hourSetCheck2][1] < daysObj[hourSetCheck1][1] ) {
  398. return false;
  399. }
  400. }
  401. }
  402. }
  403. }
  404. return true;
  405. }
  406.  
  407. _hasSameOpenCloseTimes(hoursObj) {
  408. var fromHourTemp, toHourTemp;
  409. for ( var hourSet = 0; hourSet < hoursObj.length; hourSet++ ) { // For each set of hours
  410. fromHourTemp = hoursObj[hourSet].fromHour;
  411. toHourTemp = hoursObj[hourSet].toHour;
  412. if (fromHourTemp !== '00:00' && fromHourTemp === toHourTemp) {
  413. // If open and close times are the same, don't parse.
  414. return true;
  415. }
  416. }
  417. return false;
  418. }
  419.  
  420. _sortWithIndex(toSort) {
  421. for (var i = 0; i < toSort.length; i++) {
  422. toSort[i] = [toSort[i], i];
  423. }
  424. toSort.sort(function(left, right) {
  425. return left[0] < right[0] ? -1 : 1;
  426. });
  427. toSort.sortIndices = [];
  428. for (var j = 0; j < toSort.length; j++) {
  429. toSort.sortIndices.push(toSort[j][1]);
  430. toSort[j] = toSort[j][0];
  431. }
  432. return toSort;
  433. }
  434. // delete this later...
  435. _unused() {}
  436. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址