epalla

J
u
n
02

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.

Make me popular!

    This entry was posted on Tuesday, June 2nd, 2009 at 1:44 pm and is filed under Uncategorized. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.

    4 Responses to “Using Javascript to calculate Dates”

    1. Matt says:

      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.

    2. Dan Miser says:

      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!

    3. Matt says:

      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!