fix(calendar): Add negative timestamp support to use date before 1970-01-01. Fixes #4914 (partial)

This commit is contained in:
smizrahi
2023-06-21 15:51:18 +02:00
parent fccc910791
commit 8a8dcae029
2 changed files with 89 additions and 92 deletions
+14 -9
View File
@@ -664,18 +664,23 @@ static Class iCalEventK = nil;
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];
}
+75 -83
View File
@@ -1070,98 +1070,90 @@ static inline void _feedBlockWithDayBasedData (NSMutableDictionary *block, unsig
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];
eventEnd = [[event objectAtIndex: eventEndDateIndex] intValue];
if ((eventEnd < eventStart && eventEnd > 0)
|| (eventStart > 0 && eventEnd < 0)
|| (eventStart > eventEnd && eventStart < 0 && eventEnd < 0))
{
swap = eventStart;
eventStart = eventEnd;
eventEnd = swap;
[self warnWithFormat: @"event '%@' has end < start: %d < %d",
[event objectAtIndex: eventNameIndex], eventEnd, eventStart];
}
startSecs = (long long) [startDate timeIntervalSince1970];
endsSecs = (long long) [endDate timeIntervalSince1970];
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
{
eventEnd = [[event objectAtIndex: eventEndDateIndex] intValue];
if (eventEnd < 0)
[self errorWithFormat: @"event '%@' has negative end: %d (skipped)",
[event objectAtIndex: eventNameIndex], eventEnd];
else
currentDay = [blocks objectAtIndex: offset];
currentDayStart = startSecs + dayLength * offset;
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;
userState = _userStateInEvent(event);
while (currentDayStart + dayLength < eventEnd)
{
if (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];
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;
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;
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;
// 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: 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;
// 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];
}
}