mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Fix/set due date on intraday learning card (#4101)
- Introduced `next_day_start` parameter to `set_due_date` for improved due date handling. - Updated logic to account for Unix epoch timestamps when calculating due dates.
This commit is contained in:
parent
cc395f7c44
commit
88538d8bad
1 changed files with 25 additions and 9 deletions
|
@ -17,6 +17,7 @@ use crate::collection::Collection;
|
|||
use crate::config::StringKey;
|
||||
use crate::error::Result;
|
||||
use crate::prelude::*;
|
||||
use crate::scheduler::timing::is_unix_epoch_timestamp;
|
||||
|
||||
impl Card {
|
||||
/// Make card due in `days_from_today`.
|
||||
|
@ -27,6 +28,7 @@ impl Card {
|
|||
fn set_due_date(
|
||||
&mut self,
|
||||
today: u32,
|
||||
next_day_start: i64,
|
||||
days_from_today: u32,
|
||||
ease_factor: f32,
|
||||
force_reset: bool,
|
||||
|
@ -34,8 +36,15 @@ impl Card {
|
|||
let new_due = (today + days_from_today) as i32;
|
||||
let fsrs_enabled = self.memory_state.is_some();
|
||||
let new_interval = if fsrs_enabled {
|
||||
self.interval
|
||||
.saturating_add_signed(new_due - self.original_or_current_due())
|
||||
let due = self.original_or_current_due();
|
||||
let due_diff = if is_unix_epoch_timestamp(due) {
|
||||
let offset = (due as i64 - next_day_start) / 86_400;
|
||||
let due = (today as i64 + offset) as i32;
|
||||
new_due - due
|
||||
} else {
|
||||
new_due - due
|
||||
};
|
||||
self.interval.saturating_add_signed(due_diff)
|
||||
} else if force_reset || !matches!(self.ctype, CardType::Review | CardType::Relearn) {
|
||||
days_from_today.max(1)
|
||||
} else {
|
||||
|
@ -114,6 +123,7 @@ impl Collection {
|
|||
let spec = parse_due_date_str(days)?;
|
||||
let usn = self.usn()?;
|
||||
let today = self.timing_today()?.days_elapsed;
|
||||
let next_day_start = self.timing_today()?.next_day_at.0;
|
||||
let mut rng = rand::rng();
|
||||
let distribution = Uniform::new_inclusive(spec.min, spec.max).unwrap();
|
||||
let mut decks_initial_ease: HashMap<DeckId, f32> = HashMap::new();
|
||||
|
@ -137,7 +147,13 @@ impl Collection {
|
|||
};
|
||||
let original = card.clone();
|
||||
let days_from_today = distribution.sample(&mut rng);
|
||||
card.set_due_date(today, days_from_today, ease_factor, spec.force_reset);
|
||||
card.set_due_date(
|
||||
today,
|
||||
next_day_start,
|
||||
days_from_today,
|
||||
ease_factor,
|
||||
spec.force_reset,
|
||||
);
|
||||
col.log_manually_scheduled_review(&card, original.interval, usn)?;
|
||||
col.update_card_inner(&mut card, original, usn)?;
|
||||
}
|
||||
|
@ -228,26 +244,26 @@ mod test {
|
|||
let mut c = Card::new(NoteId(0), 0, DeckId(0), 0);
|
||||
|
||||
// setting the due date of a new card will convert it
|
||||
c.set_due_date(5, 2, 1.8, false);
|
||||
c.set_due_date(5, 0, 2, 1.8, false);
|
||||
assert_eq!(c.ctype, CardType::Review);
|
||||
assert_eq!(c.due, 7);
|
||||
assert_eq!(c.interval, 2);
|
||||
assert_eq!(c.ease_factor, 1800);
|
||||
|
||||
// reschedule it again the next day, shifting it from day 7 to day 9
|
||||
c.set_due_date(6, 3, 2.5, false);
|
||||
c.set_due_date(6, 0, 3, 2.5, false);
|
||||
assert_eq!(c.due, 9);
|
||||
assert_eq!(c.interval, 2);
|
||||
assert_eq!(c.ease_factor, 1800); // interval doesn't change
|
||||
|
||||
// we can bring cards forward too - return it to its original due date
|
||||
c.set_due_date(6, 1, 2.4, false);
|
||||
c.set_due_date(6, 0, 1, 2.4, false);
|
||||
assert_eq!(c.due, 7);
|
||||
assert_eq!(c.interval, 2);
|
||||
assert_eq!(c.ease_factor, 1800); // interval doesn't change
|
||||
|
||||
// we can force the interval to be reset instead of shifted
|
||||
c.set_due_date(6, 3, 2.3, true);
|
||||
c.set_due_date(6, 0, 3, 2.3, true);
|
||||
assert_eq!(c.due, 9);
|
||||
assert_eq!(c.interval, 3);
|
||||
assert_eq!(c.ease_factor, 1800); // interval doesn't change
|
||||
|
@ -259,7 +275,7 @@ mod test {
|
|||
c.original_deck_id = DeckId(1);
|
||||
c.due = -10000;
|
||||
c.queue = CardQueue::New;
|
||||
c.set_due_date(6, 1, 2.2, false);
|
||||
c.set_due_date(6, 0, 1, 2.2, false);
|
||||
assert_eq!(c.due, 7);
|
||||
assert_eq!(c.interval, 2);
|
||||
assert_eq!(c.ease_factor, 2200);
|
||||
|
@ -271,7 +287,7 @@ mod test {
|
|||
c.ctype = CardType::Relearn;
|
||||
c.original_due = c.due;
|
||||
c.due = 12345678;
|
||||
c.set_due_date(6, 10, 2.1, false);
|
||||
c.set_due_date(6, 0, 10, 2.1, false);
|
||||
assert_eq!(c.due, 16);
|
||||
assert_eq!(c.interval, 2);
|
||||
assert_eq!(c.ease_factor, 2200); // interval doesn't change
|
||||
|
|
Loading…
Reference in a new issue