-
Notifications
You must be signed in to change notification settings - Fork 67
Open
Description
Bug
When displaying due dates with relative formatting, the tool calculates based on elapsed time rather than calendar day boundaries. This causes confusing output where a task due in 2 calendar days shows as "in 1 day".
Example
- Now: Thursday, January 8, 2026 at 9:00am
- Task due: Saturday, January 10, 2026 at 8:00am
Expected: "in 2 days" (Thursday → Friday → Saturday)
Actual: "in 1 day" (~47 hours elapsed ÷ 24 ≈ 1.9, displayed as 1)
Reproduction
# On Thursday morning:
reminders add To-Dos "Saturday morning meeting" --due-date "2026-01-10 08:00"
reminders show To-Dos
# Shows "in 1 day" instead of "in 2 days"Location
Sources/RemindersLibrary/Reminders.swift, lines 7-11:
private let dateFormatter = RelativeDateTimeFormatter()
private func formattedDueDate(from reminder: EKReminder) -> String? {
return reminder.dueDateComponents?.date.map {
dateFormatter.localizedString(for: $0, relativeTo: Date())
}
}RelativeDateTimeFormatter.localizedString(for:relativeTo:) uses elapsed time rather than calendar day boundaries.
Suggested fix
Use calendar day comparison instead:
private func formattedDueDate(from reminder: EKReminder) -> String? {
guard let dueDate = reminder.dueDateComponents?.date else { return nil }
let calendar = Calendar.current
let today = calendar.startOfDay(for: Date())
let dueDay = calendar.startOfDay(for: dueDate)
let days = calendar.dateComponents([.day], from: today, to: dueDay).day ?? 0
switch days {
case ..<0: return "\(abs(days)) day\(abs(days) == 1 ? "" : "s") ago"
case 0: return "today"
case 1: return "tomorrow"
default: return "in \(days) days"
}
}This matches how users think about dates: "due in 2 days" means the day after tomorrow, regardless of the specific hour.
Metadata
Metadata
Assignees
Labels
No labels