如何将非标准的日期和小时文本添加到XDate对象中?

时间:2014-02-05 02:28:15

标签: javascript json node.js datetime

稍微解释一下情况;我们有一个非标准文字时间和日期字符串,它们之间存在很大差异,需要解析XDatehttp://arshaw.com/xdate/)对象中(可能有多个XDate个对象。

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

我的第一个解决方案是使用split(),但失败了。我调查的其他一些可能性包括regexpattern matchingloop text until not asciinumber picker from string等。

失败后,我很可能只会产生一些随机营业时间 避免失败尤为重要。

我不确定最佳方法会是什么。 非常感谢任何和所有帮助。


这里有一些可能性。每一行代表一种可能性。

日期和时间:

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


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

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

2 个答案:

答案 0 :(得分:2)

我建议你先把日期字符串格式化为电脑更易理解的东西(更标准化),然后你就可以轻松地扯掉你需要的部分:

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

以下代码会将您的日期字符串修改为标准格式:

["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 , ... ]

然后它将根据此标准化字符串创建对象。

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)(?![a-z])/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;
}

答案 1 :(得分:1)

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

以下是可能需要它的任何人的解决方案:

<强>预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 A-Z character.
var regex_days = /(mon|tue|wed|thu|fri|sat|sun).*?(?=[^a-z])/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 A-Z character.
  var regex_day = /(monday|tuesday|wednesday|thursday|friday|saturday|sunday).*?(?![a-z])/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);