1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//! Excel の日付の数を、年月日と行き来するところ
use folio::date::{self, Moment};
/// 時刻のない日付
fn day(year: i64, month: u32, number: u32) -> Moment {
Moment {year, month, day: number, hour: 0, minute: 0, second: 0}
}
#[test]
fn the_known_landmarks_match() {
// Excel が入っていれば、どの版でもこの対応になる
assert_eq!(date::moment(1.0, false), day(1900, 1, 1));
assert_eq!(date::moment(59.0, false), day(1900, 2, 28));
assert_eq!(date::moment(61.0, false), day(1900, 3, 1));
assert_eq!(date::moment(25569.0, false), day(1970, 1, 1));
assert_eq!(date::moment(45000.0, false), day(2023, 3, 15));
}
#[test]
fn the_1904_system_starts_four_years_later() {
assert_eq!(date::moment(0.0, true), day(1904, 1, 1));
assert_eq!(date::moment(1.0, true), day(1904, 1, 2));
assert_eq!(date::moment(24107.0, true), day(1970, 1, 1));
}
#[test]
fn the_fraction_becomes_the_time_of_day() {
let noon = date::moment(45000.5, false);
assert_eq!(noon, Moment {year: 2023, month: 3, day: 15, hour: 12, minute: 0, second: 0});
let when = date::moment(45000.0 + (13.0 * 3600.0 + 45.0 * 60.0 + 30.0) / 86400.0, false);
assert_eq!(when, Moment {year: 2023, month: 3, day: 15, hour: 13, minute: 45, second: 30});
}
#[test]
fn going_out_and_back_gives_the_same_moment() {
let sample = [
day(1900, 1, 1),
day(1900, 3, 1),
day(1970, 1, 1),
day(2000, 2, 29),
day(2026, 9, 8),
day(2099, 12, 31),
Moment {year: 2026, month: 9, day: 8, hour: 23, minute: 59, second: 59},
Moment {year: 1999, month: 12, day: 31, hour: 12, minute: 34, second: 56},
];
for one in sample {
for epoch1904 in [false, true] {
let serial = date::serial(&one, epoch1904);
assert_eq!(date::moment(serial, epoch1904), one, "{one:?} 1904={epoch1904}");
}
}
}
#[test]
fn every_day_of_a_long_stretch_survives_the_trip() {
// 1900 年のずれをまたいで、1 日ずつ確かめる
for serial in 1..40000 {
let when = date::moment(serial as f64, false);
// 60 は Excel にしかない 1900-02-29 なので、行きと帰りが一致しない
if serial == 60 {
continue;
}
assert_eq!(date::serial(&when, false), serial as f64, "{serial}");
}
}