Question

Day of week and time are the only two information pieces that I have. How could I construct a valid date object (for current week) using Date or moment.js?

I have tried the following but it does not seem to work:

moment('Saturday 9:00 PM').format()
// "Invalid date"
Était-ce utile?

La solution 2

If natural language parsing is your primary concern, you might consider a library that specifically focuses on that, such as Sugar.

var dt = Date.create('Saturday 9:00 AM');

Autres conseils

var date = 'Saturday 9:00 PM';
var days = [
    'Sunday',
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday'
];

var parts = date.split(/\s/);
var day   = days.indexOf(parts[0]);
var hours = Number(parts[1].match(/^(\d+)/)[1]);
var mins  = Number(parts[1].match(/:(\d+)/)[1]);
var AMPM  = parts[2];
if(AMPM == "PM" && hours<12) hours = hours+12;
if(AMPM == "AM" && hours==12) hours = hours-12;

var d    = new Date();
var dday = d.getDay();

d.setDate(d.getDate() + (day - dday));
d.setHours(hours);
d.setMinutes(mins);

FIDDLE

The following parses the OP date string format, it uses Sunday as the first day of the week. The string can include seconds if the time is "09:32:23" and days like "Mon" or "Mo" rather than the full name and is not case sensitive ('mo' == 'Mo' == 'MO' etc.). It could also use match instead of split to handle the comma in "Monday, 09:00 AM".

// Turn a string like "Saturday 9:00 PM" into a date
// Assumes day in current week, Sunday is first day of week
var parseString = (function() {

    // constants
    var reAP  = /am$/i;
    var days  = {su:0,mo:1,tu:2,we:3,th:4,fr:5,sa:6};
    var reS = /[ :]+/;
    var reNum = /^[0-9]+$/;

    return function(s) {
      var b = s.split(reS);
      var now = new Date();
      var nowDay = now.getDay();
      var tgtDay = days[s.substr(0,2).toLowerCase()];
      now.setDate(now.getDate() - nowDay + tgtDay);
      now.setHours( (reAP.test(s)? 0 : 12) + +b[1], b[2], (reNum.test(b[3])? b[3]:0 ));
      return now; 
    }
}());

You can do this by getting the week number with moment().week(), adding it to the string you already have (since saying Saturday by itself is ambiguous) and, as @Rocket Hazmat said, using moment.js's parsing formats. Note that the solution below gives you this week's Saturday (which may not be next Saturday).

time_string = "Saturday 9:00 PM";
week_number = moment().week();                 // 19
time_string = time_string + ' ' + week_number; // now you have "Saturday 9:00 PM 19"
time = moment(time_string, "dddd h A w");      // guides parsing to read a day, hour, 
                                               //      am/pm and week number

Now that we're in week 19 of 2014, that will make time: Sat May 10 2014 21:00:00 GMT -0000

For the Saturday of last week (which may not be the same as last Saturday), the following, with the extra subtraction, yields: Sat May 03 2014 21:00:00 GMT -0000

time_string = "Saturday 9:00 PM";
week_number = moment().week();                 // 19
week_number = week_number - 1;                 // 18 = 19 - 1
time_string = time_string + ' ' + week_number; // now you have "Saturday 9:00 PM 18"
time = moment(time_string, "dddd h A w");      // guides parsing to read a day, hour, 
                                               //     am/pm and week number

Note that if you do not specify a week number, it defaults to 1 and it gives you a date in January.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top