3

My Javascript function works, but reports the wrong day of the week. Some days it works but some don't. For instance January 22nd, 1991 reports correctly as Tuesday but April 04, 1994 reports incorrectly. How is this fixed?

Also how do I implement a condition that returns "You're from the future?!" if the user provides a future date.

Here is my function so far.

    //ask user for birthday
var birthday = window.prompt("What is your birthday? (MM-DD-YYYY)", "");
var birthdayArray = birthday.split('-');
//validate entry is correct
if(birthdayArray.length !==3){
    alert("invalid date")
}
//validate if date format is correct
else{
     if(!birthdayArray[0].match(/^\d\d$/) ||
       !birthdayArray[1].match(/^\d\d$/) ||
       !birthdayArray[2].match(/^\d\d\d\d$/)){
        alert("invalid date");
     }
///take user input and find weekday
     else{var weekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday','Friday', 'Saturday'];
    var userDate = new Date(
        parseInt(birthdayArray[0])-1,
        parseInt(birthdayArray[1])-2,
        parseInt(birthdayArray[2])
    );
    var result = userDate.getDay();
    var dayName = weekDays[result];
    document.write("You were born on "+dayName);
}
}

Can this be done without completely having to redo my code?

EDIT: The -1 and -2 were me toying around with date fixes hoping I could find a golden combination, so far nothing.

Cody Carmichael
  • 177
  • 3
  • 16
  • 4
    kindly consider reading [the documentation](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date) – njzk2 Jan 30 '16 at 23:48
  • Make sure you use `parseInt(Val, 10)`, otherwise values like `08` and `09` will be parsed as if they were base-8. Also, `Date` constructor takes year-month-day, not month-day-year. – Krease Jan 30 '16 at 23:51
  • @Chris—parseInt isn't required at all. Where more than one value is supplied to the [*Date constructor*](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-date-year-month-date-hours-minutes-seconds-ms), they are converted to number anyway. – RobG Feb 01 '16 at 02:52

4 Answers4

5

Because it's backwards. Date constructor looks like-

new Date(year, month, day);

You are doing-

new Date(month, day, year);

So it should instead be-

var userDate = new Date(
        parseInt(birthdayArray[2]),
        parseInt(birthdayArray[0])-1, // dates in javascript start counting at 0
        parseInt(birthdayArray[1])
    );
micah
  • 7,596
  • 10
  • 49
  • 90
  • Make sure to use `parseInt(value, 10)` for proper parsing of `08` and `09` – Krease Jan 31 '16 at 00:23
  • 1
    @Chris I don't think that's necessary. Could you explain? – micah Jan 31 '16 at 00:36
  • Some browsers still parse strings starting with 0 as octal instead of decimal. See [this](http://stackoverflow.com/questions/3446805/parseint-returning-incorrect-value-dob-validation) related question for more details – Krease Jan 31 '16 at 00:44
  • @MicahWilliamson—you don't need to use *parseInt* at all for the Date constructor if passing more than one value. Since ES5, the default for all values passed to *parseInt* has been base 10, though some implementations are slow to catch on. – RobG Feb 01 '16 at 02:55
  • @RobG - while the standard has been updated, and if your browser is up-to-date it'll most likely work fine, it's still safer to explicitly specify base-10 in the meantime in order to avoid potential issues – Krease Feb 01 '16 at 07:17
3

Why not use Moment.js?

Take a look at this code example:

var date = moment("2016-01-31");
var weekDayNumber = date.day(); // Return the number of dayweek (0 in this case)
if (weekDayNumber === 0){console.log("Born Sunday");}
else if(weekDayNumber === 1){console.log("Born Monday");}
ronIDX
  • 758
  • 1
  • 5
  • 20
0

The fact that the code reports the correct weekday for some dates is just a coincidence. You are using the month as year, the day as month and the year as day.

Swap the values around so that you get the year, month, day order that the Date constructor expects:

var userDate = new Date(
    parseInt(birthdayArray[2], 10),
    parseInt(birthdayArray[0], 10)-1,
    parseInt(birthdayArray[1], 10)
);

Also, the parseInt takes a second parameter that is the base, which is especially important to specify when you are parsing values with a leading zero, as they are interpreted as base 8 by default.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
0

Since you've already validated the user entered the date in the form MM-DD-YYYY, you could change this

var userDate = new Date(
    parseInt(birthdayArray[0])-1,
    parseInt(birthdayArray[1])-2,
    parseInt(birthdayArray[2])
);

to this

var userDate = new Date(birthday);

Test code:

var weekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday','Friday', 'Saturday'];
var d = new Date("04-04-1994");
document.writeln("DATE: " + d + "<br>");
document.writeln("DAY OF THE WEEK: " + d.getDay() + "<br>");
var dayName = weekDays[d.getDay()];
document.write("You were born on "+dayName);

Disclaimer: Only works in browsers expecting the date format to be MM-DD-YYYY

J. Titus
  • 9,535
  • 1
  • 32
  • 45
  • That only works if the browser expects a date in the format MM-DD-YYYY. My browser for example expects a date in the format YYYY-MM-DD. – Guffa Jan 31 '16 at 00:02
  • @Guffa Thanks for the clarification. I'll update the answer with that disclaimer. – J. Titus Jan 31 '16 at 00:10
  • 1
    [relying on javascript Date(String) constructor to "do the right thing" is dangerous (depends on browser implementation), and should never be recommended due to its inconsistencies.](http://stackoverflow.com/a/2488358/836214) – Krease Jan 31 '16 at 00:21
  • @Chris—thanks for that link, I've been saying the same thing for ages, now at least I have a reference to post instead! ;-) – RobG Feb 01 '16 at 03:00