Skip to content

Commit f078e4b

Browse files
author
Brad Berger
committed
Fixes the dates logic to make more sense
1 parent 5a802a4 commit f078e4b

6 files changed

+127
-186
lines changed

dist/angular-material-calendar.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<md-content layout='column' layout-fill flex md-swipe-left='next()' md-swipe-right='prev()'><md-toolbar><div class='md-toolbar-tools' layout='row'><md-button ng-click='prev()' aria-label='Previous month'><md-tooltip ng-if='::tooltips()'>Previous month</md-tooltip>&laquo;</md-button><div flex></div><h2 class='calendar-md-title'><span>{{ calendar.start | date:titleFormat:timezone }}</span></h2><div flex></div><md-button ng-click='next()' aria-label='Next month'><md-tooltip ng-if='::tooltips()'>Next month</md-tooltip>&raquo;</md-button></div></md-toolbar><!-- agenda view --><md-content ng-if='weekLayout === columnWeekLayout' class='agenda'><div ng-repeat='week in calendar.weeks track by $index'><div ng-if='sameMonth(day)' ng-class='{ active: active === day }' ng-click='handleDayClick(day)' ng-repeat='day in week' layout><md-tooltip ng-if='::tooltips()'>{{ day | date:dayTooltipFormat:timezone }}</md-tooltip><div>{{ day | date:dayFormat:timezone }}</div><div flex ng-bind-html='getDayContent(day)'></div></div></div></md-content><!-- calendar view --><md-content ng-if='weekLayout !== columnWeekLayout' flex layout='column' class='calendar'><div layout='row' layout-fill class='subheader'><div layout-padding class='subheader-day' flex ng-repeat='day in calendar.weeks[0]'><md-tooltip ng-if='::tooltips()'>{{ day | date:dayLabelTooltipFormat:timezone }}</md-tooltip>{{ day | date:dayLabelFormat:timezone }}</div></div><div ng-if='week.length' ng-repeat='week in calendar.weeks track by $index' flex layout='row' layout-fill><div tabindex='{{ sameMonth(day) ? (day | date:dayFormat:timezone) : 0 }}' ng-repeat='day in week track by $index' ng-click='handleDayClick(day)' flex layout layout-padding ng-class='{&quot;disabled&quot; : ! sameMonth(day), &quot;active&quot;: isActive(day), &quot;md-whiteframe-12dp&quot;: hover || focus }' ng-focus='focus = true;' ng-blur='focus = false;' ng-mouseleave='hover = false' ng-mouseenter='hover = true'><md-tooltip ng-if='::tooltips()'>{{ day | date:dayTooltipFormat:timezone }}</md-tooltip><div>{{ day | date:dayFormat:timezone }}</div><div flex ng-bind-html='data[dayKey(day)]'></div></div></div></md-content></md-content>
1+
<md-content layout='column' layout-fill flex md-swipe-left='next()' md-swipe-right='prev()'><md-toolbar><div class='md-toolbar-tools' layout='row'><md-button ng-click='prev()' aria-label='Previous month'><md-tooltip ng-if='::tooltips()'>Previous month</md-tooltip>&laquo;</md-button><div flex></div><h2 class='calendar-md-title'><span>{{ calendar.start | date:titleFormat:timezone }}</span></h2><div flex></div><md-button ng-click='next()' aria-label='Next month'><md-tooltip ng-if='::tooltips()'>Next month</md-tooltip>&raquo;</md-button></div></md-toolbar><!-- agenda view --><md-content ng-if='weekLayout === columnWeekLayout' class='agenda'><div ng-repeat='week in calendar.weeks track by $index'><div ng-if='sameMonth(day)' ng-class='{ active: active === day }' ng-click='handleDayClick(day)' ng-repeat='day in week' layout><md-tooltip ng-if='::tooltips()'>{{ day | date:dayTooltipFormat:timezone }}</md-tooltip><div>{{ day | date:dayFormat:timezone }}</div><div flex ng-bind-html='getDayContent(day)'></div></div></div></md-content><!-- calendar view --><md-content ng-if='weekLayout !== columnWeekLayout' flex layout='column' class='calendar'><div layout='row' layout-fill class='subheader'><div layout-padding class='subheader-day' flex ng-repeat='day in calendar.weeks[0]'><md-tooltip ng-if='::tooltips()'>{{ day | date:dayLabelTooltipFormat }}</md-tooltip>{{ day | date:dayLabelFormat }}</div></div><div ng-if='week.length' ng-repeat='week in calendar.weeks track by $index' flex layout='row' layout-fill><div tabindex='{{ sameMonth(day) ? (day | date:dayFormat:timezone) : 0 }}' ng-repeat='day in week track by $index' ng-click='handleDayClick(day)' flex layout layout-padding ng-class='{&quot;disabled&quot; : ! sameMonth(day), &quot;active&quot;: isActive(day), &quot;md-whiteframe-12dp&quot;: hover || focus }' ng-focus='focus = true;' ng-blur='focus = false;' ng-mouseleave='hover = false' ng-mouseenter='hover = true'><md-tooltip ng-if='::tooltips()'>{{ day | date:dayTooltipFormat }}</md-tooltip><div>{{ day | date:dayFormat }}</div><div flex ng-bind-html='data[dayKey(day)]'></div></div></div></md-content></md-content>

