↑Programmieren in Rust
Das julianische Datum ist eine Zählung der Tage seit dem 1. Januar −4712 um 12:00 Uhr. Die Bewandtnis der Umrechnung zwischen Kalenderdatum und julianischem Daten ist
// Angabe des Kalenders. // Greg für gregorianischer Kalender, // Jul für julianischer Kalender. pub enum Calendar {Greg, Jul} // Bruchteil eines Tages sind Stunden/24 + Minuten/(24*60). pub struct Date { pub year: i32, pub month: i32, pub day: f64 } // Umrechnung eines Kalenderdatums ins julianische Datum. pub fn julian_date(calendar: Calendar, date: Date) -> f64 { let (y, m) = if date.month > 2 { (f64::from(date.year), f64::from(date.month)) } else { (f64::from(date.year - 1), f64::from(date.month + 12)) }; let b = if let Calendar::Jul = calendar {0.0} else { 2.0 - (y/100.0).floor() + (y/400.0).floor() }; (365.25*(y + 4716.0)).floor() + (30.6001*(m + 1.0)).floor() + date.day + b - 1524.5 } // Umrechnung eines julianischen Datums ins Kalenderdatum. #[allow(non_snake_case)] pub fn calendar_date(calendar: Calendar, jd: f64) -> Date { let Z = (jd + 0.5).floor(); let F = jd + 0.5 - Z; let A = if let Calendar::Jul = calendar {Z} else { let alpha = ((Z - 1867216.25)/36524.25).floor(); Z + 1.0 + alpha - (alpha/4.0).floor() }; let B = A + 1524.0; let C = ((B - 122.1)/365.25).floor(); let D = (365.25*C).floor(); let E = ((B - D)/30.6001).floor(); let day = B - D - (30.6001*E).floor() + F; if E <= 13.0 { Date {day, month: E as i32 - 1, year: C as i32 - 4716} } else { Date {day, month: E as i32 - 13, year: C as i32 - 4715} } }
Diesen Umrechnungen dienen nun als Hilfsmittel zur Formulierung
der Funktion shift_date
, die das um eine Anzahl von Tagen
verschobene Datum berechnet. Im julianischen Datum ist diese
Verschiebung nämlich einfach die Addition der Anzahl. Demzufolge muss
man zunächst ins julianische Datum umrechnen, dann die Anzahl addieren,
und schließlich wieder zurück ins Kalenderdatum umrechnen.
pub fn shift_date(date: Date, days: f64) -> Date { let jd = julian_date(Calendar::Greg, date); let mut date = calendar_date(Calendar::Greg, jd + days); date.day = date.day.round(); date }
Zellers Kongruenz ist eine Formel zur Ermittlung des Wochentags zu einem Datum.
static DAY_DE: [&str; 7] = [ "Sa", "So", "Mo", "Di", "Mi", "Do", "Fr" ]; static DAY_EN: [&str; 7] = [ "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri" ]; pub struct Day(i32); impl Day { pub fn de(self) -> &'static str {DAY_DE[self.0 as usize]} pub fn en(self) -> &'static str {DAY_EN[self.0 as usize]} } pub fn day_of_the_week(year: i32, month: i32, day: i32) -> Day { let j = year/100; let k = (year - if month>2 {0} else {1}) % 100; let m = month + if month>2 {0} else {12}; let n = (day + (m+1)*13/5 + k + k/4 + j/4 - 2*j) % 7; Day(n) }
Die Ermittlung des Wochentags ist auch über das julianische
Datum möglich. Den abgerundeten Wert braucht man nur um
+3
verschieben und modulo sieben nehmen.
pub fn day_of_the_week(year: i32, month: i32, day: i32) -> Day { let date = Date {year, month, day: f64::from(day)}; let jd = julian_date(Calendar::Greg, date); Day((jd as i32 + 3) % 7) }