Skip to content

Commit

Permalink
fix(calendar): Add negative timestamp support to use date before 1970…
Browse files Browse the repository at this point in the history
…-01-01. Fixes #4914 (partial)
  • Loading branch information
WoodySlum committed Jun 21, 2023
1 parent fccc910 commit 8a8dcae
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 86 deletions.
23 changes: 14 additions & 9 deletions SoObjects/Appointments/SOGoAppointmentFolder.m
Original file line number Diff line number Diff line change
Expand Up @@ -664,18 +664,23 @@ - (NSString *) _sqlStringRangeFrom: (NSCalendarDate *) _startDate
cycle: (BOOL) _isCycle
{
NSString *format;
unsigned int start, end;
long long start, end;

start = (unsigned int) [_startDate timeIntervalSince1970];
end = (unsigned int) [_endDate timeIntervalSince1970];
start = (long long) [_startDate timeIntervalSince1970];
end = (long long) [_endDate timeIntervalSince1970];

// vTODOs don't necessarily have start/end dates
if (_isCycle)
format = (@"(c_startdate = NULL OR c_startdate <= %u)"
@" AND (c_cycleenddate = NULL OR c_cycleenddate >= %u)");
else
format = (@"(c_startdate = NULL OR c_startdate <= %u)"
@" AND (c_enddate = NULL OR c_enddate >= %u)");
if (start < 0 && end < 0) {
format = (@"(c_startdate = NULL OR c_startdate <= %lld)"
@" AND (c_cycleenddate = NULL OR c_cycleenddate >= %lld)");
} else {
if (_isCycle)
format = (@"(c_startdate = NULL OR c_startdate <= %lld)"
@" AND (c_cycleenddate = NULL OR c_cycleenddate >= %lld)");
else
format = (@"(c_startdate = NULL OR c_startdate <= %lld)"
@" AND (c_enddate = NULL OR c_enddate >= %lld )");
}

return [NSString stringWithFormat: format, end, start];
}
Expand Down
146 changes: 69 additions & 77 deletions UI/Scheduler/UIxCalListingActions.m
Original file line number Diff line number Diff line change
Expand Up @@ -1070,98 +1070,90 @@ - (void) _fillBlocks: (NSArray *) blocks
withEvent: (NSArray *) event
withNumber: (NSNumber *) number
{
int currentDayStart, startSecs, endsSecs, currentStart, eventStart,
eventEnd, computedEventEnd, offset, recurrenceTime, swap;
int offset, recurrenceTime;
long long startSecs, endsSecs, swap, currentDayStart, currentStart, eventStart,
eventEnd, computedEventEnd;
NSMutableArray *currentDay;
NSMutableDictionary *eventBlock;
NSString *userState;

eventStart = [[event objectAtIndex: eventStartDateIndex] intValue];
if (eventStart < 0)
[self errorWithFormat: @"event '%@' has negative start: %d (skipped)",
[event objectAtIndex: eventNameIndex], eventStart];
else
eventEnd = [[event objectAtIndex: eventEndDateIndex] intValue];

if ((eventEnd < eventStart && eventEnd > 0)
|| (eventStart > 0 && eventEnd < 0)
|| (eventStart > eventEnd && eventStart < 0 && eventEnd < 0))
{
eventEnd = [[event objectAtIndex: eventEndDateIndex] intValue];
if (eventEnd < 0)
[self errorWithFormat: @"event '%@' has negative end: %d (skipped)",
[event objectAtIndex: eventNameIndex], eventEnd];
else
{
if (eventEnd < eventStart)
{
swap = eventStart;
eventStart = eventEnd;
eventEnd = swap;
[self warnWithFormat: @"event '%@' has end < start: %d < %d",
[event objectAtIndex: eventNameIndex], eventEnd, eventStart];
}
swap = eventStart;
eventStart = eventEnd;
eventEnd = swap;
[self warnWithFormat: @"event '%@' has end < start: %d < %d",
[event objectAtIndex: eventNameIndex], eventEnd, eventStart];
}

startSecs = (unsigned int) [startDate timeIntervalSince1970];
endsSecs = (unsigned int) [endDate timeIntervalSince1970];
startSecs = (long long) [startDate timeIntervalSince1970];
endsSecs = (long long) [endDate timeIntervalSince1970];

if ([[event objectAtIndex: eventIsCycleIndex] boolValue])
recurrenceTime = [[event objectAtIndex: eventRecurrenceIdIndex] unsignedIntValue];
else
recurrenceTime = 0;
if ([[event objectAtIndex: eventIsCycleIndex] boolValue])
recurrenceTime = [[event objectAtIndex: eventRecurrenceIdIndex] unsignedIntValue];
else
recurrenceTime = 0;

currentStart = eventStart;
if (currentStart < startSecs)
{
currentStart = startSecs;
offset = 0;
}
else
offset = ((currentStart - startSecs) / dayLength);
if (offset >= [blocks count])
[self errorWithFormat: @"event '%@' has a computed offset that"
@" overflows the amount of blocks (skipped)",
[event objectAtIndex: eventNameIndex]];
else
{
currentDay = [blocks objectAtIndex: offset];
currentDayStart = startSecs + dayLength * offset;
currentStart = eventStart;
if (currentStart < startSecs)
{
currentStart = startSecs;
offset = 0;
}
else
offset = ((currentStart - startSecs) / dayLength);
if (offset >= [blocks count])
[self errorWithFormat: @"event '%@' has a computed offset that"
@" overflows the amount of blocks (skipped)",
[event objectAtIndex: eventNameIndex]];
else
{
currentDay = [blocks objectAtIndex: offset];
currentDayStart = startSecs + dayLength * offset;

if (eventEnd > endsSecs)
eventEnd = endsSecs;
if (eventEnd > endsSecs)
eventEnd = endsSecs;

if (eventEnd < startSecs)
// The event doesn't end in the covered period.
// This special case occurs with a DST change.
return;
if (eventEnd < startSecs)
// The event doesn't end in the covered period.
// This special case occurs with a DST change.
return;

userState = _userStateInEvent(event);
while (currentDayStart + dayLength < eventEnd)
{
eventBlock = [self _eventBlockWithStart: currentStart
end: currentDayStart + dayLength - 1
number: number
onDay: currentDayStart
recurrenceTime: recurrenceTime
userState: userState];
[currentDay addObject: eventBlock];
currentDayStart += dayLength;
currentStart = currentDayStart;
offset++;
currentDay = [blocks objectAtIndex: offset];
}
userState = _userStateInEvent(event);
while (currentDayStart + dayLength < eventEnd)
{
eventBlock = [self _eventBlockWithStart: currentStart
end: currentDayStart + dayLength - 1
number: number
onDay: currentDayStart
recurrenceTime: recurrenceTime
userState: userState];
[currentDay addObject: eventBlock];
currentDayStart += dayLength;
currentStart = currentDayStart;
offset++;
currentDay = [blocks objectAtIndex: offset];
}

computedEventEnd = eventEnd;
computedEventEnd = eventEnd;

// We add 5 mins to the end date of an event if the end date
// is equal or smaller than the event's start date.
if (eventEnd <= currentStart)
computedEventEnd = currentStart + (5*60);
// We add 5 mins to the end date of an event if the end date
// is equal or smaller than the event's start date.
if (eventEnd <= currentStart)
computedEventEnd = currentStart + (5*60);

eventBlock = [self _eventBlockWithStart: currentStart
end: computedEventEnd
number: number
onDay: currentDayStart
recurrenceTime: recurrenceTime
userState: userState];
[currentDay addObject: eventBlock];
}
}
eventBlock = [self _eventBlockWithStart: currentStart
end: computedEventEnd
number: number
onDay: currentDayStart
recurrenceTime: recurrenceTime
userState: userState];
[currentDay addObject: eventBlock];
}
}

Expand Down

0 comments on commit 8a8dcae

Please sign in to comment.