Using Javascript to calculate Dates
June 2nd 2009 1:44 pm by Matt
This is also a part of this obnoxious and ridiculous reporting application that I’m using. I have a need to populate start date and end fields with a more user-friendly system. So I’ve got a dropdown with a few set options (Today, Last Week, Week to Date, etc.). Most of the code for these things is available around the internet, but the tricky part was calculating the weekly dates relative to the current date. IE grabbing “Week to date” and “Last Week” date ranges.
For the sake of completeness, I’ll post the select box here. Nothing special though.
1 2 3 4 5 6 7 8 9 10 | <select id="date_set" name="date_set" onChange="setDate();"> <option value="0">Set Start Date ... </option> <option value="today">Today</option> <option value="wetod">Week to Date</option> <option value="lastwe">Last Week</option> <option value="motod">Month to Date</option> <option value="lastmo">Last Month</option> <option value="yetod">Year to Date</option> <option value="lasty">Last Year</option> </select> |
And now the meat of it – the setDate function. I’ll let the comments handle the annotation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | function setDate() { // grab the boxes that we'll be manipulating var startbox = document.getElementById('startBox'); var endbox = document.getElementById('endBox'); // grab the selext box with teh value we're setting to var selbox = document.getElementById('date_set'); var now = new Date(); var month = ((now.getMonth() + 1) < 10) ? "0" + (now.getMonth() + 1) : (now.getMonth()+1); var day = (now.getDate() < 10) ? "0" + now.getDate() : now.getDate(); var year = now.getFullYear(); var today = month + "/" + day + "/" + year; switch (selbox[selbox.selectedIndex].value) { // today case "today": // this one is easy startbox.value = today; endbox.value = today; break; // the week functions are the tricky ones. We have to figure out where we're at in the week/month to // go back the appropriate amount. We also have to consider that last week may have included last month // week to date case "wetod": var weekstartdate = new Date(); // go back to the last sunday while (weekstartdate.getDay() != 0) { weekstartdate.setDate(weekstartdate.getDate()-1); } var wsmonth = ((weekstartdate.getMonth() + 1) < 10) ? "0" + (weekstartdate.getMonth() + 1) : (weekstartdate.getMonth()+1); var wsday = (weekstartdate.getDate() < 10) ? "0" + weekstartdate.getDate() : weekstartdate.getDate(); var wsyear = weekstartdate.getFullYear(); var weekstart = wsmonth + "/" + wsday + "/" + wsyear; startbox.value = weekstart; endbox.value = today; break; // last week case "lastwe": var weekenddate = new Date(); var weekstartdate = new Date(); // go back to the last Saturday (week end) while (weekenddate.getDay() != 6) { weekenddate.setDate(weekenddate.getDate()-1); weekstartdate.setDate(weekenddate.getDate()-1); } // week start is simply the end date less 7 days // for some reason that doesn't work nicely though weekstartdate.setDate(weekstartdate.getDate()-7); var wsmonth = ((weekstartdate.getMonth() + 1) < 10) ? "0" + (weekstartdate.getMonth() + 1) : (weekstartdate.getMonth()+1); var wsday = (weekstartdate.getDate() < 10) ? "0" + weekstartdate.getDate() : weekstartdate.getDate(); var wsyear = weekstartdate.getFullYear(); var wemonth = ((weekenddate.getMonth() + 1) < 10) ? "0" + (weekenddate.getMonth() + 1) : (weekenddate.getMonth()+1); var weday = (weekenddate.getDate() < 10) ? "0" + weekenddate.getDate() : weekenddate.getDate(); var weyear = weekenddate.getFullYear(); var weekstart = wsmonth + "/" + wsday + "/" + wsyear; var weekend = wemonth + "/" + weday + "/" + weyear; startbox.value = weekstart; endbox.value = weekend; break; // month to date case "motod": // also easy startbox.value = month + "/01/" + year; endbox.value = today; break; // last month case "lastmo": // we need a new month variable for month-1, also formatted correctly var lastmonth = ((month-1) < 10) ? "0" + (month-1) : (month-1); startbox.value = lastmonth + "/01/" + year; // now grab the last day of the month (30, 31? we don't know!) var moend = new Date(year, (month-1), 0); endbox.value = lastmonth + "/" + moend.getDate() + "/" + year; break; // year to date case "yetod": startbox.value = "01/01/" + year; endbox.value = today; break; // last year case "lasty": startbox.value = "01/01/" + (year-1); endbox.value = "12/31/" + (year-1); break; } } |
Again, not the most complicated of solutions, but function is what it’s all about. This code seems like it could be optimized quite a bit to me, it’d be interesting to see what people can do to reduce the line count and streamline the logic a little bit. Maybe I’ll take a crack at it sometime.
UPDATE
Thanks to Dan Miser for pointing out some bug fixes.

Thanks for the code. I found a couple of small issues, and wrote about them here.
http://www.distribucon.com/blog/PopulatingDateRanges.aspx
http://www.distribucon.com/blog/PopulatingDateRangesPart2.aspx
Thanks for the fixes Dan. I realize I had fixed those for production but I never updated the blog post. Note that there were some browser compatibility issues that I’ve fixed since the original post, so you may want to examine your code again to make sure you’ve caught the issues that I caught.
I think our interpretation of what “Last Month” means differs, because in my test cases the Last Month is populating as intended.
Thanks. I’ll definitely compare what I had vs. what you just posted.
The problem I had with “Last Month” can be seen right now. It was returning 9/31/09 as the end date when selecting last month. That isn’t exactly a valid date.
It appears that it’s picking up the last day of the month of August in that calculation, as opposed to picking up the last day of the month of September. I don’t see why there is a need to do the “month-2″ calculation there since “month-1″ is the one we need the end of, no? Are you seeing something different when selecting “Last Month”?
Anyways, thanks again for doing all of the heavy lifting on this. It’s a very nice piece of code!
Right you are. I guess it would help if I actually checked the dates it was returning. Code is updated. Glad it’s helping you out Dan!