dist/angular-material-calendar.js

+51-67
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
angular.module("materialCalendar", ["ngMaterial", "ngSanitize"]);
22

3-
angular.module("materialCalendar").filter("dateToGmt", function() {
4-
return function(date) {
5-
date = date || new Date();
6-
return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
7-
};
8-
});
9-
103
angular.module("materialCalendar").constant("config", {
114
version: "0.2.9",
125
debug: document.domain.indexOf("localhost") > -1
@@ -19,18 +12,18 @@ angular.module("materialCalendar").config(["config", "$logProvider", "$compilePr
1912
}
2013
}]);
2114

22-
angular.module("materialCalendar").service("Calendar", ["$filter", function($filter) {
15+
angular.module("materialCalendar").service("Calendar", [function() {
2316

2417
function Calendar(year, month, options) {
2518

26-
var now = $filter("dateToGmt")();
19+
var now = new Date();
2720

2821
this.getNumDays = function() {
29-
return $filter("dateToGmt")(new Date(
22+
return new Date(
3023
this.start.getYear(),
3124
this.start.getMonth(),
3225
0
33-
)).getDate();
26+
).getDate();
3427
};
3528

3629
this.setWeekStartsOn = function(i) {
@@ -53,90 +46,81 @@ angular.module("materialCalendar").service("Calendar", ["$filter", function($fil
5346

5447
// Get first date of month.
5548
var date = this.start;
56-
var first = new Date(date.getFullYear(), date.getMonth(), 1);
57-
58-
if (first.getDay() !== this.weekStartsOn) {
5949

60-
// Set the first day of the month.
61-
first.setDate(first.getDate() - first.getDay() + (this.weekStartsOn));
62-
63-
// Sanity check to prevent first/last week from being out of month.
64-
if (first.getDate() > 1 && first.getDate() < 7) {
65-
first.setDate(first.getDate() - 7);
66-
}
50+
// Undo the timezone offset here.
51+
var first = angular.copy(date);
6752

53+
while(first.getDay() != this.weekStartsOn) {
54+
var d = first.getDate();
55+
first.setDate(d - 1);
6856
}
6957

7058
return first;
7159

7260
};
7361

7462
this.next = function() {
75-
this.init(this.year, this.month + 1);
63+
if(this.start.getMonth() < 11) {
64+
this.init(this.start.getFullYear(), this.start.getMonth() + 1);
65+
} else {
66+
this.init(this.start.getFullYear() + 1, 0);
67+
}
7668
};
7769

7870
this.prev = function() {
79-
this.init(this.year, this.month - 1);
80-
};
81-
82-
this._isFirstDayOfWeek = function(date) {
83-
return !date.getDay();
71+
if (this.month) {
72+
this.init(this.start.getFullYear(), this.start.getMonth() - 1);
73+
return;
74+
} else {
75+
this.init(this.start.getFullYear() - 1, 11);
76+
}
8477
};
8578

8679
// Month should be the javascript indexed month, 0 is January, etc.
8780
this.init = function(year, month) {
8881

89-
if (year) {
90-
if (month) {
91-
this.year = year;
92-
this.month = month;
93-
} else {
94-
this.year = year - 1;
95-
this.month = 11;
96-
}
97-
}
82+
var now = new Date();
83+
this.year = angular.isDefined(year) ? year : now.getFullYear();
84+
this.month = angular.isDefined(month) ? month : now.getMonth();
9885

99-
// Set up the new date.
100-
this.start = $filter("dateToGmt")(new Date(this.year, this.month, 1, 0, 0));
101-
this.weeks = [];
86+
var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
87+
var monthLength = daysInMonth[this.month];
10288

103-
// Reset the month and year to handle the case of many
104-
// prev/next calls across years.
105-
this.year = this.start.getFullYear();
106-
this.month = this.start.getMonth();
89+
// Figure out if is a leap year.
90+
if (this.month == 1) {
91+
if ((this.year % 4 == 0 && this.year % 100 != 0) || this.year % 400 == 0){
92+
monthLength = 29;
93+
}
94+
}
10795

108-
var date;
109-
var first = this.getFirstDayOfCalendar();
110-
var i = 0;
111-
var _i = first.getDate() == 1 && this.getNumDays() == 28 ? 28 : 42;
96+
// First day of calendar month.
97+
this.start = new Date(this.year, this.month, 1);
98+
var date = angular.copy(this.start);
99+
while(date.getDay() != this.weekStartsOn) {
100+
date.setDate(date.getDate() - 1);
101+
monthLength++;
102+
}
112103

113-
// @todo Need to fix for up to 6 weeks.
114-
for (; i < _i; i++) {
104+
// Last day of calendar month.
105+
while(monthLength % 7 !== 0) {
106+
monthLength++;
107+
}
115108

116-
date = $filter("dateToGmt")(new Date(first.valueOf() + (i * 86400000)));
109+
this.weeks = [];
110+
for(var i = 0; i < monthLength; ++i) {
117111

118112
// Let's start a new week.
119-
// @todo If timezone changes, this goes haywire.
120113
if (i % 7 === 0) {
121114
this.weeks.push([]);
122115
}
123116

124-
// Sanity check to prevent first day of week from being in next month.
125-
if (this.weeks.length > 1 && !this.weeks[this.weeks.length - 1].length) {
126-
if (date.getMonth() !== this.month) {
127-
break;
128-
}
129-
}
130-
131-
this.weeks[this.weeks.length - 1].push(date);
117+
// Add copy of the date. If not a copy,
118+
// it will get updated shortly.
119+
this.weeks[this.weeks.length - 1].push(angular.copy(date));
132120

133-
}
121+
// Increment it.
122+
date.setDate(date.getDate() + 1);
134123

135-
// Sanity check to prevent empty weeks.
136-
for (var x = this.weeks.length - 1; x >= 0; --x) {
137-
if (this.weeks[x].length === 0) {
138-
this.weeks.splice(x, 1);
139-
}
140124
}
141125

142126
};
@@ -152,7 +136,7 @@ angular.module("materialCalendar").service("Calendar", ["$filter", function($fil
152136
angular.module("materialCalendar").directive("calendarMd", ["$compile", "$timeout", "$parse", "$http", "$q", "$filter", "$log", "Calendar", function($compile, $timeout, $parse, $http, $q, $filter, $log, Calendar) {
153137

154138
var hasCss;
155-
var defaultTemplate = "<md-content layout='column' layout-fill flex md-swipe-left='next()' md-swipe-right='prev()'><md-toolbar><div class='md-toolbar-tools' layout='row'><md-button ng-click='prev()' aria-label='Previous month'><md-tooltip ng-if='::tooltips()'>Previous month</md-tooltip>&laquo;</md-button><div flex></div><h2 class='calendar-md-title'><span>{{ calendar.start | date:titleFormat:timezone }}</span></h2><div flex></div><md-button ng-click='next()' aria-label='Next month'><md-tooltip ng-if='::tooltips()'>Next month</md-tooltip>&raquo;</md-button></div></md-toolbar><!-- agenda view --><md-content ng-if='weekLayout === columnWeekLayout' class='agenda'><div ng-repeat='week in calendar.weeks track by $index'><div ng-if='sameMonth(day)' ng-class='{ active: active === day }' ng-click='handleDayClick(day)' ng-repeat='day in week' layout><md-tooltip ng-if='::tooltips()'>{{ day | date:dayTooltipFormat:timezone }}</md-tooltip><div>{{ day | date:dayFormat:timezone }}</div><div flex ng-bind-html='getDayContent(day)'></div></div></div></md-content><!-- calendar view --><md-content ng-if='weekLayout !== columnWeekLayout' flex layout='column' class='calendar'><div layout='row' layout-fill class='subheader'><div layout-padding class='subheader-day' flex ng-repeat='day in calendar.weeks[0]'><md-tooltip ng-if='::tooltips()'>{{ day | date:dayLabelTooltipFormat:timezone }}</md-tooltip>{{ day | date:dayLabelFormat:timezone }}</div></div><div ng-if='week.length' ng-repeat='week in calendar.weeks track by $index' flex layout='row' layout-fill><div tabindex='{{ sameMonth(day) ? (day | date:dayFormat:timezone) : 0 }}' ng-repeat='day in week track by $index' ng-click='handleDayClick(day)' flex layout layout-padding ng-class='{&quot;disabled&quot; : ! sameMonth(day), &quot;active&quot;: isActive(day), &quot;md-whiteframe-12dp&quot;: hover || focus }' ng-focus='focus = true;' ng-blur='focus = false;' ng-mouseleave='hover = false' ng-mouseenter='hover = true'><md-tooltip ng-if='::tooltips()'>{{ day | date:dayTooltipFormat:timezone }}</md-tooltip><div>{{ day | date:dayFormat:timezone }}</div><div flex ng-bind-html='data[dayKey(day)]'></div></div></div></md-content></md-content>";
139+
var defaultTemplate = "<md-content layout='column' layout-fill flex md-swipe-left='next()' md-swipe-right='prev()'><md-toolbar><div class='md-toolbar-tools' layout='row'><md-button ng-click='prev()' aria-label='Previous month'><md-tooltip ng-if='::tooltips()'>Previous month</md-tooltip>&laquo;</md-button><div flex></div><h2 class='calendar-md-title'><span>{{ calendar.start | date:titleFormat:timezone }}</span></h2><div flex></div><md-button ng-click='next()' aria-label='Next month'><md-tooltip ng-if='::tooltips()'>Next month</md-tooltip>&raquo;</md-button></div></md-toolbar><!-- agenda view --><md-content ng-if='weekLayout === columnWeekLayout' class='agenda'><div ng-repeat='week in calendar.weeks track by $index'><div ng-if='sameMonth(day)' ng-class='{ active: active === day }' ng-click='handleDayClick(day)' ng-repeat='day in week' layout><md-tooltip ng-if='::tooltips()'>{{ day | date:dayTooltipFormat:timezone }}</md-tooltip><div>{{ day | date:dayFormat:timezone }}</div><div flex ng-bind-html='getDayContent(day)'></div></div></div></md-content><!-- calendar view --><md-content ng-if='weekLayout !== columnWeekLayout' flex layout='column' class='calendar'><div layout='row' layout-fill class='subheader'><div layout-padding class='subheader-day' flex ng-repeat='day in calendar.weeks[0]'><md-tooltip ng-if='::tooltips()'>{{ day | date:dayLabelTooltipFormat }}</md-tooltip>{{ day | date:dayLabelFormat }}</div></div><div ng-if='week.length' ng-repeat='week in calendar.weeks track by $index' flex layout='row' layout-fill><div tabindex='{{ sameMonth(day) ? (day | date:dayFormat:timezone) : 0 }}' ng-repeat='day in week track by $index' ng-click='handleDayClick(day)' flex layout layout-padding ng-class='{&quot;disabled&quot; : ! sameMonth(day), &quot;active&quot;: isActive(day), &quot;md-whiteframe-12dp&quot;: hover || focus }' ng-focus='focus = true;' ng-blur='focus = false;' ng-mouseleave='hover = false' ng-mouseenter='hover = true'><md-tooltip ng-if='::tooltips()'>{{ day | date:dayTooltipFormat }}</md-tooltip><div>{{ day | date:dayFormat }}</div><div flex ng-bind-html='data[dayKey(day)]'></div></div></div></md-content></md-content>";
156140

157141
var injectCss = function() {
158142
if (!hasCss) {
@@ -221,7 +205,7 @@ angular.module("materialCalendar").directive("calendarMd", ["$compile", "$timeou
221205
$scope.dayTooltipFormat = $scope.dayTooltipFormat || "fullDate";
222206

223207
$scope.sameMonth = function(date) {
224-
var d = $filter("dateToGmt")(date);
208+
var d = angular.copy(date);
225209
return d.getFullYear() === $scope.calendar.year &&
226210
d.getMonth() === $scope.calendar.month;
227211
};

src/angular-material-calendar.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ <h2 class='calendar-md-title'><span>{{ calendar.start | date:titleFormat:timezon
2828
<md-content ng-if='weekLayout !== columnWeekLayout' flex layout="column" class='calendar'>
2929
<div layout='row' layout-fill class='subheader'>
3030
<div layout-padding class='subheader-day' flex ng-repeat='day in calendar.weeks[0]'>
31-
<md-tooltip ng-if="::tooltips()">{{ day | date:dayLabelTooltipFormat:timezone }}</md-tooltip>
32-
{{ day | date:dayLabelFormat:timezone }}
31+
<md-tooltip ng-if="::tooltips()">{{ day | date:dayLabelTooltipFormat }}</md-tooltip>
32+
{{ day | date:dayLabelFormat }}
3333
</div>
3434
</div>
3535
<div ng-if='week.length' ng-repeat='week in calendar.weeks track by $index' flex layout='row' layout-fill>
3636
<div tabindex='{{ sameMonth(day) ? (day | date:dayFormat:timezone) : 0 }}' ng-repeat='day in week track by $index' ng-click='handleDayClick(day)' flex layout layout-padding ng-class='{"disabled" : ! sameMonth(day), "active": isActive(day), "md-whiteframe-12dp": hover || focus }' ng-focus='focus = true;' ng-blur='focus = false;' ng-mouseleave="hover = false" ng-mouseenter="hover = true">
37-
<md-tooltip ng-if="::tooltips()">{{ day | date:dayTooltipFormat:timezone }}</md-tooltip>
38-
<div>{{ day | date:dayFormat:timezone }}</div>
37+
<md-tooltip ng-if="::tooltips()">{{ day | date:dayTooltipFormat }}</md-tooltip>
38+
<div>{{ day | date:dayFormat }}</div>
3939
<div flex ng-bind-html='data[dayKey(day)]'></div>
4040
</div>
4141
</div>

0 commit comments

Comments
 (0)