CalendrierOuvre.swift
70 lignes · 2496 octets
import Foundation /// Calendrier ouvré d'un projet — port de `Server/src/services/calendrier.rs`, /// décalqué du Kotlin `planning/CalendrierOuvre.kt`. /// /// Les durées de tâches se comptent en jours **ouvrés** selon le rythme du /// projet (`joursOuvres` : 5 = lun-ven, 6 = lun-sam, 7 = tous les jours). Une /// tâche ne peut donc pas calculer sa fin seule : il lui faut le calendrier de /// son projet. Sans ce port, le téléphone afficherait une fin différente de /// celle du diagramme web. /// /// Les trois implémentations sont tenues par les mêmes cas de test : /// `Server/tests/calendrier.rs`, `CalendrierOuvreTest.kt` et `CalendrierOuvreTest.swift`. struct CalendrierOuvre { /// Un rythme hors de 5-7 (donnée abîmée) retombe sur 7, comportement historique. private let rythme: Int init(joursOuvres: Int) { switch joursOuvres { case 5: rythme = 5 case 6: rythme = 6 default: rythme = 7 } } func estOuvre(_ jour: DateCivile) -> Bool { switch jour.jourDeSemaine { case 6: return rythme >= 6 // samedi case 7: return rythme >= 7 // dimanche default: return true } } /// Premier jour ouvré à partir de `jour` inclus. func caler(_ jour: DateCivile) -> DateCivile { var j = jour while !estOuvre(j) { j = j.plusJours(1) } return j } /// Avance de `n` jours ouvrés depuis `jour`, calé au préalable. func avancer(_ jour: DateCivile, _ n: Int) -> DateCivile { var j = caler(jour) for _ in 0..<max(n, 0) { j = caler(j.plusJours(1)) } return j } /// Nombre de jours ouvrés dans `[debut, fin]` inclus ; 0 si l'intervalle est inversé. func compter(_ debut: DateCivile, _ fin: DateCivile) -> Int { var n = 0 var j = debut while j <= fin { if estOuvre(j) { n += 1 } j = j.plusJours(1) } return n } /// Dernier jour inclus. Une durée nulle vaut un jour : jamais de période vide. func fin(_ debut: DateCivile, _ dureeJours: Int) -> DateCivile { avancer(debut, max(dureeJours, 1) - 1) } /// « 09/01 → 13/01 », ou le jour seul si la tâche tient sur une journée. func periodeAffichee(_ debut: DateCivile, _ dureeJours: Int) -> String { let f = fin(debut, dureeJours) let d = caler(debut) return d == f ? d.jourMois : "\(d.jourMois) → \(f.jourMois)" } }
GitRust