extern crate zoneinfo_parse;
extern crate datetime;
use zoneinfo_parse::line::{Line, DaySpec, WeekdaySpec, MonthSpec, YearSpec, TimeSpec, ChangeTime};
use zoneinfo_parse::table::{Saving, ZoneInfo, RuleInfo, Table, Format, TableBuilder};
use zoneinfo_parse::transitions::{FixedTimespan, FixedTimespanSet, TableTransitions};
use datetime::Weekday::*;
use datetime::Month::*;
use datetime::zone::TimeType;
#[test]
fn no_transitions() {
let zone = ZoneInfo {
offset: 1234,
format: Format::new("TEST"),
saving: Saving::NoSaving,
end_time: None,
};
let mut table = Table::default();
table.zonesets.insert("Test/Zone".to_owned(), vec![ zone ]);
assert_eq!(table.timespans("Test/Zone"), Some(FixedTimespanSet {
first: FixedTimespan { utc_offset: 1234, dst_offset: 0, name: "TEST".to_owned() },
rest: vec![],
}));
}
#[test]
fn one_transition() {
let zone_1 = ZoneInfo {
offset: 1234,
format: Format::new("TEST"),
saving: Saving::NoSaving,
end_time: Some(ChangeTime::UntilTime(YearSpec::Number(1970), MonthSpec(January), DaySpec::Ordinal(2), TimeSpec::HoursMinutesSeconds(10, 17, 36).with_type(TimeType::UTC))),
};
let zone_2 = ZoneInfo {
offset: 5678,
format: Format::new("TSET"),
saving: Saving::NoSaving,
end_time: None,
};
let mut table = Table::default();
table.zonesets.insert("Test/Zone".to_owned(), vec![ zone_1, zone_2 ]);
let expected = FixedTimespanSet {
first: FixedTimespan { utc_offset: 1234, dst_offset: 0, name: "TEST".to_owned() },
rest: vec![
(122222, FixedTimespan { utc_offset: 5678, dst_offset: 0, name: "TSET".to_owned() }),
],
};
assert_eq!(table.timespans("Test/Zone"), Some(expected));
}
#[test]
fn two_transitions() {
let zone_1 = ZoneInfo {
offset: 1234,
format: Format::new("TEST"),
saving: Saving::NoSaving,
end_time: Some(ChangeTime::UntilTime(YearSpec::Number(1970), MonthSpec(January), DaySpec::Ordinal(2), TimeSpec::HoursMinutesSeconds(10, 17, 36).with_type(TimeType::Standard))),
};
let zone_2 = ZoneInfo {
offset: 3456,
format: Format::new("TSET"),
saving: Saving::NoSaving,
end_time: Some(ChangeTime::UntilTime(YearSpec::Number(1970), MonthSpec(January), DaySpec::Ordinal(3), TimeSpec::HoursMinutesSeconds(17, 09, 27).with_type(TimeType::Standard))),
};
let zone_3 = ZoneInfo {
offset: 5678,
format: Format::new("ESTE"),
saving: Saving::NoSaving,
end_time: None,
};
let mut table = Table::default();
table.zonesets.insert("Test/Zone".to_owned(), vec![ zone_1, zone_2, zone_3 ]);
let expected = FixedTimespanSet {
first: FixedTimespan { utc_offset: 1234, dst_offset: 0, name: "TEST".to_owned(), },
rest: vec![
(122222, FixedTimespan {
utc_offset: 3456,
dst_offset: 0,
name: "TSET".to_owned(),
}),
(231111, FixedTimespan {
utc_offset: 5678,
dst_offset: 0,
name: "ESTE".to_owned(),
}),
],
};
assert_eq!(table.timespans("Test/Zone"), Some(expected));
}
#[test]
fn one_rule() {
let ruleset = vec![
RuleInfo {
from_year: YearSpec::Number(1980),
to_year: None,
month: MonthSpec(February),
day: DaySpec::Ordinal(4),
time: 0,
time_type: TimeType::UTC,
time_to_add: 1000,
letters: None,
}
];
let lmt = ZoneInfo {
offset: 0,
format: Format::new("LMT"),
saving: Saving::NoSaving,
end_time: Some(ChangeTime::UntilYear(YearSpec::Number(1980))),
};
let zone = ZoneInfo {
offset: 2000,
format: Format::new("TEST"),
saving: Saving::Multiple("Dwayne".to_owned()),
end_time: None,
};
let mut table = Table::default();
table.zonesets.insert("Test/Zone".to_owned(), vec![ lmt, zone ]);
table.rulesets.insert("Dwayne".to_owned(), ruleset);
assert_eq!(table.timespans("Test/Zone"), Some(FixedTimespanSet {
first: FixedTimespan { utc_offset: 0, dst_offset: 0, name: "LMT".to_owned() },
rest: vec![
(318_470_400, FixedTimespan { utc_offset: 2000, dst_offset: 1000, name: "TEST".to_owned() })
],
}));
}
#[test]
fn two_rules() {
let ruleset = vec![
RuleInfo {
from_year: YearSpec::Number(1980),
to_year: None,
month: MonthSpec(February),
day: DaySpec::Ordinal(4),
time: 0,
time_type: TimeType::UTC,
time_to_add: 1000,
letters: None,
},
RuleInfo {
from_year: YearSpec::Number(1989),
to_year: None,
month: MonthSpec(January),
day: DaySpec::Ordinal(12),
time: 0,
time_type: TimeType::UTC,
time_to_add: 1500,
letters: None,
},
];
let lmt = ZoneInfo {
offset: 0,
format: Format::new("LMT"),
saving: Saving::NoSaving,
end_time: Some(ChangeTime::UntilYear(YearSpec::Number(1980))),
};
let zone = ZoneInfo {
offset: 2000,
format: Format::new("TEST"),
saving: Saving::Multiple("Dwayne".to_owned()),
end_time: None,
};
let mut table = Table::default();
table.zonesets.insert("Test/Zone".to_owned(), vec![ lmt, zone ]);
table.rulesets.insert("Dwayne".to_owned(), ruleset);
assert_eq!(table.timespans("Test/Zone"), Some(FixedTimespanSet {
first: FixedTimespan { utc_offset: 0, dst_offset: 0, name: "LMT".to_owned() },
rest: vec![
(318_470_400, FixedTimespan { utc_offset: 2000, dst_offset: 1000, name: "TEST".to_owned() }),
(600_566_400, FixedTimespan { utc_offset: 2000, dst_offset: 1500, name: "TEST".to_owned() }),
],
}));
}
#[test]
fn tripoli() {
let libya = vec![
RuleInfo { from_year: YearSpec::Number(1951), to_year: None, month: MonthSpec(October), day: DaySpec::Ordinal(14), time: 7200, time_type: TimeType::Wall, time_to_add: 3600, letters: Some("S".to_owned()) },
RuleInfo { from_year: YearSpec::Number(1952), to_year: None, month: MonthSpec(January), day: DaySpec::Ordinal(1), time: 0, time_type: TimeType::Wall, time_to_add: 0, letters: None },
RuleInfo { from_year: YearSpec::Number(1953), to_year: None, month: MonthSpec(October), day: DaySpec::Ordinal(9), time: 7200, time_type: TimeType::Wall, time_to_add: 3600, letters: Some("S".to_owned()) },
RuleInfo { from_year: YearSpec::Number(1954), to_year: None, month: MonthSpec(January), day: DaySpec::Ordinal(1), time: 0, time_type: TimeType::Wall, time_to_add: 0, letters: None },
RuleInfo { from_year: YearSpec::Number(1955), to_year: None, month: MonthSpec(September), day: DaySpec::Ordinal(30), time: 0, time_type: TimeType::Wall, time_to_add: 3600, letters: Some("S".to_owned()) },
RuleInfo { from_year: YearSpec::Number(1956), to_year: None, month: MonthSpec(January), day: DaySpec::Ordinal(1), time: 0, time_type: TimeType::Wall, time_to_add: 0, letters: None },
RuleInfo { from_year: YearSpec::Number(1982), to_year: Some(YearSpec::Number(1984)), month: MonthSpec(April), day: DaySpec::Ordinal(1), time: 0, time_type: TimeType::Wall, time_to_add: 3600, letters: Some("S".to_owned()) },
RuleInfo { from_year: YearSpec::Number(1982), to_year: Some(YearSpec::Number(1985)), month: MonthSpec(October), day: DaySpec::Ordinal(1), time: 0, time_type: TimeType::Wall, time_to_add: 0, letters: None },
RuleInfo { from_year: YearSpec::Number(1985), to_year: None, month: MonthSpec(April), day: DaySpec::Ordinal(6), time: 0, time_type: TimeType::Wall, time_to_add: 3600, letters: Some("S".to_owned()) },
RuleInfo { from_year: YearSpec::Number(1986), to_year: None, month: MonthSpec(April), day: DaySpec::Ordinal(4), time: 0, time_type: TimeType::Wall, time_to_add: 3600, letters: Some("S".to_owned()) },
RuleInfo { from_year: YearSpec::Number(1986), to_year: None, month: MonthSpec(October), day: DaySpec::Ordinal(3), time: 0, time_type: TimeType::Wall, time_to_add: 0, letters: None },
RuleInfo { from_year: YearSpec::Number(1987), to_year: Some(YearSpec::Number(1989)), month: MonthSpec(April), day: DaySpec::Ordinal(1), time: 0, time_type: TimeType::Wall, time_to_add: 3600, letters: Some("S".to_owned()) },
RuleInfo { from_year: YearSpec::Number(1987), to_year: Some(YearSpec::Number(1989)), month: MonthSpec(October), day: DaySpec::Ordinal(1), time: 0, time_type: TimeType::Wall, time_to_add: 0, letters: None },
RuleInfo { from_year: YearSpec::Number(1997), to_year: None, month: MonthSpec(April), day: DaySpec::Ordinal(4), time: 0, time_type: TimeType::Wall, time_to_add: 3600, letters: Some("S".to_owned()) },
RuleInfo { from_year: YearSpec::Number(1997), to_year: None, month: MonthSpec(October), day: DaySpec::Ordinal(4), time: 0, time_type: TimeType::Wall, time_to_add: 0, letters: None },
RuleInfo { from_year: YearSpec::Number(2013), to_year: None, month: MonthSpec(March), day: DaySpec::Last(WeekdaySpec(Friday)), time: 3600, time_type: TimeType::Wall, time_to_add: 3600, letters: Some("S".to_owned()) },
RuleInfo { from_year: YearSpec::Number(2013), to_year: None, month: MonthSpec(October), day: DaySpec::Last(WeekdaySpec(Friday)), time: 7200, time_type: TimeType::Wall, time_to_add: 0, letters: None },
];
let zone = vec![
ZoneInfo { offset: 3164, format: Format::new("LMT"), saving: Saving::NoSaving, end_time: Some(ChangeTime::UntilYear(YearSpec::Number(1920))) },
ZoneInfo { offset: 3600, format: Format::new("CE%sT"), saving: Saving::Multiple("Libya".to_owned()), end_time: Some(ChangeTime::UntilYear(YearSpec::Number(1959))) },
ZoneInfo { offset: 7200, format: Format::new("EET"), saving: Saving::NoSaving, end_time: Some(ChangeTime::UntilYear(YearSpec::Number(1982))) },
ZoneInfo { offset: 3600, format: Format::new("CE%sT"), saving: Saving::Multiple("Libya".to_owned()), end_time: Some(ChangeTime::UntilDay (YearSpec::Number(1990), MonthSpec(May), DaySpec::Ordinal( 4))) },
ZoneInfo { offset: 7200, format: Format::new("EET"), saving: Saving::NoSaving, end_time: Some(ChangeTime::UntilDay (YearSpec::Number(1996), MonthSpec(September), DaySpec::Ordinal(30))) },
ZoneInfo { offset: 3600, format: Format::new("CE%sT"), saving: Saving::Multiple("Libya".to_owned()), end_time: Some(ChangeTime::UntilDay (YearSpec::Number(1997), MonthSpec(October), DaySpec::Ordinal( 4))) },
ZoneInfo { offset: 7200, format: Format::new("EET"), saving: Saving::NoSaving, end_time: Some(ChangeTime::UntilTime(YearSpec::Number(2012), MonthSpec(November), DaySpec::Ordinal(10), TimeSpec::HoursMinutes(2, 0).with_type(TimeType::Wall))) },
ZoneInfo { offset: 3600, format: Format::new("CE%sT"), saving: Saving::Multiple("Libya".to_owned()), end_time: Some(ChangeTime::UntilTime(YearSpec::Number(2013), MonthSpec(October), DaySpec::Ordinal(25), TimeSpec::HoursMinutes(2, 0).with_type(TimeType::Wall))) },
ZoneInfo { offset: 7200, format: Format::new("EET"), saving: Saving::NoSaving, end_time: None },
];
let mut table = Table::default();
table.zonesets.insert("Test/Zone".to_owned(), zone);
table.rulesets.insert("Libya".to_owned(), libya);
assert_eq!(table.timespans("Test/Zone"), Some(FixedTimespanSet {
first: FixedTimespan { utc_offset: 3164, dst_offset: 0, name: "LMT".to_owned() },
rest: vec![
(-1_577_926_364, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( -574_902_000, FixedTimespan { utc_offset: 3600, dst_offset: 3600, name: "CEST".to_owned() }),
( -568_087_200, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( -512_175_600, FixedTimespan { utc_offset: 3600, dst_offset: 3600, name: "CEST".to_owned() }),
( -504_928_800, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( -449_888_400, FixedTimespan { utc_offset: 3600, dst_offset: 3600, name: "CEST".to_owned() }),
( -441_856_800, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( -347_158_800, FixedTimespan { utc_offset: 7200, dst_offset: 0, name: "EET".to_owned() }),
( 378_684_000, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( 386_463_600, FixedTimespan { utc_offset: 3600, dst_offset: 3600, name: "CEST".to_owned() }),
( 402_271_200, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( 417_999_600, FixedTimespan { utc_offset: 3600, dst_offset: 3600, name: "CEST".to_owned() }),
( 433_807_200, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( 449_622_000, FixedTimespan { utc_offset: 3600, dst_offset: 3600, name: "CEST".to_owned() }),
( 465_429_600, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( 481_590_000, FixedTimespan { utc_offset: 3600, dst_offset: 3600, name: "CEST".to_owned() }),
( 496_965_600, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( 512_953_200, FixedTimespan { utc_offset: 3600, dst_offset: 3600, name: "CEST".to_owned() }),
( 528_674_400, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( 544_230_000, FixedTimespan { utc_offset: 3600, dst_offset: 3600, name: "CEST".to_owned() }),
( 560_037_600, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( 575_852_400, FixedTimespan { utc_offset: 3600, dst_offset: 3600, name: "CEST".to_owned() }),
( 591_660_000, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( 607_388_400, FixedTimespan { utc_offset: 3600, dst_offset: 3600, name: "CEST".to_owned() }),
( 623_196_000, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( 641_775_600, FixedTimespan { utc_offset: 7200, dst_offset: 0, name: "EET".to_owned() }),
( 844_034_400, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( 860_108_400, FixedTimespan { utc_offset: 3600, dst_offset: 3600, name: "CEST".to_owned() }),
( 875_916_000, FixedTimespan { utc_offset: 7200, dst_offset: 0, name: "EET".to_owned() }),
( 1_352_505_600, FixedTimespan { utc_offset: 3600, dst_offset: 0, name: "CET".to_owned() }),
( 1_364_515_200, FixedTimespan { utc_offset: 3600, dst_offset: 3600, name: "CEST".to_owned() }),
( 1_382_659_200, FixedTimespan { utc_offset: 7200, dst_offset: 0, name: "EET".to_owned() }),
],
}));
}
#[test]
fn dushanbe() {
static ZONEINFO : &'static str = r#"
Zone Asia/Dushanbe 4:35:12 - LMT 1924 May 2
5:00 1:00 +05/+06 1991 Sep 9 2:00s
"#;
let mut table = TableBuilder::new();
for line in ZONEINFO.lines() {
let line = Line::from_str(line).unwrap();
match line {
Line::Zone(zone) => table.add_zone_line(zone).unwrap(),
Line::Continuation(cont) => table.add_continuation_line(cont).unwrap(),
Line::Rule(rule) => table.add_rule_line(rule).unwrap(),
Line::Link(link) => table.add_link_line(link).unwrap(),
Line::Space => {},
}
}
let table = table.build();
let _ = table.timespans("Asia/Dushanbe").unwrap();
}