var processSlotItem = function(cNum, sNum, sType, dateFormat, slotItem) { var slotMatches = getSlotItemRe().exec(slotItem); // If there's no day-time information, we can't generate schedule items if (!slotMatches[1] || !slotMatches[2] || !slotMatches[3]) { return []; } // Grab info from the slot item // E.g. TTh -> ['T', 'Th'] var days = slotMatches[1].match(/[A-Z][a-z]?/g); // FIXME(Sandy): Eventually worry about timezones // E.g. '2:30PM' var startTimeStr = formatTime(slotMatches[2]); // E.g. '3:20PM' var endTimeStr = formatTime(slotMatches[3]); // The day can appear in the following formats: // - '01/23/2013' // - '23/01/2013' // - '2013/01/23' // - '2013-01-07' var startDateStr = slotMatches[6]; var endDateStr = slotMatches[7]; // E.g. PHY 313, TBA var location = slotMatches[4].split(/\s+/g); var building = location[0]; // room will be undefined if the location is 'TBA' var room = location[1]; // E.g. Anna Lubiw OR Behrad Khamesee,\nJan Huissoon // If more than one prof, only keep the first one var profName = slotMatches[5].split(',')[0]; // Generate each UserScheduleItem // TODO(Sandy): Not sure if Saturday's and Sunday's are S and SU var weekdayMap = { Su: 0, M: 1, T: 2, W: 3, Th: 4, F: 5, S: 6 }; var hasClassOnDay = []; _.each(days, function(day) { hasClassOnDay[weekdayMap[day]] = true; }); var timeFormats = [dateFormat + (ampm ? ' h:mm A' : ' H:mm')]; var timeZone = "America/Toronto"; var firstStartMoment = moment.tz(startDateStr + " " + startTimeStr, timeFormats, timeZone); var firstEndMoment = moment.tz(startDateStr + " " + endTimeStr, timeFormats, timeZone); // Time delta between start and end time, in milliseconds var timeDelta = firstEndMoment - firstStartMoment; var processedSlotItems = []; // Iterate through all days in the date range var currMoment = firstStartMoment; var slotEndMoment = moment.tz(endDateStr + " " + startTimeStr, timeFormats, timeZone); while (currMoment <= slotEndMoment) { if (hasClassOnDay[currMoment.day()]) { processedSlotItems.push({ class_num: cNum, section_num: sNum, section_type: sType, start_date: currMoment.unix(), end_date: currMoment.unix() + (timeDelta / 1000.0), building: building, room: room, prof_name: profName }); } /* jshint -W101 */ // When this crosses a DST line, it only changes the date, not the time // // > moment("2013-11-02 15:00").add('days', 0).tz("America/Toronto").format() // "2013-11-02T18:00:00-04:00" // > moment("2013-11-02 15:00").add('days', 1).tz("America/Toronto").format() // "2013-11-03T18:00:00-05:00" // /* jshint +W101 */ currMoment.add('days', 1); } return processedSlotItems; };
var processSlotItem = function(cNum, sNum, sType, slotItem) { var slotMatches = getSlotItemRe().exec(slotItem); // If there's no day-time information, we can't generate schedule items if (!slotMatches[1] || !slotMatches[2] || !slotMatches[3]) { return []; } // Grab info from the slot item // E.g. TTh -> ['T', 'Th'] var days = slotMatches[1].match(/[A-Z][a-z]?/g); // FIXME(Sandy): Eventually worry about timezones // E.g. '2:30PM' var startTimeStr = formatTime(slotMatches[2]); // E.g. '3:20PM' var endTimeStr = formatTime(slotMatches[3]); // The day can appear in the following formats: // - '01/23/2013' // - '23/01/2013' // - '2013/01/23' // - '2013-01-07' var startDateStr = slotMatches[6]; var endDateStr = slotMatches[7]; // E.g. PHY 313, TBA var location = slotMatches[4].split(/\s+/g); var building = location[0]; // room will be undefined if the location is 'TBA' var room = location[1]; // E.g. Anna Lubiw OR Behrad Khamesee,\nJan Huissoon // If more than one prof, only keep the first one var profName = slotMatches[5].split(',')[0]; // Generate each UserScheduleItem // TODO(Sandy): Not sure if Saturday's and Sunday's are S and SU var weekdayMap = { Su: 0, M: 1, T: 2, W: 3, Th: 4, F: 5, S: 6 }; var hasClassOnDay = []; _.each(days, function(day) { hasClassOnDay[weekdayMap[day]] = true; }); var dateFormat; if (startDateStr.indexOf('-') > -1) { dateFormat = 'YYYY-MM-DD'; } else if ((/\d{4}\/\d{2}\/\d{2}/).exec(startDateStr)) { dateFormat = 'YYYY/MM/DD'; } else { // Could be either MM/DD/YYYY or DD/MM/YYYY. It's probably MM/DD/YYYY // but if that gives impossible results, we'll assume DD/MM/YYYY // instead. See #107. var slashRe = /(\d{2})\/(\d{2})\/(\d{4})/; var startSlashMatch = slashRe.exec(startDateStr); var startMm = parseInt(startSlashMatch[1], 10); var startYyyy = parseInt(startSlashMatch[3], 10); var endSlashMatch = slashRe.exec(endDateStr); var endMm = parseInt(endSlashMatch[1], 10); var endYyyy = parseInt(endSlashMatch[3], 10); if (startMm > 12 || endMm > 12 || (startYyyy === endYyyy && startMm > endMm)) { // Invalid month or backwards range; this must be DD/MM/YYYY. dateFormat = 'DD/MM/YYYY'; } else { // All looks good -- assume MM/DD/YYYY. dateFormat = 'MM/DD/YYYY'; } } var timeFormats = [dateFormat + (ampm ? ' h:mm A' : ' H:mm')]; var firstStartMoment = moment.tz(startDateStr + " " + startTimeStr, timeFormats, "America/Toronto"); var firstEndMoment = moment.tz(startDateStr + " " + endTimeStr, timeFormats, "America/Toronto"); // Time delta between start and end time, in milliseconds var timeDelta = firstEndMoment - firstStartMoment; var processedSlotItems = []; // Iterate through all days in the date range var currMoment = firstStartMoment; var slotEndMoment = moment(endDateStr + " " + startTimeStr, timeFormats); while (currMoment <= slotEndMoment) { if (hasClassOnDay[currMoment.day()]) { processedSlotItems.push({ class_num: cNum, section_num: sNum, section_type: sType, start_date: currMoment.unix(), end_date: moment(currMoment.unix() * 1000 + timeDelta).unix(), building: building, room: room, prof_name: profName }); } /* jshint -W101 */ // When this crosses a DST line, it only changes the date, not the time // // > moment("2013-11-02 15:00").add('days', 0).tz("America/Toronto").format() // "2013-11-02T18:00:00-04:00" // > moment("2013-11-02 15:00").add('days', 1).tz("America/Toronto").format() // "2013-11-03T18:00:00-05:00" // /* jshint +W101 */ currMoment.add('days', 1); } return processedSlotItems; };