Skip to content

Commit a2a49c8

Browse files
committed
[fixed] consistent handling of end dates as _exclusive_ ranges
Ensures that date math is done the same way when calculating whether things fall within a range. All event start-end are considered exclusive ranges throughout. fixes jquense#62, fixes jquense#36, fixes jquense#32, closes jquense#67, closes jquense#65
1 parent 1c12b16 commit a2a49c8

File tree

4 files changed

+30
-22
lines changed

4 files changed

+30
-22
lines changed

src/Month.jsx

+6-8
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ import Overlay from 'react-overlays/lib/Overlay';
1919
import BackgroundCells from './BackgroundCells';
2020

2121
import { dateFormat } from './utils/propTypes';
22-
import { segStyle, inRange, eventSegments, eventLevels, sortEvents } from './utils/eventLevels';
23-
22+
import {
23+
segStyle, inRange, eventSegments
24+
, endOfRange, eventLevels, sortEvents } from './utils/eventLevels';
2425

2526
let eventsForWeek = (evts, start, end, props) =>
2627
evts.filter(e => inRange(e, start, end, props));
@@ -132,8 +133,7 @@ let MonthView = React.createClass({
132133
},
133134

134135
renderWeek(week, weekIdx, content) {
135-
let first = week[0]
136-
let last = week[week.length - 1]
136+
let { first, last } = endOfRange(week);
137137
let evts = eventsForWeek(this.props.events, week[0], week[week.length - 1], this.props)
138138

139139
evts.sort((a, b) => sortEvents(a, b, this.props))
@@ -200,8 +200,7 @@ let MonthView = React.createClass({
200200
},
201201

202202
renderRowLevel(segments, week, idx){
203-
let first = week[0]
204-
let last = week[week.length - 1]
203+
let { first, last } = endOfRange(week);
205204

206205
return (
207206
<EventRow
@@ -217,8 +216,7 @@ let MonthView = React.createClass({
217216
},
218217

219218
renderShowMore(segments, extraSegments, week, weekIdx) {
220-
let first = week[0]
221-
let last = week[week.length - 1]
219+
let { first, last } = endOfRange(week);
222220

223221
let onClick = slot => this._showMore(segments, week[slot - 1], weekIdx, slot)
224222

src/TimeGrid.jsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@ import { notify } from './utils/helpers';
2020
import { navigate } from './utils/constants';
2121
import { accessor as get } from './utils/accessors';
2222

23-
import { inRange, eventSegments, eventLevels, sortEvents, segStyle } from './utils/eventLevels';
23+
import {
24+
inRange, eventSegments, endOfRange
25+
, eventLevels, sortEvents, segStyle } from './utils/eventLevels';
2426

2527
const MIN_ROWS = 2;
2628

29+
2730
let TimeGrid = React.createClass({
2831

2932
propTypes: {
@@ -154,8 +157,7 @@ let TimeGrid = React.createClass({
154157
},
155158

156159
renderAllDayEvents(range, levels){
157-
let first = range[0]
158-
, last = range[range.length - 1];
160+
let { first, last } = endOfRange(range);
159161

160162
while (levels.length < MIN_ROWS )
161163
levels.push([])

src/utils/dates.js

+2
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ let dates = Object.assign(dateMath, {
122122
return Math.abs(+dateA - +dateB)
123123

124124
// the .round() handles an edge case
125+
// with DST where the total won't be exact
126+
// since one day in the range may be shorter/longer by an hour
125127
return Math.round(Math.abs(
126128
(+dates.startOf(dateA, unit) / MILLI[unit]) - (+dates.startOf(dateB, unit) / MILLI[unit])
127129
))

src/utils/eventLevels.js

+17-11
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
import dates from './dates';
22
import { accessor as get } from './accessors';
33

4-
export function eventSegments(event, first, last, { startAccessor, endAccessor, culture }){
4+
export function endOfRange(dateRange, unit = 'day') {
5+
return {
6+
first: dateRange[0],
7+
last: dates.add(dateRange[dateRange.length - 1], 1, unit)
8+
}
9+
}
10+
11+
export function eventSegments(event, first, last, { startAccessor, endAccessor, culture }) {
512
let slots = dates.diff(first, last, 'day')
613
let start = dates.max(dates.startOf(get(event, startAccessor), 'day'), first);
7-
let end = dates.min(dates.ceil(get(event, endAccessor), 'day'), dates.add(last, 1, 'day'))
14+
let end = dates.min(dates.ceil(get(event, endAccessor), 'day'), last)
815

16+
let padding = dates.diff(first, start, 'day');
917
let span = dates.diff(start, end, 'day');
1018

11-
span = Math.floor(Math.max(Math.min(span, slots), 1));
12-
13-
let padding = Math.floor(dates.diff(first, start, 'day'));
19+
span = Math.min(span, slots)
20+
span = Math.max(span, 1);
1421

1522
return {
1623
event,
@@ -54,14 +61,13 @@ export function eventLevels(rowSegments, limit = Infinity){
5461
}
5562

5663
export function inRange(e, start, end, { startAccessor, endAccessor }){
57-
let eStart = get(e, startAccessor)
58-
let eEnd = get(e, endAccessor)
64+
let eStart = dates.startOf(get(e, startAccessor), 'day')
65+
let eEnd = dates.ceil(get(e, endAccessor), 'day')
5966

60-
let starts = dates.inRange(eStart, start, end, 'day')
61-
let during = dates.lt(eStart, start, 'day') && dates.gt(eEnd, end, 'day')
62-
let ends = dates.lt(eStart, start) && dates.inRange(eEnd, start, end, 'day')
67+
let startsBeforeEnd = dates.lte(eStart, end, 'day')
68+
let endsAfterStart = dates.gt(eEnd, start, 'day')
6369

64-
return starts || ends || during
70+
return startsBeforeEnd && endsAfterStart
6571
}
6672

6773

0 commit comments

Comments
 (0)