Compare commits
1 commit
master
...
fc-mightyd
Author | SHA1 | Date | |
---|---|---|---|
|
409cf6d404 |
20 changed files with 1065 additions and 526 deletions
|
@ -22,8 +22,8 @@ function Calendar(element, options, eventSources) {
|
|||
t.today = today;
|
||||
t.gotoDate = gotoDate;
|
||||
t.incrementDate = incrementDate;
|
||||
t.formatDate = function(format, date) { return formatDate(format, date, options) };
|
||||
t.formatDates = function(format, date1, date2) { return formatDates(format, date1, date2, options) };
|
||||
t.formatDate = function(date, format) { return date.toString(format, options) };
|
||||
t.formatDates = function(date1, date2, format) { return date1.toString(date2, format, options) };
|
||||
t.getDate = getDate;
|
||||
t.getView = getView;
|
||||
t.option = option;
|
||||
|
@ -49,7 +49,7 @@ function Calendar(element, options, eventSources) {
|
|||
var absoluteViewElement;
|
||||
var resizeUID = 0;
|
||||
var ignoreWindowResize = 0;
|
||||
var date = new Date();
|
||||
var date = new MightyDate();
|
||||
var events = [];
|
||||
var _dragElement;
|
||||
|
||||
|
@ -59,7 +59,13 @@ function Calendar(element, options, eventSources) {
|
|||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
setYMD(date, options.year, options.month, options.date);
|
||||
if (options.year) {
|
||||
date = new MightyDate(
|
||||
options.year,
|
||||
options.month || 0,
|
||||
options.date || 1
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function render(inc) {
|
||||
|
@ -198,7 +204,9 @@ function Calendar(element, options, eventSources) {
|
|||
}
|
||||
|
||||
var forceEventRender = false;
|
||||
if (!currentView.start || inc || date < currentView.start || date >= currentView.end) {
|
||||
if (
|
||||
!currentView.start || inc || date.before(currentView.start) || !date.before(currentView.end)
|
||||
) {
|
||||
// view must render an entire new date range (and refetch/render events)
|
||||
currentView.render(date, inc || 0); // responsible for clearing events
|
||||
setSize(true);
|
||||
|
@ -221,8 +229,8 @@ function Calendar(element, options, eventSources) {
|
|||
elementOuterWidth = element.outerWidth();
|
||||
|
||||
header.updateTitle(currentView.title);
|
||||
var today = new Date();
|
||||
if (today >= currentView.start && today < currentView.end) {
|
||||
var today = new MightyDate();
|
||||
if (!today.before(currentView.start) && today.before(currentView.end)) { // within range
|
||||
header.disableButton('today');
|
||||
}else{
|
||||
header.enableButton('today');
|
||||
|
@ -391,28 +399,32 @@ function Calendar(element, options, eventSources) {
|
|||
|
||||
|
||||
function prevYear() {
|
||||
addYears(date, -1);
|
||||
date.addYears(-1, true);
|
||||
renderView();
|
||||
}
|
||||
|
||||
|
||||
function nextYear() {
|
||||
addYears(date, 1);
|
||||
date.addYears(1, true);
|
||||
renderView();
|
||||
}
|
||||
|
||||
|
||||
function today() {
|
||||
date = new Date();
|
||||
date = new MightyDate();
|
||||
renderView();
|
||||
}
|
||||
|
||||
|
||||
function gotoDate(year, month, dateOfMonth) {
|
||||
if (year instanceof Date) {
|
||||
date = cloneDate(year); // provided 1 argument, a Date
|
||||
if (typeof year == 'object') {
|
||||
date = new MightyDate(year); // provided 1 argument, a Date or MightyDate
|
||||
}else{
|
||||
setYMD(date, year, month, dateOfMonth);
|
||||
date = new MightyDate(
|
||||
year,
|
||||
month || 0,
|
||||
dateOfMonth || 1
|
||||
);
|
||||
}
|
||||
renderView();
|
||||
}
|
||||
|
@ -420,20 +432,20 @@ function Calendar(element, options, eventSources) {
|
|||
|
||||
function incrementDate(years, months, days) {
|
||||
if (years !== undefined) {
|
||||
addYears(date, years);
|
||||
date.addYears(years, true);
|
||||
}
|
||||
if (months !== undefined) {
|
||||
addMonths(date, months);
|
||||
date.addMonths(months, true);
|
||||
}
|
||||
if (days !== undefined) {
|
||||
addDays(date, days);
|
||||
date.addDays(days);
|
||||
}
|
||||
renderView();
|
||||
}
|
||||
|
||||
|
||||
function getDate() {
|
||||
return cloneDate(date);
|
||||
return date.clone();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ function EventManager(options, _sources) {
|
|||
|
||||
|
||||
function isFetchNeeded(start, end) {
|
||||
return !rangeStart || start < rangeStart || end > rangeEnd;
|
||||
return !rangeStart || start.before(rangeStart) || end.after(rangeEnd);
|
||||
}
|
||||
|
||||
|
||||
|
@ -94,7 +94,7 @@ function EventManager(options, _sources) {
|
|||
var fetchers = fc.sourceFetchers;
|
||||
var res;
|
||||
for (i=0; i<fetchers.length; i++) {
|
||||
res = fetchers[i](source, rangeStart, rangeEnd, callback);
|
||||
res = fetchers[i](source, rangeStart.clone(), rangeEnd.clone(), callback);
|
||||
if (res === true) {
|
||||
// the fetcher is in charge. made its own async request
|
||||
return;
|
||||
|
@ -109,7 +109,7 @@ function EventManager(options, _sources) {
|
|||
if (events) {
|
||||
if ($.isFunction(events)) {
|
||||
pushLoading();
|
||||
events(cloneDate(rangeStart), cloneDate(rangeEnd), function(events) {
|
||||
events(rangeStart.clone(), rangeEnd.clone(), function(events) {
|
||||
callback(events);
|
||||
popLoading();
|
||||
});
|
||||
|
@ -208,22 +208,23 @@ function EventManager(options, _sources) {
|
|||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
function updateEvent(event) { // update an existing event
|
||||
function updateEvent(event) { // update an existing event // TODO: test thoroughly
|
||||
var i, len = cache.length, e,
|
||||
defaultEventEnd = getView().defaultEventEnd, // getView???
|
||||
startDelta = event.start - event._start,
|
||||
endDelta = event.end ?
|
||||
(event.end - (event._end || defaultEventEnd(event))) // event._end would be null if event.end
|
||||
: 0; // was null and event was just resized
|
||||
startDelta = event._start.diffMilliseconds(event.start),
|
||||
endDelta =
|
||||
event.end ?
|
||||
(event._end || defaultEventEnd(event)).diffMilliseconds(event.end) : // event._end would be null if event.end
|
||||
0; // was null and event was just resized
|
||||
for (i=0; i<len; i++) {
|
||||
e = cache[i];
|
||||
if (e._id == event._id && e != event) {
|
||||
e.start = new Date(+e.start + startDelta);
|
||||
e.start.addMilliseconds(startDelta);
|
||||
if (event.end) {
|
||||
if (e.end) {
|
||||
e.end = new Date(+e.end + endDelta);
|
||||
e.end.addMilliseconds(endDelta);
|
||||
}else{
|
||||
e.end = new Date(+defaultEventEnd(e) + endDelta);
|
||||
e.end = defaultEventEnd(e).addMilliseconds(endDelta);
|
||||
}
|
||||
}else{
|
||||
e.end = null;
|
||||
|
@ -334,12 +335,12 @@ function EventManager(options, _sources) {
|
|||
}
|
||||
delete event.date;
|
||||
}
|
||||
event._start = cloneDate(event.start = parseDate(event.start, ignoreTimezone));
|
||||
event._start = (event.start = parseDate(event.start, ignoreTimezone)).clone();
|
||||
event.end = parseDate(event.end, ignoreTimezone);
|
||||
if (event.end && event.end <= event.start) {
|
||||
if (event.end && !event.end.after(event.start)) {
|
||||
event.end = null;
|
||||
}
|
||||
event._end = event.end ? cloneDate(event.end) : null;
|
||||
event._end = event.end ? event.end.clone() : null;
|
||||
if (event.allDay === undefined) {
|
||||
event.allDay = firstDefined(source.allDayDefault, options.allDayDefault);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ js('main.js');
|
|||
js('Calendar.js');
|
||||
js('Header.js');
|
||||
js('EventManager.js');
|
||||
js('date_util.js');
|
||||
js('mightydate.js');
|
||||
js('util.js');
|
||||
|
||||
js('basic/MonthView.js');
|
||||
|
|
|
@ -19,13 +19,13 @@ function AgendaDayView(element, calendar) {
|
|||
|
||||
function render(date, delta) {
|
||||
if (delta) {
|
||||
addDays(date, delta);
|
||||
date.addDays(delta);
|
||||
if (!opt('weekends')) {
|
||||
skipWeekend(date, delta < 0 ? -1 : 1);
|
||||
}
|
||||
}
|
||||
var start = cloneDate(date, true);
|
||||
var end = addDays(cloneDate(start), 1);
|
||||
var start = date.clone().clearTime();
|
||||
var end = start.clone().addDays(1);
|
||||
t.title = formatDate(date, opt('titleFormat'));
|
||||
t.start = t.visStart = start;
|
||||
t.end = t.visEnd = end;
|
||||
|
|
|
@ -103,14 +103,14 @@ function AgendaEventRenderer() {
|
|||
var colCnt = getColCnt(),
|
||||
minMinute = getMinMinute(),
|
||||
maxMinute = getMaxMinute(),
|
||||
d = addMinutes(cloneDate(t.visStart), minMinute),
|
||||
d = t.visStart.clone().addMinutes(minMinute),
|
||||
visEventEnds = $.map(events, slotEventEnd),
|
||||
i, col,
|
||||
j, level,
|
||||
k, seg,
|
||||
segs=[];
|
||||
for (i=0; i<colCnt; i++) {
|
||||
col = stackSegs(sliceSegs(events, visEventEnds, d, addMinutes(cloneDate(d), maxMinute-minMinute)));
|
||||
col = stackSegs(sliceSegs(events, visEventEnds, d, d.clone().addMinutes(maxMinute-minMinute)));
|
||||
countForwardSegs(col);
|
||||
for (j=0; j<col.length; j++) {
|
||||
level = col[j];
|
||||
|
@ -121,7 +121,7 @@ function AgendaEventRenderer() {
|
|||
segs.push(seg);
|
||||
}
|
||||
}
|
||||
addDays(d, 1, true);
|
||||
d.addDays(1);
|
||||
}
|
||||
return segs;
|
||||
}
|
||||
|
@ -129,9 +129,9 @@ function AgendaEventRenderer() {
|
|||
|
||||
function slotEventEnd(event) {
|
||||
if (event.end) {
|
||||
return cloneDate(event.end);
|
||||
return event.end.clone();
|
||||
}else{
|
||||
return addMinutes(cloneDate(event.start), opt('defaultEventMinutes'));
|
||||
return event.start.clone().addMinutes(opt('defaultEventMinutes'));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -383,8 +383,8 @@ function AgendaEventRenderer() {
|
|||
if (!cell.row) {
|
||||
// on full-days
|
||||
renderDayOverlay(
|
||||
addDays(cloneDate(event.start), dayDelta),
|
||||
addDays(exclEndDay(event), dayDelta)
|
||||
event.start.clone().addDays(dayDelta).clearTime(),
|
||||
exclEndDay(event).addDays(dayDelta).clearTime()
|
||||
);
|
||||
resetElement();
|
||||
}else{
|
||||
|
@ -396,8 +396,7 @@ function AgendaEventRenderer() {
|
|||
setOuterHeight(
|
||||
eventElement,
|
||||
slotHeight * Math.round(
|
||||
(event.end ? ((event.end - event.start) / MINUTE_MS) : opt('defaultEventMinutes'))
|
||||
/ opt('slotMinutes')
|
||||
(event.end ? event.start.diffMinutes(event.end) : opt('defaultEventMinutes')) / opt('slotMinutes')
|
||||
)
|
||||
);
|
||||
eventElement.draggable('option', 'grid', [colWidth, 1]);
|
||||
|
@ -490,8 +489,8 @@ function AgendaEventRenderer() {
|
|||
eventElement.draggable('option', 'grid', null);
|
||||
}
|
||||
renderDayOverlay(
|
||||
addDays(cloneDate(event.start), dayDelta),
|
||||
addDays(exclEndDay(event), dayDelta)
|
||||
event.start.clone().addDays(dayDelta).clearTime(),
|
||||
exclEndDay(event).addDays(dayDelta).clearTime()
|
||||
);
|
||||
}else{
|
||||
// on slots
|
||||
|
@ -527,10 +526,10 @@ function AgendaEventRenderer() {
|
|||
}
|
||||
});
|
||||
function updateTimeText(minuteDelta) {
|
||||
var newStart = addMinutes(cloneDate(event.start), minuteDelta);
|
||||
var newStart = event.start.clone().addMinutes(minuteDelta);
|
||||
var newEnd;
|
||||
if (event.end) {
|
||||
newEnd = addMinutes(cloneDate(event.end), minuteDelta);
|
||||
newEnd = event.end.clone().addMinutes(minuteDelta);
|
||||
}
|
||||
timeElement.text(formatDates(newStart, newEnd, opt('timeFormat')));
|
||||
}
|
||||
|
@ -572,7 +571,7 @@ function AgendaEventRenderer() {
|
|||
formatDates(
|
||||
event.start,
|
||||
(!slotDelta && !event.end) ? null : // no change, so don't display time range
|
||||
addMinutes(eventEnd(event), opt('slotMinutes')*slotDelta),
|
||||
eventEnd(event).addMinutes(opt('slotMinutes')*slotDelta),
|
||||
opt('timeFormat')
|
||||
)
|
||||
);
|
||||
|
|
|
@ -273,11 +273,11 @@ function AgendaView(element, calendar, viewName) {
|
|||
s =
|
||||
"<table class='fc-agenda-slots' style='width:100%' cellspacing='0'>" +
|
||||
"<tbody>";
|
||||
d = zeroDate();
|
||||
maxd = addMinutes(cloneDate(d), maxMinute);
|
||||
addMinutes(d, minMinute);
|
||||
d = t.visStart.clone();
|
||||
maxd = d.clone().addMinutes(maxMinute);
|
||||
d.addMinutes(minMinute);
|
||||
slotCnt = 0;
|
||||
for (i=0; d < maxd; i++) {
|
||||
for (i=0; d.before(maxd); i++) {
|
||||
minutes = d.getMinutes();
|
||||
s +=
|
||||
"<tr class='fc-slot" + i + ' ' + (!minutes ? '' : 'fc-minor') + "'>" +
|
||||
|
@ -288,7 +288,7 @@ function AgendaView(element, calendar, viewName) {
|
|||
"<div style='position:relative'> </div>" +
|
||||
"</td>" +
|
||||
"</tr>";
|
||||
addMinutes(d, opt('slotMinutes'));
|
||||
d.addMinutes(opt('slotMinutes'));
|
||||
slotCnt++;
|
||||
}
|
||||
s +=
|
||||
|
@ -309,13 +309,13 @@ function AgendaView(element, calendar, viewName) {
|
|||
var headCell;
|
||||
var bodyCell;
|
||||
var date;
|
||||
var today = clearTime(new Date());
|
||||
var today = new MightyDate().clearTime();
|
||||
for (i=0; i<colCnt; i++) {
|
||||
date = colDate(i);
|
||||
headCell = dayHeadCells.eq(i);
|
||||
headCell.html(formatDate(date, colFormat));
|
||||
bodyCell = dayBodyCells.eq(i);
|
||||
if (+date == +today) {
|
||||
if (date.equals(today)) {
|
||||
bodyCell.addClass(tm + '-state-highlight fc-today');
|
||||
}else{
|
||||
bodyCell.removeClass(tm + '-state-highlight fc-today');
|
||||
|
@ -394,8 +394,8 @@ function AgendaView(element, calendar, viewName) {
|
|||
|
||||
|
||||
function resetScroll() {
|
||||
var d0 = zeroDate();
|
||||
var scrollDate = cloneDate(d0);
|
||||
var d0 = t.visStart.clone();
|
||||
var scrollDate = d0.clone();
|
||||
scrollDate.setHours(opt('firstHour'));
|
||||
var top = timePosition(d0, scrollDate) + 1; // +1 for the border
|
||||
function scroll() {
|
||||
|
@ -457,17 +457,18 @@ function AgendaView(element, calendar, viewName) {
|
|||
|
||||
|
||||
function renderDayOverlay(startDate, endDate, refreshCoordinateGrid) { // endDate is exclusive
|
||||
// TODO: get straight whether caller needs to do clearTime or not
|
||||
if (refreshCoordinateGrid) {
|
||||
coordinateGrid.build();
|
||||
}
|
||||
var visStart = cloneDate(t.visStart);
|
||||
var visStart = t.visStart;
|
||||
var startCol, endCol;
|
||||
if (rtl) {
|
||||
startCol = dayDiff(endDate, visStart)*dis+dit+1;
|
||||
endCol = dayDiff(startDate, visStart)*dis+dit+1;
|
||||
startCol = visStart.diffDays(endDate)*dis+dit+1;
|
||||
endCol = visStart.diffDays(startDate)*dis+dit+1;
|
||||
}else{
|
||||
startCol = dayDiff(startDate, visStart);
|
||||
endCol = dayDiff(endDate, visStart);
|
||||
startCol = visStart.diffDays(startDate);
|
||||
endCol = visStart.diffDays(endDate);
|
||||
}
|
||||
startCol = Math.max(0, startCol);
|
||||
endCol = Math.min(colCnt, endCol);
|
||||
|
@ -486,12 +487,12 @@ function AgendaView(element, calendar, viewName) {
|
|||
|
||||
|
||||
function renderSlotOverlay(overlayStart, overlayEnd) {
|
||||
var dayStart = cloneDate(t.visStart);
|
||||
var dayEnd = addDays(cloneDate(dayStart), 1);
|
||||
var dayStart = t.visStart.clone();
|
||||
var dayEnd = dayStart.clone().addDays(1);
|
||||
for (var i=0; i<colCnt; i++) {
|
||||
var stretchStart = new Date(Math.max(dayStart, overlayStart));
|
||||
var stretchEnd = new Date(Math.min(dayEnd, overlayEnd));
|
||||
if (stretchStart < stretchEnd) {
|
||||
var stretchStart = overlayStart.before(dayStart) ? dayStart : overlayStart;
|
||||
var stretchEnd = overlayEnd.after(dayEnd) ? dayEnd : overlayEnd;
|
||||
if (stretchStart.before(stretchEnd)) {
|
||||
var col = i*dis+dit;
|
||||
var rect = coordinateGrid.rect(0, col, 0, col, slotContent); // only use it for horizontal coords
|
||||
var top = timePosition(dayStart, stretchStart);
|
||||
|
@ -502,8 +503,8 @@ function AgendaView(element, calendar, viewName) {
|
|||
renderOverlay(rect, slotContent)
|
||||
);
|
||||
}
|
||||
addDays(dayStart, 1);
|
||||
addDays(dayEnd, 1);
|
||||
dayStart.addDays(1);
|
||||
dayEnd.addDays(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -567,7 +568,7 @@ function AgendaView(element, calendar, viewName) {
|
|||
|
||||
function dateCell(date) { // "cell" terminology is now confusing
|
||||
return {
|
||||
row: Math.floor(dayDiff(date, t.visStart) / 7),
|
||||
row: t.visStart.diffWeeks(date),
|
||||
col: dayOfWeekCol(date.getDay())
|
||||
};
|
||||
}
|
||||
|
@ -580,14 +581,14 @@ function AgendaView(element, calendar, viewName) {
|
|||
slotIndex--;
|
||||
}
|
||||
if (slotIndex >= 0) {
|
||||
addMinutes(d, minMinute + slotIndex * opt('slotMinutes'));
|
||||
d.addMinutes(minMinute + slotIndex * opt('slotMinutes'));
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
function colDate(col) { // returns dates with 00:00:00
|
||||
return addDays(cloneDate(t.visStart), col*dis+dit);
|
||||
return t.visStart.clone().addDays(col*dis+dit);
|
||||
}
|
||||
|
||||
|
||||
|
@ -605,11 +606,11 @@ function AgendaView(element, calendar, viewName) {
|
|||
|
||||
// get the Y coordinate of the given time on the given day (both Date objects)
|
||||
function timePosition(day, time) { // both date objects. day holds 00:00 of current day
|
||||
day = cloneDate(day, true);
|
||||
if (time < addMinutes(cloneDate(day), minMinute)) {
|
||||
day = day.clone().clearTime();
|
||||
if (time.before(day.clone().addMinutes(minMinute))) {
|
||||
return 0;
|
||||
}
|
||||
if (time >= addMinutes(cloneDate(day), maxMinute)) {
|
||||
if (!time.before(day.clone().addMinutes(maxMinute))) {
|
||||
return slotTable.height();
|
||||
}
|
||||
var slotMinutes = opt('slotMinutes'),
|
||||
|
@ -639,11 +640,11 @@ function AgendaView(element, calendar, viewName) {
|
|||
|
||||
|
||||
function defaultEventEnd(event) {
|
||||
var start = cloneDate(event.start);
|
||||
var start = event.start.clone();
|
||||
if (event.allDay) {
|
||||
return start;
|
||||
}
|
||||
return addMinutes(start, opt('defaultEventMinutes'));
|
||||
return start.addMinutes(opt('defaultEventMinutes'));
|
||||
}
|
||||
|
||||
|
||||
|
@ -654,16 +655,20 @@ function AgendaView(element, calendar, viewName) {
|
|||
|
||||
function defaultSelectionEnd(startDate, allDay) {
|
||||
if (allDay) {
|
||||
return cloneDate(startDate);
|
||||
return startDate.clone();
|
||||
}
|
||||
return addMinutes(cloneDate(startDate), opt('slotMinutes'));
|
||||
return startDate.clone().addMinutes(opt('slotMinutes'));
|
||||
}
|
||||
|
||||
|
||||
function renderSelection(startDate, endDate, allDay) { // only for all-day
|
||||
if (allDay) {
|
||||
if (opt('allDaySlot')) {
|
||||
renderDayOverlay(startDate, addDays(cloneDate(endDate), 1), true);
|
||||
renderDayOverlay(
|
||||
startDate.clone().clearTime(),
|
||||
endDate.clone().addDays(1).clearTime(), // TODO: use util
|
||||
true
|
||||
);
|
||||
}
|
||||
}else{
|
||||
renderSlotSelection(startDate, endDate);
|
||||
|
@ -675,7 +680,7 @@ function AgendaView(element, calendar, viewName) {
|
|||
var helperOption = opt('selectHelper');
|
||||
coordinateGrid.build();
|
||||
if (helperOption) {
|
||||
var col = dayDiff(startDate, t.visStart) * dis + dit;
|
||||
var col = t.visStart.diffDays(startDate) * dis + dit;
|
||||
if (col >= 0 && col < colCnt) { // only works when times are on same day
|
||||
var rect = coordinateGrid.rect(0, col, 0, col, slotContent); // only for horizontal coords
|
||||
var top = timePosition(startDate, startDate);
|
||||
|
@ -743,9 +748,9 @@ function AgendaView(element, calendar, viewName) {
|
|||
var d2 = cellDate(cell);
|
||||
dates = [
|
||||
d1,
|
||||
addMinutes(cloneDate(d1), opt('slotMinutes')),
|
||||
d1.clone().addMinutes(opt('slotMinutes')),
|
||||
d2,
|
||||
addMinutes(cloneDate(d2), opt('slotMinutes'))
|
||||
d2.clone().addMinutes(opt('slotMinutes'))
|
||||
].sort(cmp);
|
||||
renderSlotSelection(dates[0], dates[3]);
|
||||
}else{
|
||||
|
@ -755,7 +760,7 @@ function AgendaView(element, calendar, viewName) {
|
|||
$(document).one('mouseup', function(ev) {
|
||||
hoverListener.stop();
|
||||
if (dates) {
|
||||
if (+dates[0] == +dates[1]) {
|
||||
if (dates[0].equals(dates[1])) {
|
||||
reportDayClick(dates[0], false, ev);
|
||||
}
|
||||
reportSelection(dates[0], dates[3], false, ev);
|
||||
|
@ -766,7 +771,7 @@ function AgendaView(element, calendar, viewName) {
|
|||
|
||||
|
||||
function reportDayClick(date, allDay, ev) {
|
||||
trigger('dayClick', dayBodyCells[dayOfWeekCol(date.getDay())], date, allDay, ev);
|
||||
trigger('dayClick', dayBodyCells[dayOfWeekCol(date.getDay())], date.clone(), allDay, ev);
|
||||
}
|
||||
|
||||
|
||||
|
@ -783,7 +788,7 @@ function AgendaView(element, calendar, viewName) {
|
|||
renderCellOverlay(cell.row, cell.col, cell.row, cell.col);
|
||||
}else{
|
||||
var d1 = cellDate(cell);
|
||||
var d2 = addMinutes(cloneDate(d1), opt('defaultEventMinutes'));
|
||||
var d2 = d1.clone().addMinutes(opt('defaultEventMinutes'));
|
||||
renderSlotOverlay(d1, d2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,12 +19,12 @@ function AgendaWeekView(element, calendar) {
|
|||
|
||||
function render(date, delta) {
|
||||
if (delta) {
|
||||
addDays(date, delta * 7);
|
||||
date.addWeeks(delta);
|
||||
}
|
||||
var start = addDays(cloneDate(date), -((date.getDay() - opt('firstDay') + 7) % 7));
|
||||
var end = addDays(cloneDate(start), 7);
|
||||
var visStart = cloneDate(start);
|
||||
var visEnd = cloneDate(end);
|
||||
var start = date.clone().clearTime().addDays(-((date.getDay() - opt('firstDay') + 7) % 7));
|
||||
var end = start.clone().addWeeks(1);
|
||||
var visStart = start.clone();
|
||||
var visEnd = end.clone();
|
||||
var weekends = opt('weekends');
|
||||
if (!weekends) {
|
||||
skipWeekend(visStart);
|
||||
|
@ -32,7 +32,7 @@ function AgendaWeekView(element, calendar) {
|
|||
}
|
||||
t.title = formatDates(
|
||||
visStart,
|
||||
addDays(cloneDate(visEnd), -1),
|
||||
visEnd.clone().addDays(-1),
|
||||
opt('titleFormat')
|
||||
);
|
||||
t.start = start;
|
||||
|
|
|
@ -22,14 +22,14 @@ function BasicDayView(element, calendar) {
|
|||
|
||||
function render(date, delta) {
|
||||
if (delta) {
|
||||
addDays(date, delta);
|
||||
date.addDays(delta);
|
||||
if (!opt('weekends')) {
|
||||
skipWeekend(date, delta < 0 ? -1 : 1);
|
||||
}
|
||||
}
|
||||
t.title = formatDate(date, opt('titleFormat'));
|
||||
t.start = t.visStart = cloneDate(date, true);
|
||||
t.end = t.visEnd = addDays(cloneDate(t.start), 1);
|
||||
t.start = t.visStart = date.clone().clearTime();
|
||||
t.end = t.visEnd = t.start.clone().addDays(1);
|
||||
renderBasic(1, 1, 1, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,8 +53,8 @@ function BasicEventRenderer() {
|
|||
function compileSegs(events) {
|
||||
var rowCnt = getRowCnt(),
|
||||
colCnt = getColCnt(),
|
||||
d1 = cloneDate(t.visStart),
|
||||
d2 = addDays(cloneDate(d1), colCnt),
|
||||
d1 = t.visStart.clone(),
|
||||
d2 = d1.clone().addDays(colCnt),
|
||||
visEventsEnds = $.map(events, exclEndDay),
|
||||
i, row,
|
||||
j, level,
|
||||
|
@ -71,8 +71,8 @@ function BasicEventRenderer() {
|
|||
segs.push(seg);
|
||||
}
|
||||
}
|
||||
addDays(d1, 7);
|
||||
addDays(d2, 7);
|
||||
d1.addWeeks(1);
|
||||
d2.addWeeks(1);
|
||||
}
|
||||
return segs;
|
||||
}
|
||||
|
@ -113,8 +113,8 @@ function BasicEventRenderer() {
|
|||
//setOverflowHidden(true);
|
||||
dayDelta = rowDelta*7 + colDelta * (opt('isRTL') ? -1 : 1);
|
||||
renderDayOverlay(
|
||||
addDays(cloneDate(event.start), dayDelta),
|
||||
addDays(exclEndDay(event), dayDelta)
|
||||
event.start.clone().addDays(dayDelta).clearTime(),
|
||||
exclEndDay(event).addDays(dayDelta).clearTime()
|
||||
);
|
||||
}else{
|
||||
//setOverflowHidden(false);
|
||||
|
|
|
@ -184,7 +184,7 @@ function BasicView(element, calendar, viewName) {
|
|||
function updateCells(firstTime) {
|
||||
var dowDirty = firstTime || rowCnt == 1; // could the cells' day-of-weeks need updating?
|
||||
var month = t.start.getMonth();
|
||||
var today = clearTime(new Date());
|
||||
var today = new MightyDate().clearTime();
|
||||
var cell;
|
||||
var date;
|
||||
var row;
|
||||
|
@ -206,7 +206,7 @@ function BasicView(element, calendar, viewName) {
|
|||
}else{
|
||||
cell.addClass('fc-other-month');
|
||||
}
|
||||
if (+date == +today) {
|
||||
if (date.equals(today)) {
|
||||
cell.addClass(tm + '-state-highlight fc-today');
|
||||
}else{
|
||||
cell.removeClass(tm + '-state-highlight fc-today');
|
||||
|
@ -296,29 +296,30 @@ function BasicView(element, calendar, viewName) {
|
|||
|
||||
|
||||
function renderDayOverlay(overlayStart, overlayEnd, refreshCoordinateGrid) { // overlayEnd is exclusive
|
||||
// TODO: get straight whether caller needs to do clearTime or not
|
||||
if (refreshCoordinateGrid) {
|
||||
coordinateGrid.build();
|
||||
}
|
||||
var rowStart = cloneDate(t.visStart);
|
||||
var rowEnd = addDays(cloneDate(rowStart), colCnt);
|
||||
var rowStart = t.visStart.clone();
|
||||
var rowEnd = rowStart.clone().addDays(colCnt);
|
||||
for (var i=0; i<rowCnt; i++) {
|
||||
var stretchStart = new Date(Math.max(rowStart, overlayStart));
|
||||
var stretchEnd = new Date(Math.min(rowEnd, overlayEnd));
|
||||
if (stretchStart < stretchEnd) {
|
||||
var stretchStart = overlayStart.before(rowStart) ? rowStart : overlayStart;
|
||||
var stretchEnd = overlayEnd.after(rowEnd) ? rowEnd : overlayEnd;
|
||||
if (stretchStart.before(stretchEnd)) {
|
||||
var colStart, colEnd;
|
||||
if (rtl) {
|
||||
colStart = dayDiff(stretchEnd, rowStart)*dis+dit+1;
|
||||
colEnd = dayDiff(stretchStart, rowStart)*dis+dit+1;
|
||||
colStart = rowStart.diffDays(stretchEnd)*dis+dit+1;
|
||||
colEnd = rowStart.diffDays(stretchStart)*dis+dit+1;
|
||||
}else{
|
||||
colStart = dayDiff(stretchStart, rowStart);
|
||||
colEnd = dayDiff(stretchEnd, rowStart);
|
||||
colStart = rowStart.diffDays(stretchStart);
|
||||
colEnd = rowStart.diffDays(stretchEnd);
|
||||
}
|
||||
dayBind(
|
||||
renderCellOverlay(i, colStart, i, colEnd-1)
|
||||
);
|
||||
}
|
||||
addDays(rowStart, 7);
|
||||
addDays(rowEnd, 7);
|
||||
rowStart.addWeeks(1);
|
||||
rowEnd.addWeeks(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -335,12 +336,16 @@ function BasicView(element, calendar, viewName) {
|
|||
|
||||
|
||||
function defaultSelectionEnd(startDate, allDay) {
|
||||
return cloneDate(startDate);
|
||||
return startDate.clone();
|
||||
}
|
||||
|
||||
|
||||
function renderSelection(startDate, endDate, allDay) {
|
||||
renderDayOverlay(startDate, addDays(cloneDate(endDate), 1), true); // rebuild every time???
|
||||
renderDayOverlay(
|
||||
startDate.clone().clearTime(),
|
||||
endDate.clone().addDays(1).clearTime(), // TODO: use util
|
||||
true // rebuild every time???
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
@ -352,7 +357,7 @@ function BasicView(element, calendar, viewName) {
|
|||
function reportDayClick(date, allDay, ev) {
|
||||
var cell = dateCell(date);
|
||||
var _element = bodyCells[cell.row*colCnt + cell.col];
|
||||
trigger('dayClick', _element, date, allDay, ev);
|
||||
trigger('dayClick', _element, date.clone(), allDay, ev);
|
||||
}
|
||||
|
||||
|
||||
|
@ -387,7 +392,7 @@ function BasicView(element, calendar, viewName) {
|
|||
|
||||
|
||||
function defaultEventEnd(event) {
|
||||
return cloneDate(event.start);
|
||||
return event.start.clone();
|
||||
}
|
||||
|
||||
|
||||
|
@ -440,7 +445,7 @@ function BasicView(element, calendar, viewName) {
|
|||
|
||||
function dateCell(date) {
|
||||
return {
|
||||
row: Math.floor(dayDiff(date, t.visStart) / 7),
|
||||
row: t.visStart.diffWeeks(date),
|
||||
col: dayOfWeekCol(date.getDay())
|
||||
};
|
||||
}
|
||||
|
@ -452,7 +457,7 @@ function BasicView(element, calendar, viewName) {
|
|||
|
||||
|
||||
function _cellDate(row, col) {
|
||||
return addDays(cloneDate(t.visStart), row*7 + col*dis+dit);
|
||||
return t.visStart.clone().addDays(row*7 + col*dis+dit);
|
||||
// what about weekends in middle of week?
|
||||
}
|
||||
|
||||
|
|
|
@ -19,12 +19,12 @@ function BasicWeekView(element, calendar) {
|
|||
|
||||
function render(date, delta) {
|
||||
if (delta) {
|
||||
addDays(date, delta * 7);
|
||||
date.addWeeks(delta);
|
||||
}
|
||||
var start = addDays(cloneDate(date), -((date.getDay() - opt('firstDay') + 7) % 7));
|
||||
var end = addDays(cloneDate(start), 7);
|
||||
var visStart = cloneDate(start);
|
||||
var visEnd = cloneDate(end);
|
||||
var start = date.clone().clearTime().addDays(-((date.getDay() - opt('firstDay') + 7) % 7));
|
||||
var end = start.clone().addWeeks(1);
|
||||
var visStart = start.clone();
|
||||
var visEnd = end.clone();
|
||||
var weekends = opt('weekends');
|
||||
if (!weekends) {
|
||||
skipWeekend(visStart);
|
||||
|
@ -32,7 +32,7 @@ function BasicWeekView(element, calendar) {
|
|||
}
|
||||
t.title = formatDates(
|
||||
visStart,
|
||||
addDays(cloneDate(visEnd), -1),
|
||||
visEnd.clone().addDays(-1),
|
||||
opt('titleFormat')
|
||||
);
|
||||
t.start = start;
|
||||
|
|
|
@ -19,25 +19,23 @@ function MonthView(element, calendar) {
|
|||
|
||||
function render(date, delta) {
|
||||
if (delta) {
|
||||
addMonths(date, delta);
|
||||
date.setDate(1);
|
||||
date.setDate(1).addMonths(delta);
|
||||
}
|
||||
var start = cloneDate(date, true);
|
||||
start.setDate(1);
|
||||
var end = addMonths(cloneDate(start), 1);
|
||||
var visStart = cloneDate(start);
|
||||
var visEnd = cloneDate(end);
|
||||
var start = date.clone().setDate(1).clearTime();
|
||||
var end = start.clone().addMonths(1);
|
||||
var visStart = start.clone();
|
||||
var visEnd = end.clone();
|
||||
var firstDay = opt('firstDay');
|
||||
var nwe = opt('weekends') ? 0 : 1;
|
||||
if (nwe) {
|
||||
skipWeekend(visStart);
|
||||
skipWeekend(visEnd, -1, true);
|
||||
}
|
||||
addDays(visStart, -((visStart.getDay() - Math.max(firstDay, nwe) + 7) % 7));
|
||||
addDays(visEnd, (7 - visEnd.getDay() + Math.max(firstDay, nwe)) % 7);
|
||||
var rowCnt = Math.round((visEnd - visStart) / (DAY_MS * 7));
|
||||
visStart.addDays(-((visStart.getDay() - Math.max(firstDay, nwe) + 7) % 7));
|
||||
visEnd.addDays((7 - visEnd.getDay() + Math.max(firstDay, nwe)) % 7);
|
||||
var rowCnt = visStart.diffWeeks(visEnd);
|
||||
if (opt('weekMode') == 'fixed') {
|
||||
addDays(visEnd, (6 - rowCnt) * 7);
|
||||
visEnd.addWeeks(6 - rowCnt);
|
||||
rowCnt = 6;
|
||||
}
|
||||
t.title = formatDate(start, opt('titleFormat'));
|
||||
|
|
|
@ -438,7 +438,7 @@ function DayEventRenderer() {
|
|||
}
|
||||
}
|
||||
dayDelta = (r*7 + c*dis+dit) - (origCell.row*7 + origCell.col*dis+dit);
|
||||
var newEnd = addDays(eventEnd(event), dayDelta, true);
|
||||
var newEnd = eventEnd(event).addDays(dayDelta);
|
||||
if (dayDelta) {
|
||||
eventCopy.end = newEnd;
|
||||
var oldHelpers = helpers;
|
||||
|
@ -456,7 +456,11 @@ function DayEventRenderer() {
|
|||
}
|
||||
}
|
||||
clearOverlays();
|
||||
renderDayOverlay(event.start, addDays(cloneDate(newEnd), 1)); // coordinate grid already rebuild at hoverListener.start
|
||||
renderDayOverlay(
|
||||
event.start.clone().clearTime(),
|
||||
newEnd.clone().addDays(1).clearTime() // TODO: use util
|
||||
);
|
||||
// coordinate grid already rebuild at hoverListener.start
|
||||
}
|
||||
}, ev);
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ function SelectionManager() {
|
|||
|
||||
function reportSelection(startDate, endDate, allDay, ev) {
|
||||
selected = true;
|
||||
trigger('select', null, startDate, endDate, allDay, ev);
|
||||
trigger('select', null, startDate.clone(), endDate.clone(), allDay, ev);
|
||||
}
|
||||
|
||||
|
||||
|
@ -85,7 +85,7 @@ function SelectionManager() {
|
|||
$(document).one('mouseup', function(ev) {
|
||||
hoverListener.stop();
|
||||
if (dates) {
|
||||
if (+dates[0] == +dates[1]) {
|
||||
if (dates[0].equals(dates[1])) {
|
||||
reportDayClick(dates[0], true, ev);
|
||||
}
|
||||
reportSelection(dates[0], dates[1], true, ev);
|
||||
|
|
|
@ -102,7 +102,7 @@ function View(element, calendar, viewName) {
|
|||
|
||||
// returns a Date object for an event's end
|
||||
function eventEnd(event) {
|
||||
return event.end ? cloneDate(event.end) : defaultEventEnd(event);
|
||||
return event.end ? event.end.clone() : defaultEventEnd(event);
|
||||
}
|
||||
|
||||
|
||||
|
@ -232,9 +232,9 @@ function View(element, calendar, viewName) {
|
|||
if (allDay !== undefined) {
|
||||
e.allDay = allDay;
|
||||
}
|
||||
addMinutes(addDays(e.start, dayDelta, true), minuteDelta);
|
||||
e.start.addDays(dayDelta).addMinutes(minuteDelta);
|
||||
if (e.end) {
|
||||
e.end = addMinutes(addDays(e.end, dayDelta, true), minuteDelta);
|
||||
e.end.addDays(dayDelta).addMinutes(minuteDelta);
|
||||
}
|
||||
normalizeEvent(e, options);
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ function View(element, calendar, viewName) {
|
|||
minuteDelta = minuteDelta || 0;
|
||||
for (var e, len=events.length, i=0; i<len; i++) {
|
||||
e = events[i];
|
||||
e.end = addMinutes(addDays(eventEnd(e), dayDelta, true), minuteDelta);
|
||||
e.end = eventEnd(e).addDays(dayDelta).addMinutes(minuteDelta);
|
||||
normalizeEvent(e, options);
|
||||
}
|
||||
}
|
||||
|
|
357
src/date_util.js
357
src/date_util.js
|
@ -1,357 +0,0 @@
|
|||
|
||||
|
||||
fc.addDays = addDays;
|
||||
fc.cloneDate = cloneDate;
|
||||
fc.parseDate = parseDate;
|
||||
fc.parseISO8601 = parseISO8601;
|
||||
fc.parseTime = parseTime;
|
||||
fc.formatDate = formatDate;
|
||||
fc.formatDates = formatDates;
|
||||
|
||||
|
||||
|
||||
/* Date Math
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
var dayIDs = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'],
|
||||
DAY_MS = 86400000,
|
||||
HOUR_MS = 3600000,
|
||||
MINUTE_MS = 60000;
|
||||
|
||||
|
||||
function addYears(d, n, keepTime) {
|
||||
d.setFullYear(d.getFullYear() + n);
|
||||
if (!keepTime) {
|
||||
clearTime(d);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
function addMonths(d, n, keepTime) { // prevents day overflow/underflow
|
||||
if (+d) { // prevent infinite looping on invalid dates
|
||||
var m = d.getMonth() + n,
|
||||
check = cloneDate(d);
|
||||
check.setDate(1);
|
||||
check.setMonth(m);
|
||||
d.setMonth(m);
|
||||
if (!keepTime) {
|
||||
clearTime(d);
|
||||
}
|
||||
while (d.getMonth() != check.getMonth()) {
|
||||
d.setDate(d.getDate() + (d < check ? 1 : -1));
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
function addDays(d, n, keepTime) { // deals with daylight savings
|
||||
if (+d) {
|
||||
var dd = d.getDate() + n,
|
||||
check = cloneDate(d);
|
||||
check.setHours(9); // set to middle of day
|
||||
check.setDate(dd);
|
||||
d.setDate(dd);
|
||||
if (!keepTime) {
|
||||
clearTime(d);
|
||||
}
|
||||
fixDate(d, check);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
function fixDate(d, check) { // force d to be on check's YMD, for daylight savings purposes
|
||||
if (+d) { // prevent infinite looping on invalid dates
|
||||
while (d.getDate() != check.getDate()) {
|
||||
d.setTime(+d + (d < check ? 1 : -1) * HOUR_MS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function addMinutes(d, n) {
|
||||
d.setMinutes(d.getMinutes() + n);
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
function clearTime(d) {
|
||||
d.setHours(0);
|
||||
d.setMinutes(0);
|
||||
d.setSeconds(0);
|
||||
d.setMilliseconds(0);
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
function cloneDate(d, dontKeepTime) {
|
||||
if (dontKeepTime) {
|
||||
return clearTime(new Date(+d));
|
||||
}
|
||||
return new Date(+d);
|
||||
}
|
||||
|
||||
|
||||
function zeroDate() { // returns a Date with time 00:00:00 and dateOfMonth=1
|
||||
var i=0, d;
|
||||
do {
|
||||
d = new Date(1970, i++, 1);
|
||||
} while (d.getHours()); // != 0
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
function skipWeekend(date, inc, excl) {
|
||||
inc = inc || 1;
|
||||
while (!date.getDay() || (excl && date.getDay()==1 || !excl && date.getDay()==6)) {
|
||||
addDays(date, inc);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
|
||||
function dayDiff(d1, d2) { // d1 - d2
|
||||
return Math.round((cloneDate(d1, true) - cloneDate(d2, true)) / DAY_MS);
|
||||
}
|
||||
|
||||
|
||||
function setYMD(date, y, m, d) {
|
||||
if (y !== undefined && y != date.getFullYear()) {
|
||||
date.setDate(1);
|
||||
date.setMonth(0);
|
||||
date.setFullYear(y);
|
||||
}
|
||||
if (m !== undefined && m != date.getMonth()) {
|
||||
date.setDate(1);
|
||||
date.setMonth(m);
|
||||
}
|
||||
if (d !== undefined) {
|
||||
date.setDate(d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Date Parsing
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
function parseDate(s, ignoreTimezone) { // ignoreTimezone defaults to true
|
||||
if (typeof s == 'object') { // already a Date object
|
||||
return s;
|
||||
}
|
||||
if (typeof s == 'number') { // a UNIX timestamp
|
||||
return new Date(s * 1000);
|
||||
}
|
||||
if (typeof s == 'string') {
|
||||
if (s.match(/^\d+(\.\d+)?$/)) { // a UNIX timestamp
|
||||
return new Date(parseFloat(s) * 1000);
|
||||
}
|
||||
if (ignoreTimezone === undefined) {
|
||||
ignoreTimezone = true;
|
||||
}
|
||||
return parseISO8601(s, ignoreTimezone) || (s ? new Date(s) : null);
|
||||
}
|
||||
// TODO: never return invalid dates (like from new Date(<string>)), return null instead
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
function parseISO8601(s, ignoreTimezone) { // ignoreTimezone defaults to false
|
||||
// derived from http://delete.me.uk/2005/03/iso8601.html
|
||||
// TODO: for a know glitch/feature, read tests/issue_206_parseDate_dst.html
|
||||
var m = s.match(/^([0-9]{4})(-([0-9]{2})(-([0-9]{2})([T ]([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2})(:?([0-9]{2}))?))?)?)?)?$/);
|
||||
if (!m) {
|
||||
return null;
|
||||
}
|
||||
var date = new Date(m[1], 0, 1);
|
||||
if (ignoreTimezone || !m[14]) {
|
||||
var check = new Date(m[1], 0, 1, 9, 0);
|
||||
if (m[3]) {
|
||||
date.setMonth(m[3] - 1);
|
||||
check.setMonth(m[3] - 1);
|
||||
}
|
||||
if (m[5]) {
|
||||
date.setDate(m[5]);
|
||||
check.setDate(m[5]);
|
||||
}
|
||||
fixDate(date, check);
|
||||
if (m[7]) {
|
||||
date.setHours(m[7]);
|
||||
}
|
||||
if (m[8]) {
|
||||
date.setMinutes(m[8]);
|
||||
}
|
||||
if (m[10]) {
|
||||
date.setSeconds(m[10]);
|
||||
}
|
||||
if (m[12]) {
|
||||
date.setMilliseconds(Number("0." + m[12]) * 1000);
|
||||
}
|
||||
fixDate(date, check);
|
||||
}else{
|
||||
date.setUTCFullYear(
|
||||
m[1],
|
||||
m[3] ? m[3] - 1 : 0,
|
||||
m[5] || 1
|
||||
);
|
||||
date.setUTCHours(
|
||||
m[7] || 0,
|
||||
m[8] || 0,
|
||||
m[10] || 0,
|
||||
m[12] ? Number("0." + m[12]) * 1000 : 0
|
||||
);
|
||||
var offset = Number(m[16]) * 60 + (m[18] ? Number(m[18]) : 0);
|
||||
offset *= m[15] == '-' ? 1 : -1;
|
||||
date = new Date(+date + (offset * 60 * 1000));
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
|
||||
function parseTime(s) { // returns minutes since start of day
|
||||
if (typeof s == 'number') { // an hour
|
||||
return s * 60;
|
||||
}
|
||||
if (typeof s == 'object') { // a Date object
|
||||
return s.getHours() * 60 + s.getMinutes();
|
||||
}
|
||||
var m = s.match(/(\d+)(?::(\d+))?\s*(\w+)?/);
|
||||
if (m) {
|
||||
var h = parseInt(m[1], 10);
|
||||
if (m[3]) {
|
||||
h %= 12;
|
||||
if (m[3].toLowerCase().charAt(0) == 'p') {
|
||||
h += 12;
|
||||
}
|
||||
}
|
||||
return h * 60 + (m[2] ? parseInt(m[2], 10) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Date Formatting
|
||||
-----------------------------------------------------------------------------*/
|
||||
// TODO: use same function formatDate(date, [date2], format, [options])
|
||||
|
||||
|
||||
function formatDate(date, format, options) {
|
||||
return formatDates(date, null, format, options);
|
||||
}
|
||||
|
||||
|
||||
function formatDates(date1, date2, format, options) {
|
||||
options = options || defaults;
|
||||
var date = date1,
|
||||
otherDate = date2,
|
||||
i, len = format.length, c,
|
||||
i2, formatter,
|
||||
res = '';
|
||||
for (i=0; i<len; i++) {
|
||||
c = format.charAt(i);
|
||||
if (c == "'") {
|
||||
for (i2=i+1; i2<len; i2++) {
|
||||
if (format.charAt(i2) == "'") {
|
||||
if (date) {
|
||||
if (i2 == i+1) {
|
||||
res += "'";
|
||||
}else{
|
||||
res += format.substring(i+1, i2);
|
||||
}
|
||||
i = i2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c == '(') {
|
||||
for (i2=i+1; i2<len; i2++) {
|
||||
if (format.charAt(i2) == ')') {
|
||||
var subres = formatDate(date, format.substring(i+1, i2), options);
|
||||
if (parseInt(subres.replace(/\D/, ''), 10)) {
|
||||
res += subres;
|
||||
}
|
||||
i = i2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c == '[') {
|
||||
for (i2=i+1; i2<len; i2++) {
|
||||
if (format.charAt(i2) == ']') {
|
||||
var subformat = format.substring(i+1, i2);
|
||||
var subres = formatDate(date, subformat, options);
|
||||
if (subres != formatDate(otherDate, subformat, options)) {
|
||||
res += subres;
|
||||
}
|
||||
i = i2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c == '{') {
|
||||
date = date2;
|
||||
otherDate = date1;
|
||||
}
|
||||
else if (c == '}') {
|
||||
date = date1;
|
||||
otherDate = date2;
|
||||
}
|
||||
else {
|
||||
for (i2=len; i2>i; i2--) {
|
||||
if (formatter = dateFormatters[format.substring(i, i2)]) {
|
||||
if (date) {
|
||||
res += formatter(date, options);
|
||||
}
|
||||
i = i2 - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i2 == i) {
|
||||
if (date) {
|
||||
res += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
var dateFormatters = {
|
||||
s : function(d) { return d.getSeconds() },
|
||||
ss : function(d) { return zeroPad(d.getSeconds()) },
|
||||
m : function(d) { return d.getMinutes() },
|
||||
mm : function(d) { return zeroPad(d.getMinutes()) },
|
||||
h : function(d) { return d.getHours() % 12 || 12 },
|
||||
hh : function(d) { return zeroPad(d.getHours() % 12 || 12) },
|
||||
H : function(d) { return d.getHours() },
|
||||
HH : function(d) { return zeroPad(d.getHours()) },
|
||||
d : function(d) { return d.getDate() },
|
||||
dd : function(d) { return zeroPad(d.getDate()) },
|
||||
ddd : function(d,o) { return o.dayNamesShort[d.getDay()] },
|
||||
dddd: function(d,o) { return o.dayNames[d.getDay()] },
|
||||
M : function(d) { return d.getMonth() + 1 },
|
||||
MM : function(d) { return zeroPad(d.getMonth() + 1) },
|
||||
MMM : function(d,o) { return o.monthNamesShort[d.getMonth()] },
|
||||
MMMM: function(d,o) { return o.monthNames[d.getMonth()] },
|
||||
yy : function(d) { return (d.getFullYear()+'').substring(2) },
|
||||
yyyy: function(d) { return d.getFullYear() },
|
||||
t : function(d) { return d.getHours() < 12 ? 'a' : 'p' },
|
||||
tt : function(d) { return d.getHours() < 12 ? 'am' : 'pm' },
|
||||
T : function(d) { return d.getHours() < 12 ? 'A' : 'P' },
|
||||
TT : function(d) { return d.getHours() < 12 ? 'AM' : 'PM' },
|
||||
u : function(d) { return formatDate(d, "yyyy-MM-dd'T'HH:mm:ss'Z'") },
|
||||
S : function(d) {
|
||||
var date = d.getDate();
|
||||
if (date > 10 && date < 20) {
|
||||
return 'th';
|
||||
}
|
||||
return ['st', 'nd', 'rd'][date%10-1] || 'th';
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -42,10 +42,6 @@ var defaults = {
|
|||
// locale
|
||||
isRTL: false,
|
||||
firstDay: 0,
|
||||
monthNames: ['January','February','March','April','May','June','July','August','September','October','November','December'],
|
||||
monthNamesShort: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
|
||||
dayNames: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
|
||||
dayNamesShort: ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'],
|
||||
buttonText: {
|
||||
prev: ' ◄ ',
|
||||
next: ' ► ',
|
||||
|
|
|
@ -13,9 +13,7 @@
|
|||
|
||||
|
||||
var fc = $.fullCalendar;
|
||||
var formatDate = fc.formatDate;
|
||||
var parseISO8601 = fc.parseISO8601;
|
||||
var addDays = fc.addDays;
|
||||
var parseDate = fc.parseDate;
|
||||
var applyAll = fc.applyAll;
|
||||
|
||||
|
||||
|
@ -42,8 +40,8 @@ function transformOptions(sourceOptions, start, end) {
|
|||
|
||||
var success = sourceOptions.success;
|
||||
var data = $.extend({}, sourceOptions.data || {}, {
|
||||
'start-min': formatDate(start, 'u'),
|
||||
'start-max': formatDate(end, 'u'),
|
||||
'start-min': start.toString('u'),
|
||||
'start-max': end.toString('u'),
|
||||
'singleevents': true,
|
||||
'max-results': 9999
|
||||
});
|
||||
|
@ -64,8 +62,8 @@ function transformOptions(sourceOptions, start, end) {
|
|||
if (data.feed.entry) {
|
||||
$.each(data.feed.entry, function(i, entry) {
|
||||
var startStr = entry['gd$when'][0]['startTime'];
|
||||
var start = parseISO8601(startStr, true);
|
||||
var end = parseISO8601(entry['gd$when'][0]['endTime'], true);
|
||||
var start = parseDate(startStr, true); // true for ignoreTimezone
|
||||
var end = parseDate(entry['gd$when'][0]['endTime'], true); // true for ignoreTimezone
|
||||
var allDay = startStr.indexOf('T') == -1;
|
||||
var url;
|
||||
$.each(entry.link, function(i, link) {
|
||||
|
@ -77,7 +75,7 @@ function transformOptions(sourceOptions, start, end) {
|
|||
}
|
||||
});
|
||||
if (allDay) {
|
||||
addDays(end, -1); // make inclusive
|
||||
end.addDays(-1); // make inclusive
|
||||
}
|
||||
events.push({
|
||||
id: entry['gCal$uid']['value'],
|
||||
|
|
795
src/mightydate.js
Normal file
795
src/mightydate.js
Normal file
|
@ -0,0 +1,795 @@
|
|||
/**
|
||||
* @preserve MightyDate v0.4
|
||||
* http://github.com/arshaw/mightydate
|
||||
*
|
||||
* Copyright 2011, Adam Shaw
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
*
|
||||
* Date: Sun May 8 00:19:07 2011 -0700
|
||||
*/
|
||||
|
||||
|
||||
var MightyDate = (function(Date, undefined) {
|
||||
|
||||
|
||||
/** @const */ var FULLYEAR_INDEX = 0;
|
||||
/** @const */ var MONTH_INDEX = 1;
|
||||
/** @const */ var DATE_INDEX = 2;
|
||||
/** @const */ var HOURS_INDEX = 3;
|
||||
/** @const */ var MINUTES_INDEX = 4;
|
||||
/** @const */ var SECONDS_INDEX = 5;
|
||||
/** @const */ var MILLISECONDS_INDEX = 6;
|
||||
/** @const */ var DAY_INDEX = 7;
|
||||
/** @const */ var YEAR_INDEX = 8;
|
||||
/** @const */ var WEEK_INDEX = 9;
|
||||
|
||||
/** @const */ var DAY_MS = 86400000;
|
||||
|
||||
var methodSubjects = [
|
||||
'FullYear', // 0
|
||||
'Month', // 1
|
||||
'Date', // 2
|
||||
'Hours', // 3
|
||||
'Minutes', // 4
|
||||
'Seconds', // 5
|
||||
'Milliseconds', // 6
|
||||
'Day', // 7
|
||||
'Year' // 8
|
||||
];
|
||||
var subjectPlurals = [
|
||||
'Years', // 0
|
||||
'Months', // 1
|
||||
'Days' // 2
|
||||
];
|
||||
var otherGetters = [
|
||||
'getTimezoneOffset',
|
||||
'getTime',
|
||||
'valueOf',
|
||||
'toDateString',
|
||||
'toTimeString',
|
||||
'toLocaleString',
|
||||
'toLocaleDateString',
|
||||
'toLocaleTimeString',
|
||||
'toJSON'
|
||||
];
|
||||
var formatStringRE = new RegExp(
|
||||
"(" + // 1
|
||||
"\\((" + "('.*?'|\\(.*?\\)|.)*?" + ")\\)" + "|" + // 2 3
|
||||
"\\{(" + "('.*?'|.)*?" + ")\\}" + "|" + // 4 5
|
||||
"\\[(" + "('.*?'|.)*?" + ")\\]" + "|" + // 6 7
|
||||
"'(.*?)'" + "|" + // 8
|
||||
"(.[^({[']*)" + // 9
|
||||
")" +
|
||||
"(.*)" // 10
|
||||
);
|
||||
var UTC = Date.UTC;
|
||||
var proto = MightyDate.prototype;
|
||||
var i;
|
||||
var noopSignal = {};
|
||||
|
||||
|
||||
|
||||
/* Constructor
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
function MightyDate() {
|
||||
if (!(this instanceof MightyDate)) {
|
||||
// when MightyDate is called as a method. TODO: write test
|
||||
return init(new MightyDate(noopSignal), arguments);
|
||||
}
|
||||
init(this, arguments);
|
||||
}
|
||||
|
||||
|
||||
function init(mightyDate, args) {
|
||||
var len = args.length;
|
||||
if (!len) {
|
||||
// set to now
|
||||
setLocalDate(mightyDate, new Date());
|
||||
}
|
||||
else if (len == 1) {
|
||||
var arg = args[0];
|
||||
if (isNumber(arg)) {
|
||||
setLocalDate(mightyDate, new Date(arg));
|
||||
}
|
||||
else if (isString(arg)) {
|
||||
_setUniversalDate(mightyDate, new Date(0));
|
||||
parse(mightyDate, arg);
|
||||
}
|
||||
else if (arg instanceof Date) {
|
||||
setLocalDate(mightyDate, new Date(+arg));
|
||||
}
|
||||
else if (arg instanceof MightyDate) {
|
||||
_setUniversalDate(mightyDate, new Date(+getUniversalDate(arg)));
|
||||
}
|
||||
else if (arg != noopSignal) {
|
||||
_setUniversalDate(mightyDate, NaN); // make it an Invalid Date. TODO: write test
|
||||
}
|
||||
}
|
||||
else {
|
||||
_setUniversalDate(mightyDate, new Date(UTC.apply(Date, args)));
|
||||
}
|
||||
return mightyDate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Standard Methods + Adding/Diffing Methods
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
for (i=0; i<WEEK_INDEX; i++) (function(subject, i) { // TODO: rename i to fieldIndex
|
||||
|
||||
if (i != YEAR_INDEX) { // there is no getUTCYear
|
||||
|
||||
// getFullYear
|
||||
// getMonth
|
||||
// getDate
|
||||
// getHours
|
||||
// getMinutes
|
||||
// getSeconds
|
||||
// getMilliseconds
|
||||
// getDay
|
||||
proto['get' + subject] = function() {
|
||||
return getUniversalDate(this)['getUTC' + subject]();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// getFullYear
|
||||
// getMonth
|
||||
// getDate
|
||||
// getHours
|
||||
// getMinutes
|
||||
// getSeconds
|
||||
// getMilliseconds
|
||||
// getDay
|
||||
// getYear
|
||||
proto['getUTC' + subject] = function() {
|
||||
return getLocalDate(this)['getUTC' + subject]();
|
||||
};
|
||||
|
||||
if (i != DAY_INDEX) { // there is no setDay or setUTCDay methods
|
||||
|
||||
// setFullYear
|
||||
// setMonth
|
||||
// setDate
|
||||
// setHours
|
||||
// setMinutes
|
||||
// setSeconds
|
||||
// setMilliseconds
|
||||
// setYear
|
||||
proto['set' + subject] = function(value, preventOverflow) {
|
||||
value = parseInt(value); // TODO: write tests
|
||||
var month = i == MONTH_INDEX ? value % 12 : this.getMonth();
|
||||
var args = arguments;
|
||||
if (args.length == 2 && (isBoolean(preventOverflow) || preventOverflow === undefined)) {
|
||||
args = [value];
|
||||
}
|
||||
getUniversalDate(this)['setUTC' + subject].apply(
|
||||
getUniversalDate(this),
|
||||
args
|
||||
);
|
||||
clearLocalDate(this);
|
||||
// TODO: write tests for year overflow
|
||||
if (i < DATE_INDEX && preventOverflow === true && this.getMonth() != month) { // fullyear or month
|
||||
this.addMonths(-1)
|
||||
.setDate(
|
||||
getDaysInMonth(this.getFullYear(), this.getMonth())
|
||||
);
|
||||
}
|
||||
return this; // for chaining
|
||||
};
|
||||
|
||||
if (i != YEAR_INDEX) { // there is no setUTCYear method
|
||||
|
||||
// setUTCFullYear
|
||||
// setUTCMonth
|
||||
// setUTCDate
|
||||
// setUTCHours
|
||||
// setUTCMinutes
|
||||
// setUTCMilliseconds
|
||||
proto['setUTC' + subject] = function() {
|
||||
var localDate = getLocalDate(this);
|
||||
localDate['setUTC' + subject].apply(
|
||||
localDate,
|
||||
arguments
|
||||
);
|
||||
setUniversalDate(this, localToUniversal(localDate));
|
||||
return this; // for chaining
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (i < DAY_INDEX) { // not day and not year
|
||||
|
||||
// addYears
|
||||
// addMonths
|
||||
// addDays
|
||||
// addHours
|
||||
// addMinutes
|
||||
// addSeconds
|
||||
// addMilliseconds
|
||||
proto['add' + (subjectPlurals[i] || subject)] = function(delta, preventOverflow) {
|
||||
delta = parseInt(delta);
|
||||
this['set' + subject](
|
||||
this['get' + subject]() + delta,
|
||||
preventOverflow
|
||||
);
|
||||
return this; // for chaining
|
||||
};
|
||||
|
||||
// diffYears
|
||||
// diffMonths
|
||||
// diffDays
|
||||
// diffHours
|
||||
// diffMinutes
|
||||
// diffSeconds
|
||||
// diffMilliseconds
|
||||
proto['diff' + (subjectPlurals[i] || subject)] = function(otherDate, exact) {
|
||||
return diff(i, this, otherDate, exact);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
})(methodSubjects[i], i);
|
||||
|
||||
|
||||
for (i=0; i<otherGetters.length; i++) (function(getter) {
|
||||
|
||||
proto[getter] = function() {
|
||||
return getLocalDate(this)[getter]();
|
||||
};
|
||||
|
||||
})(otherGetters[i]);
|
||||
|
||||
|
||||
proto.getYear = function() {
|
||||
return getUniversalDate(this).getUTCFullYear() - 1900;
|
||||
};
|
||||
|
||||
|
||||
proto.setTime = function(t) {
|
||||
setLocalDate(this, new Date(t));
|
||||
};
|
||||
|
||||
|
||||
function diff(fieldIndex, date, otherDate, exact) { // TODO: write tests
|
||||
var d1 = getUniversalDate(date);
|
||||
var d2 = extractUniversalDate(otherDate);
|
||||
var v;
|
||||
if (fieldIndex < DATE_INDEX) { // fullyear or month
|
||||
v = (d2.getUTCFullYear() * 12 + d2.getUTCMonth()) -
|
||||
(d1.getUTCFullYear() * 12 + d1.getUTCMonth()) +
|
||||
((d2 - UTC(d2.getUTCFullYear(), d2.getUTCMonth(), 1)) -
|
||||
(d1 - UTC(d1.getUTCFullYear(), d1.getUTCMonth(), 1))) / DAY_MS / 31;
|
||||
if (fieldIndex == FULLYEAR_INDEX) {
|
||||
v /= 12;
|
||||
}
|
||||
}else{
|
||||
v = (d2 - d1) / [ // milliseconds in a...
|
||||
DAY_MS, // day
|
||||
3600000, // hour
|
||||
60000, // minute
|
||||
1000, // second
|
||||
1, // millisecond
|
||||
0,
|
||||
0,
|
||||
DAY_MS * 7 // week
|
||||
][fieldIndex - 2];
|
||||
}
|
||||
if (!exact) {
|
||||
v = Math.floor(v);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Week (TODO: write tests)
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
proto.diffWeeks = function(otherDate, exact) {
|
||||
return diff(WEEK_INDEX, this, otherDate, exact);
|
||||
};
|
||||
|
||||
|
||||
proto.addWeeks = function(delta) {
|
||||
return this.addDays(delta * 7);
|
||||
};
|
||||
|
||||
|
||||
proto.getWeek = function(d) {
|
||||
return _getWeek(this.getFullYear(), this.getMonth(), this.getDate());
|
||||
};
|
||||
|
||||
|
||||
proto.getUTCWeek = function(d) {
|
||||
return _getWeek(this.getUTCFullYear(), this.getUTCMonth(), this.getUTCDate());
|
||||
};
|
||||
|
||||
|
||||
function _getWeek(year, month, date) {
|
||||
var d = new Date(UTC(year, month, date));
|
||||
var currentWeek1 = getWeek1(year);
|
||||
var week1 = currentWeek1;
|
||||
if (d < currentWeek1) {
|
||||
week1 = getWeek1(year-1);
|
||||
}else{
|
||||
var nextWeek1 = getWeek1(year+1);
|
||||
if (d >= nextWeek1) {
|
||||
week1 = nextWeek1;
|
||||
}
|
||||
}
|
||||
return Math.floor(Math.round((d - week1) / DAY_MS) / 7) + 1;
|
||||
}
|
||||
|
||||
|
||||
function getWeek1(year) {
|
||||
var d = new Date(UTC(year, 0, 4));
|
||||
d.setUTCDate(d.getUTCDate() - (d.getUTCDay() + 6) % 7);
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Non-Standard Methods
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
proto.equals = function(date) {
|
||||
return +getUniversalDate(this) == +extractUniversalDate(date);
|
||||
};
|
||||
|
||||
|
||||
proto.before = function(date) {
|
||||
return getUniversalDate(this) < extractUniversalDate(date);
|
||||
};
|
||||
|
||||
|
||||
proto.after = function(date) {
|
||||
return getUniversalDate(this) > extractUniversalDate(date);
|
||||
};
|
||||
|
||||
|
||||
proto.valid = function() {
|
||||
return !isNaN(+getUniversalDate(this));
|
||||
};
|
||||
|
||||
|
||||
proto.clearTime = function() {
|
||||
return this.setHours(0, 0, 0, 0);
|
||||
};
|
||||
|
||||
|
||||
proto.clone = function() {
|
||||
return new MightyDate(this);
|
||||
};
|
||||
|
||||
|
||||
proto.toDate = function() {
|
||||
return new Date(+this);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Parsing
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
MightyDate.parsers = [
|
||||
parseISO
|
||||
];
|
||||
|
||||
|
||||
MightyDate.parse = function(str) {
|
||||
return +new MightyDate(''+str);
|
||||
};
|
||||
|
||||
|
||||
function parse(date, str) {
|
||||
var parsers = MightyDate.parsers;
|
||||
for (var i=0; i<parsers.length; i++) {
|
||||
if (parsers[i](date, str)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
setLocalDate(date, new Date(str));
|
||||
}
|
||||
|
||||
|
||||
function parseISO(date, str) {
|
||||
var m = str.match(/^(\d{4})(-(\d{2})(-(\d{2})([T ](\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/);
|
||||
if (!m) {
|
||||
return false;
|
||||
}
|
||||
var args1 = [
|
||||
m[1],
|
||||
m[3] ? m[3] - 1 : 0,
|
||||
m[5] || 1
|
||||
];
|
||||
var args2 = [
|
||||
m[7] || 0,
|
||||
m[8] || 0,
|
||||
m[10] || 0,
|
||||
m[12] ? Number('0.' + m[12]) * 1000 : 0
|
||||
];
|
||||
if (m[14]) {
|
||||
date.setUTCFullYear.apply(date, args1);
|
||||
date.setUTCHours.apply(date, args2);
|
||||
var offset = Number(m[16]) * 60 + (m[18] ? Number(m[18]) : 0);
|
||||
offset *= m[15] == '-' ? 1 : -1;
|
||||
date.addMinutes(offset);
|
||||
}else{
|
||||
date.setFullYear.apply(date, args1);
|
||||
date.setHours.apply(date, args2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Formatting
|
||||
---------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
MightyDate.defaultLocale = '';
|
||||
MightyDate.locales = {
|
||||
'': {
|
||||
monthNames: ['January','February','March','April','May','June','July','August','September','October','November','December'],
|
||||
monthNamesShort: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
|
||||
dayNames: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
|
||||
dayNamesShort: ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'],
|
||||
amDesignator: 'AM',
|
||||
pmDesignator: 'PM'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
MightyDate.formatters = {
|
||||
i: "yyyy-MM-dd'T'HH:mm:ss",
|
||||
u: "yyyy-MM-dd'T'HH:mm:ssK"
|
||||
};
|
||||
|
||||
|
||||
proto.toString = function(otherDate, formatString, settings) {
|
||||
if (!arguments.length || !this.valid()) {
|
||||
return getLocalDate(this).toString();
|
||||
}
|
||||
return format(false, this, otherDate, formatString, settings);
|
||||
};
|
||||
|
||||
|
||||
proto.toUTCString = proto.toGMTString = function(otherDate, formatString, settings) {
|
||||
if (!arguments.length || !this.valid()) {
|
||||
return getLocalDate(this).toUTCString();
|
||||
}
|
||||
return format(true, this, otherDate, formatString, settings);
|
||||
};
|
||||
|
||||
|
||||
function format(isUTC, date, otherDate, formatString, settings) {
|
||||
|
||||
if (isString(otherDate)) {
|
||||
settings = formatString;
|
||||
formatString = otherDate;
|
||||
otherDate = null;
|
||||
}
|
||||
|
||||
var locales = MightyDate.locales;
|
||||
var localeSettings = locales[MightyDate.defaultLocale] || {};
|
||||
if (isString(settings)) {
|
||||
localeSettings = locales[settings] || localeSettings;
|
||||
settings = {};
|
||||
}else{
|
||||
settings = settings || {};
|
||||
}
|
||||
|
||||
function getSetting(name) {
|
||||
return settings[name] || localeSettings[name];
|
||||
}
|
||||
|
||||
return _format(isUTC, date, otherDate, formatString, getSetting);
|
||||
}
|
||||
|
||||
|
||||
function _format(isUTC, date, otherDate, formatString, getSetting, uniqueness) {
|
||||
|
||||
var match;
|
||||
var tokenReplacement;
|
||||
var subOutput;
|
||||
var output = '';
|
||||
var _getField = isUTC ? getUTCField : getLocalField;
|
||||
|
||||
function getField(i) {
|
||||
if (uniqueness) {
|
||||
for (var j=i; j>=0; j--) {
|
||||
uniqueness.push(_getField(date, j));
|
||||
}
|
||||
}
|
||||
return _getField(date, i);
|
||||
}
|
||||
|
||||
while (formatString) {
|
||||
match = formatStringRE.exec(formatString);
|
||||
if (match[9] !== undefined) {
|
||||
// tokens
|
||||
var tokenSoup = match[9];
|
||||
var tokenSoupLength = tokenSoup.length;
|
||||
var tokenStart = 0;
|
||||
var tokenEnd = tokenSoupLength;
|
||||
while (tokenStart < tokenSoupLength) {
|
||||
tokenReplacement = undefined;
|
||||
// find the longest formatter starting at tokenStart
|
||||
while (tokenEnd > tokenStart) {
|
||||
tokenReplacement = getTokenReplacement(
|
||||
tokenSoup.substring(tokenStart, tokenEnd), // the potential token
|
||||
isUTC, date, getField, getSetting, uniqueness
|
||||
);
|
||||
if (tokenReplacement !== undefined) {
|
||||
output += tokenReplacement;
|
||||
tokenStart = tokenEnd; // continue looking after
|
||||
break;
|
||||
}
|
||||
tokenEnd--;
|
||||
}
|
||||
if (tokenReplacement === undefined) {
|
||||
// swallow single character and continue after
|
||||
output += formatString.charAt(tokenStart);
|
||||
tokenStart++;
|
||||
}
|
||||
tokenEnd = tokenSoupLength;
|
||||
}
|
||||
}
|
||||
else if (match[2] !== undefined) {
|
||||
// only if non-zero
|
||||
subOutput = _format(isUTC, date, otherDate, match[2], getSetting);
|
||||
if (Number(subOutput.replace(/\D/g, ''))) {
|
||||
output += subOutput;
|
||||
}
|
||||
}
|
||||
else if (match[4] !== undefined) {
|
||||
// switch to other date
|
||||
if (otherDate) {
|
||||
output += _format(isUTC, otherDate, date, match[4], getSetting);
|
||||
}
|
||||
}
|
||||
else if (match[6] !== undefined) {
|
||||
// only if different
|
||||
var otherSubUniqueness = [];
|
||||
var otherSubOutput = _format(isUTC, otherDate, date, match[6], getSetting, otherSubUniqueness);
|
||||
var subUniqueness = [];
|
||||
subOutput = _format(isUTC, date, otherDate, match[6], getSetting, subUniqueness);
|
||||
if (subOutput != otherSubOutput || subUniqueness.join() != otherSubUniqueness.join()) {
|
||||
output += subOutput;
|
||||
}
|
||||
}
|
||||
else if (match[8] !== undefined) {
|
||||
if (match[8]) {
|
||||
output += match[8]; // quoted text
|
||||
}else{
|
||||
output += "'"; // escaped quote
|
||||
}
|
||||
}
|
||||
formatString = match[10];
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
function getTokenReplacement(token, isUTC, date, getField, getSetting, uniqueness) {
|
||||
var formatter = MightyDate.formatters[token];
|
||||
if (formatter) {
|
||||
if (isString(formatter)) {
|
||||
return _format(isUTC, date, null, formatter, getSetting, uniqueness);
|
||||
}
|
||||
return formatter(date, getSetting, isUTC);
|
||||
}
|
||||
switch (token) {
|
||||
case 's' : return getField(SECONDS_INDEX);
|
||||
case 'ss' : return zeroPad(getField(SECONDS_INDEX));
|
||||
case 'm' : return getField(MINUTES_INDEX);
|
||||
case 'mm' : return zeroPad(getField(MINUTES_INDEX));
|
||||
case 'h' : return getField(HOURS_INDEX) % 12 || 12;
|
||||
case 'hh' : return zeroPad(getField(HOURS_INDEX) % 12 || 12);
|
||||
case 'H' : return getField(HOURS_INDEX);
|
||||
case 'HH' : return zeroPad(getField(HOURS_INDEX));
|
||||
case 'd' : return getField(DATE_INDEX);
|
||||
case 'dd' : return zeroPad(getField(DATE_INDEX));
|
||||
case 'ddd' : return getSetting('dayNamesShort')[getField(DAY_INDEX)];
|
||||
case 'dddd' : return getSetting('dayNames')[getField(DAY_INDEX)];
|
||||
case 'M' : return getField(MONTH_INDEX) + 1;
|
||||
case 'MM' : return zeroPad(getField(MONTH_INDEX) + 1);
|
||||
case 'MMM' : return getSetting('monthNamesShort')[getField(MONTH_INDEX)];
|
||||
case 'MMMM' : return getSetting('monthNames')[getField(MONTH_INDEX)];
|
||||
case 'yy' : return (getField(FULLYEAR_INDEX)+'').substring(2);
|
||||
case 'yyyy' : return getField(FULLYEAR_INDEX);
|
||||
case 't' :
|
||||
case 'tt' :
|
||||
case 'T' :
|
||||
case 'TT' :
|
||||
var s = getField(HOURS_INDEX) < 12 ? getSetting('amDesignator') : getSetting('pmDesignator');
|
||||
if (token.length == 1) s = s.substr(0, 1);
|
||||
if (token > 'TT') s = s.toLowerCase(); // token == 't' || token == 'tt'
|
||||
return s;
|
||||
case 'K' : if (isUTC) return 'Z';
|
||||
case 'z' :
|
||||
case 'zz' :
|
||||
case 'zzz' :
|
||||
var tzo = date.getTimezoneOffset();
|
||||
var sign = tzo < 0 ? '+' : '-';
|
||||
var hours = Math.floor((tzo = Math.abs(tzo)) / 60);
|
||||
var minutes = tzo % 60;
|
||||
return sign +
|
||||
(token == 'z' ? hours : zeroPad(hours)) +
|
||||
((token == 'z' || token == 'zz') ? '' : ':' + zeroPad(minutes));
|
||||
case 'S' :
|
||||
var d = getField(DATE_INDEX);
|
||||
if (d > 10 && d < 20) return 'th';
|
||||
return ['st', 'nd', 'rd'][d % 10 - 1] || 'th';
|
||||
case 'W' :
|
||||
return _getWeek(
|
||||
getField(FULLYEAR_INDEX),
|
||||
getField(MONTH_INDEX),
|
||||
getField(DATE_INDEX)
|
||||
);
|
||||
case 'WW' :
|
||||
return zeroPad(
|
||||
_getWeek(
|
||||
getField(FULLYEAR_INDEX),
|
||||
getField(MONTH_INDEX),
|
||||
getField(DATE_INDEX)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getLocalField(date, i) {
|
||||
return date['get' + methodSubjects[i]]();
|
||||
}
|
||||
|
||||
|
||||
function getUTCField(date, i) {
|
||||
return date['getUTC' + methodSubjects[i]]();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Misc Class Methods
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
MightyDate.now = Date.now;
|
||||
|
||||
|
||||
MightyDate.UTC = UTC;
|
||||
|
||||
|
||||
MightyDate.getDaysInMonth = getDaysInMonth;
|
||||
|
||||
|
||||
|
||||
/* Date Utilities
|
||||
--------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
function getDaysInMonth(year, month) {
|
||||
return 32 - new Date(Date.UTC(year, month, 32)).getUTCDate();
|
||||
}
|
||||
|
||||
|
||||
function extractUniversalDate(date) {
|
||||
if (date instanceof MightyDate) {
|
||||
return getUniversalDate(date);
|
||||
}
|
||||
else if (date instanceof Date) {
|
||||
return localToUniversal(date);
|
||||
}
|
||||
return getUniversalDate(new MightyDate(date));
|
||||
}
|
||||
|
||||
|
||||
function localToUniversal(localDate) {
|
||||
return new Date(UTC(
|
||||
localDate.getFullYear(),
|
||||
localDate.getMonth(),
|
||||
localDate.getDate(),
|
||||
localDate.getHours(),
|
||||
localDate.getMinutes(),
|
||||
localDate.getSeconds(),
|
||||
localDate.getMilliseconds()
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
function universalToLocal(universalDate) {
|
||||
return new Date(
|
||||
universalDate.getUTCFullYear(),
|
||||
universalDate.getUTCMonth(),
|
||||
universalDate.getUTCDate(),
|
||||
universalDate.getUTCHours(),
|
||||
universalDate.getUTCMinutes(),
|
||||
universalDate.getUTCSeconds(),
|
||||
universalDate.getUTCMilliseconds()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* General Utilities
|
||||
--------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
function zeroPad(n) {
|
||||
return (n < 10 ? '0' : '') + n;
|
||||
}
|
||||
|
||||
|
||||
function isString(x) {
|
||||
return typeof x == 'string';
|
||||
}
|
||||
|
||||
|
||||
function isNumber(x) {
|
||||
return typeof x == 'number';
|
||||
}
|
||||
|
||||
|
||||
function isBoolean(x) {
|
||||
return typeof x == 'boolean';
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Internal Utilities
|
||||
---------------------------------------------------------------------------------*/
|
||||
|
||||
// _ is universal date
|
||||
// $ is local date
|
||||
|
||||
|
||||
function getUniversalDate(mightyDate) {
|
||||
return mightyDate._;
|
||||
}
|
||||
|
||||
|
||||
function setUniversalDate(mightyDate, universalDate) {
|
||||
_setUniversalDate(mightyDate, universalDate);
|
||||
clearLocalDate(mightyDate);
|
||||
}
|
||||
|
||||
|
||||
function _setUniversalDate(mightyDate, universalDate) {
|
||||
mightyDate._ = universalDate;
|
||||
}
|
||||
|
||||
|
||||
function getLocalDate(mightyDate) {
|
||||
if (mightyDate.$ === undefined) {
|
||||
mightyDate.$ = universalToLocal(mightyDate._);
|
||||
}
|
||||
return mightyDate.$;
|
||||
}
|
||||
|
||||
|
||||
function setLocalDate(mightyDate, localDate) {
|
||||
mightyDate.$ = localDate;
|
||||
mightyDate._ = localToUniversal(localDate);
|
||||
}
|
||||
|
||||
|
||||
function clearLocalDate(mightyDate) {
|
||||
delete mightyDate.$;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return MightyDate;
|
||||
|
||||
})(Date);
|
105
src/util.js
105
src/util.js
|
@ -1,5 +1,85 @@
|
|||
|
||||
fc.applyAll = applyAll;
|
||||
fc.Date = MightyDate;
|
||||
fc.parseDate = parseDate;
|
||||
fc.parseISO8601 = parseISO8601;
|
||||
fc.formatDate = formatDate;
|
||||
fc.formatDates = formatDates;
|
||||
|
||||
|
||||
var dayIDs = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
|
||||
|
||||
|
||||
/* Date
|
||||
--------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
function skipWeekend(date, inc, excl) {
|
||||
inc = inc || 1;
|
||||
while (!date.getDay() || (excl && date.getDay()==1 || !excl && date.getDay()==6)) {
|
||||
date.addDays(inc);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
|
||||
function parseTime(s) { // returns minutes since start of day
|
||||
if (typeof s == 'number') { // an hour
|
||||
return s * 60;
|
||||
}
|
||||
if (typeof s == 'object') { // a Date object
|
||||
return s.getHours() * 60 + s.getMinutes();
|
||||
}
|
||||
var m = s.match(/(\d+)(?::(\d+))?\s*(\w+)?/);
|
||||
if (m) {
|
||||
var h = parseInt(m[1], 10);
|
||||
if (m[3]) {
|
||||
h %= 12;
|
||||
if (m[3].toLowerCase().charAt(0) == 'p') {
|
||||
h += 12;
|
||||
}
|
||||
}
|
||||
return h * 60 + (m[2] ? parseInt(m[2], 10) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: change ignoreTimezone default
|
||||
function parseDate(input, ignoreTimezone) { // ignoreTimezone DEFAULTS TO TRUE!!! :(
|
||||
// handles more than just strings
|
||||
if (ignoreTimezone === undefined) {
|
||||
ignoreTimezone = true;
|
||||
}
|
||||
if (ignoreTimezone && typeof input == 'string') {
|
||||
input = stripTimezone(input);
|
||||
}
|
||||
return new MightyDate(input);
|
||||
}
|
||||
|
||||
|
||||
// TODO: deprecate
|
||||
function parseISO8601(input, ignoreTimezone) { // ignoreTimezone DEFAULTS TO FALSE
|
||||
if (ignoreTimezone === undefined) {
|
||||
ignoreTimezone = false;
|
||||
}
|
||||
return parseDate(input, ignoreTimezone);
|
||||
}
|
||||
|
||||
|
||||
function stripTimezone(s) {
|
||||
return s.replace(/^(\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(\.\d+)?)(.*)$/, '$1');
|
||||
}
|
||||
|
||||
|
||||
function formatDate(date, formatString, settings) {
|
||||
return new MightyDate(date).toString(formatString, settings);
|
||||
}
|
||||
|
||||
|
||||
function formatDates(date1, date2, formatString, settings) {
|
||||
return new MightyDate(date1).toString(date2, formatString, settings);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Event Date Math
|
||||
|
@ -10,24 +90,27 @@ function exclEndDay(event) {
|
|||
if (event.end) {
|
||||
return _exclEndDay(event.end, event.allDay);
|
||||
}else{
|
||||
return addDays(cloneDate(event.start), 1);
|
||||
return event.start.clone().addDays(1).clearTime();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function _exclEndDay(end, allDay) {
|
||||
end = cloneDate(end);
|
||||
return allDay || end.getHours() || end.getMinutes() ? addDays(end, 1) : clearTime(end);
|
||||
end = end.clone();
|
||||
if (allDay || end.getHours() || end.getMinutes()) {
|
||||
end.addDays(1);
|
||||
}
|
||||
return end.clearTime();
|
||||
}
|
||||
|
||||
|
||||
function segCmp(a, b) {
|
||||
return (b.msLength - a.msLength) * 100 + (a.event.start - b.event.start);
|
||||
return (b.msLength - a.msLength) * 100 + b.event.start.diffMilliseconds(a.event.start);
|
||||
}
|
||||
|
||||
|
||||
function segsCollide(seg1, seg2) {
|
||||
return seg1.end > seg2.start && seg1.start < seg2.end;
|
||||
return seg1.end.after(seg2.start) && seg1.start.before(seg2.end);
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,16 +130,16 @@ function sliceSegs(events, visEventEnds, start, end) {
|
|||
event = events[i];
|
||||
eventStart = event.start;
|
||||
eventEnd = visEventEnds[i];
|
||||
if (eventEnd > start && eventStart < end) {
|
||||
if (eventStart < start) {
|
||||
segStart = cloneDate(start);
|
||||
if (eventEnd.after(start) && eventStart.before(end)) {
|
||||
if (eventStart.before(start)) {
|
||||
segStart = start.clone();
|
||||
isStart = false;
|
||||
}else{
|
||||
segStart = eventStart;
|
||||
isStart = true;
|
||||
}
|
||||
if (eventEnd > end) {
|
||||
segEnd = cloneDate(end);
|
||||
if (eventEnd.after(end)) {
|
||||
segEnd = end.clone();
|
||||
isEnd = false;
|
||||
}else{
|
||||
segEnd = eventEnd;
|
||||
|
@ -68,7 +151,7 @@ function sliceSegs(events, visEventEnds, start, end) {
|
|||
end: segEnd,
|
||||
isStart: isStart,
|
||||
isEnd: isEnd,
|
||||
msLength: segEnd - segStart
|
||||
msLength: segStart.diffMilliseconds(segEnd)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue