我如何将非标准的date和时间文本转换为XDate对象?

多解释一下情况; 我们有一个非标准的文本时间和datestring ,这些string变化很大,需要parsing成一个XDate ( http://arshaw.com/xdate/ )对象(可能是多个XDate对象)。

请注意, 我不是在寻找某人来完整编写代码 。 只是一些理论和快速代码片段来处理所有可能的情况(即使是失败 )。 此外,这不是一项家庭作业

我的第一个解决scheme是使用split()但是失败了。 我看到的一些其他的可能性是regexpattern matchingloop text until not asciinumber picker from string等。

一旦失败,我很可能会产生一些随机的工作时间。
避免失败尤为重要。

我不确定最好的方法是什么。 任何和所有的帮助,高度赞赏。

这只是一些可能性。 每条线代表一种可能性。

date和时间:

  • 星期一上午6点 – 下午8点
  • 周一至周五上午6点至晚上8点
  • 星期一,星期三,星期五晚上12点 – 晚上9点
  • 周一至周四,周日上午11点至晚上8点
  • 周一中午12点至晚上10点,周二中午12点至晚上10点,周三中午12点至晚上10:00
  • 周一至周五上午10点至晚上10点,周六上午10点至凌晨1点,周日上午10点至上午9点,随机发送文字
  • 周一上午11点至上午12点,周二上午11点至上午12点,周一至周日上午11点至上午2点
  • 星期一11:00-21:00,星期二11:00-21:00,星期三11:00-21:00
  • 星期一上午11:00-8:30pm;上午11:00-8:30pm;上午11:00-8:30pm;星期一11:00 am-8:30pm;

结果:
输出将是格式的JSON对象:

 { mon_open: "6:00 am", mon_close: "8:00 pm", tue_open: "6:00 am", tue_close: "8:00 pm", etc } 

我build议你先把datestring格式化为计算机可以理解的东西(更加标准化),然后你可以非常容易地撕掉你需要的部分:

http://jsfiddle.net/DerekL/8L5EA/

下面的代码将把你的datestring修改成一个标准化的格式:

 ["monday+tuesday+wednesday+thursday+friday06:00-20:00"] ["monday+wednesday+friday12:00-21:00"] ["monday+tuesday+wednesday+thursday+sunday11:00-20:00"] ["monday11:00-20:30", "tuesday11:00-20:30", "wednesday11:00-20:30", "thursday11:00-20:30", ""] [ d[+d...]HH:MM-HH:MM , d[+d...]HH:MM-HH:MM , ... ] 

然后它会根据这个标准化的string创build对象。

http://jsfiddle.net/DerekL/8L5EA/

 console.log(makeObj(txt)); //<-- Here is your object function makeObj(txt) { arr = formatText(txt); var result = {}; for (var i = 0; i < arr.length; i++) { var times = arr[i].match(/\d\d:\d\d-\d\d:\d\d/); if (times === null) { continue; } times = times[0].split("-"); var days = arr[i].match(/(\D+)\d\d:\d\d-\d\d:\d\d/)[1].split("+"); for (var j = 0; j < days.length; j++) { result[days[j] + "_open"] = times[0]; result[days[j] + "_close"] = times[1]; } } return result; } function addZeros(n) { return ("0" + n).slice(-2); }; function formatText(txt) { //remove spaces var output = txt.replace(/\s/g, ""); //change abbr. to full name output = output.toLowerCase().replace(/(mon|tues|tue|wed|thurs|thur|thu|fri|sat|sun)(?![az])/g, function (c) { return { mon: "monday", tue: "tuesday", tues: "tuesday", wed: "wednesday", thu: "thursday", thur: "thursday", thurs: "thursday", fri: "friday", sat: "saturday", sun: "sunday" }[c]; }); //change "comma" day intervals to "plus" var daysInt = /(monday|tuesday|wednesday|thursday|friday|saturday|sunday),(monday|tuesday|wednesday|thursday|friday|saturday|sunday)/g; while (daysInt.test(output)) { output = output.replace(daysInt, "$1+$2"); } //remove comma after days declarations output = output.replace(/(monday|tuesday|wednesday|thursday|friday|saturday|sunday)\,/g, "$1"); //change intervals into using "plus" output = output.replace(/(monday|tuesday|wednesday|thursday|friday|saturday|sunday)-(monday|tuesday|wednesday|thursday|friday|saturday|sunday)/g, function (c) { var days = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"], opt = [], interval = c.split("-"); interval[0] = days.indexOf(interval[0]); interval[1] = days.indexOf(interval[1]); interval[0] -= interval[1] < interval[0] ? 7 : 0; while (true) { opt.push(days[interval[0] < 0 ? interval[0] + 7 : interval[0]]); interval[0]++; if (interval[0] > interval[1]) { break; } } opt = opt.join("+"); return opt; }); //turn 12-hour format to 24-hour format output = output.replace(/(\D)(\d)(?!\d)/g, "$10$2"); output = output.replace(/([^:])(\d\d)(am|pm)/g, "$1$2:00$3"); output = output.replace(/\d\d:\d\d(am|pm)/g, function (c) { if (c.indexOf("pm") == -1) { return c == "12:00am" ? "00:00" : c.replace("am", ""); } else { c = c.replace("pm", ""); return c == "12:00" ? "12:00" : addZeros((+c.substr(0, 2) + 12)) + c.slice(2); } }); //split different times output = output.split(/[,;]/); return output; } 

经过5个多小时,我完成了这个项目(在Derek的帮助下)。 除了一个实例外,其他的都通过了我的testing 在单个失败项目上,结束时间显示错误。 也许别人可以看到这个错误。

以下是任何可能需要它的解决scheme:

预requisits:
修改/更新DateJS从: https : //github.com/abritinthebay/datejs

要旨:
https://gist.github.com/bugs181/8819564

JSBin:
http://jsbin.com/EXeyeZI/5/edit?html,js,console

码:

 //var str = "monday-Thursday 9:00 PM - 12:00 PM, Tue 11:00 PM - 12:00 PM, Wednesday 10:00 PM - 12:00 PM"; // PASS //var str = "Mon 6 am - 8 pm"; // PASS //var str = "Mon-Fri 6 am - 8 pm"; // PASS //var str = "Mon, Wed, Fri 9 pm - 12 pm"; // PASS //var str = "Mon-Thu, Sun 11 am - 8 pm"; // PASS //var str = "Monday 10:00 PM - 12:00 PM, Tuesday 11:00 PM - 11:30 PM, Wednesday 10:00 PM - 12:00 PM"; // PASS //var str = "Mon-Fri 10am-10pm, Sat 10am-1am, Sun 9am-10am, some random text"; // PASS //var str = "Mon-Fri 10am-10pm, don't break the days, Sat 10am-1am, Sun 9am-10am, some random text"; // PASS //var str = "Mon-Fri 10am-10pm, !@#$%^&U* Sat 10am-1am, Sun 9am-10am, some random text"; // PASS //var str = "mon 11:00am-12:00am, tue 11:00am-12:00am, wed 11:00am-02:00pm"; // PASS //var str = "monday 11:00-21:00, tuesday 11:00-21:00, wednesday 11:00-21:00";// PASS //var str = "mon 11:00am-8:00pm;tue 11:00am-8:30pm;wed 11:00am-8:30pm;thu 11:00am-8:30pm;"; // FAILED var str = "monday-Thursday 10:00 PM - 11:00 PM, Tue 10:00 PM - 12:00 PM, Wednesday 10:00 PM - 12:00 PM"; // PASS // Some useful variables. var splitter = '$'; var short_days = new Array('mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'); var long_days = new Array('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'); var open_name_days = {}; // Place to store business hours object. // Make text all lower case and remove white space. var str = str.toLowerCase().replace(/\s/g, ''); // Match and replace any day abbreviations. Will match until non AZ character. var regex_days = /(mon|tue|wed|thu|fri|sat|sun).*?(?=[^az])/g; var match; while ((match = regex_days.exec(str)) !== null) { var match_day = short_days.indexOf(match[1]); // Returns a regex short_day. str = str.replace(match[0], long_days[match_day] + splitter); // Replace short_days with long_days in string. } // Replace any indicator for interval with + signs, which represent 'to'. Indicator will be assumed anything between start_day and end_day. //str = str.replace(/-/g, '+'); // Split days by characters var days = str.split(/[,;]/); console.log(days); console.log(''); // Loop through each day. var len = days.length; for (var i = 0; i < len; i++) { if (!days[i]) continue; var day = days[i].trim(); console.log('Day: ' + day); // Find the start and end day. Will match until not AZ character. var regex_day = /(monday|tuesday|wednesday|thursday|friday|saturday|sunday).*?(?![az])/g; // Something broke, so continue onto next day. This is likely caused by random text not containing a day. if (!day.match(regex_day)) console.log('Something broke with regex_day'); if (!day.match(regex_day)) continue; // Regex start_day and end_day from day. var start_day = day.match(regex_day)[0]; var end_day = day.match(regex_day)[1]; end_day = ((end_day) ? end_day : start_day); // Get indexes of start_day and end_day to be used later for days range. var start_day_index = long_days.indexOf(start_day); var end_day_index = long_days.indexOf(end_day); console.log('start_day: [' + start_day_index + '] ' + start_day); console.log('end_day: [' + end_day_index + '] ' + end_day); // Detect times from day string. var regex_time = /(\d\d:\d\d|\d{1,2})(am|pm)?/g; // Regex time from this day string, fallback to string before split. var time_match = day.match(regex_time); // Something broke, this is likely caused by no time information. Attempt to retrieve it from string. if (!time_match) { time_match = str.match(regex_time); if (!time_match) continue; // Unrecoverable at this point, continue onto next day. } var start_time = time_match[0]; var end_time = time_match[1]; // Parse time from Date.js. start_time = new Date.parse(start_time).toString('h:mm tt'); end_time = new Date.parse(end_time).toString('h:mm tt'); console.log('start_time: ' + start_time); console.log('end_time: ' + end_time); console.log(''); // Loop through days range and output to object. var len = short_days.length; for (var b = 0; b < len; b++) { if ((b >= start_day_index) && (b <= end_day_index)) { var open_day_name_hour = short_days[b] + "_open"; var close_day_name_hour = short_days[b] + "_close"; open_name_days[open_day_name_hour] = start_time; open_name_days[close_day_name_hour] = end_time; } } } console.log(open_name_days);