diff --git a/src/ds323x/alarms.rs b/src/ds323x/alarms.rs
index 9774794..d5b91f2 100644
--- a/src/ds323x/alarms.rs
+++ b/src/ds323x/alarms.rs
@@ -5,6 +5,12 @@ use super::{decimal_to_packed_bcd, hours_to_register};
 use interface::{ReadData, WriteData};
 
 /// Parameters for setting Alarm1 on a day of the month
+///
+/// Depending on the matching strategy, some fields may not be relevant. In this
+/// case, invalid values are ignored and basic values are used instead to
+/// configure the alarm:
+/// - second, minute and hour : 0
+/// - day: 1
 #[derive(Debug, Clone, Copy, PartialEq)]
 pub struct DayAlarm1 {
     /// Day of the month [1-31]
@@ -18,6 +24,12 @@ pub struct DayAlarm1 {
 }
 
 /// Parameters for setting Alarm1 on a weekday
+///
+/// Depending on the matching strategy, some fields may not be relevant. In this
+/// case, invalid values are ignored and basic values are used instead to
+/// configure the alarm:
+/// - second, minute and hour : 0
+/// - weekday: 1
 #[derive(Debug, Clone, Copy, PartialEq)]
 pub struct WeekdayAlarm1 {
     /// Weekday [1-7]
@@ -46,6 +58,12 @@ pub enum Alarm1Matching {
 }
 
 /// Parameters for setting Alarm2 on a day of the month
+///
+/// Depending on the matching strategy, some fields may not be relevant. In this
+/// case, invalid values are ignored and basic values are used instead to
+/// configure the alarm:
+/// - minute and hour : 0
+/// - day: 1
 #[derive(Debug, Clone, Copy, PartialEq)]
 pub struct DayAlarm2 {
     /// Day of month [1-31]
@@ -57,6 +75,12 @@ pub struct DayAlarm2 {
 }
 
 /// Parameters for setting Alarm2 on a weekday
+///
+/// Depending on the matching strategy, some fields may not be relevant. In this
+/// case, invalid values are ignored and basic values are used instead to
+/// configure the alarm:
+/// - minute and hour : 0
+/// - weekday: 1
 #[derive(Debug, Clone, Copy, PartialEq)]
 pub struct WeekdayAlarm2 {
     /// Weekday [1-7]
@@ -101,92 +125,187 @@ fn get_matching_mask_alarm2(matching: Alarm2Matching) -> [u8; 3] {
     }
 }
 
+/// Test if hours value is valid
+///
+/// Will return true if valid, false if not
+fn is_hour_valid(hours: Hours) -> bool {
+    match hours {
+        Hours::H24(h) if h > 23 => true,
+        Hours::AM(h) if h < 1 || h > 12 => true,
+        Hours::PM(h) if h < 1 || h > 12 => true,
+        _ => false,
+    }
+}
+
+/// Relax the hour value by changing an incorrect value by 0
+fn relax_hour(hours: Hours) -> Hours {
+    match hours {
+        Hours::H24(h) if h > 23 => Hours::H24(0),
+        Hours::H24(h) => Hours::H24(h),
+        Hours::AM(h) if h < 1 || h > 12 => Hours::AM(1),
+        Hours::AM(h) => Hours::AM(h),
+        Hours::PM(h) if h < 1 || h > 12 => Hours::PM(1),
+        Hours::PM(h) => Hours::PM(h),
+    }
+}
+
 impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
 where
     DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>,
 {
     /// Set Alarm1 for day of the month.
     ///
-    /// Will return an `Error::InvalidInputData` if any of the parameters is out of range.
+    /// Will return an `Error::InvalidInputData` if any of the used parameters
+    /// (depending on the matching startegy) is out of range. Any unused
+    /// parameter is set to basic valid value:
+    /// - second, minute, hour: 0
+    /// - day: 1
     pub fn set_alarm1_day(
         &mut self,
         when: DayAlarm1,
         matching: Alarm1Matching,
     ) -> Result<(), Error<CommE, PinE>> {
-        if when.day < 1 || when.day > 31 || when.minute > 59 || when.second > 59 {
+        let day_invalid = when.day < 1 || when.day > 31;
+        let hour_invalid = is_hour_valid(when.hour);
+        let minute_invalid = when.minute > 59;
+        let second_invalid = when.second > 59;
+
+        let day = if day_invalid { 1 } else { when.day };
+        let hour = relax_hour(when.hour);
+        let minute = if minute_invalid { 0 } else { when.minute };
+
+        if (matching == Alarm1Matching::AllMatch && (day_invalid || hour_invalid))
+            || (hour_invalid && matching == Alarm1Matching::HoursMinutesAndSecondsMatch)
+            || ((matching != Alarm1Matching::SecondsMatch
+                && matching != Alarm1Matching::OncePerSecond)
+                && minute_invalid)
+            || second_invalid
+        {
             return Err(Error::InvalidInputData);
         }
+
         let match_mask = get_matching_mask_alarm1(matching);
         let mut data = [
             Register::ALARM1_SECONDS,
             decimal_to_packed_bcd(when.second) | match_mask[0],
-            decimal_to_packed_bcd(when.minute) | match_mask[1],
-            hours_to_register(when.hour)? | match_mask[2],
-            decimal_to_packed_bcd(when.day) | match_mask[3],
+            decimal_to_packed_bcd(minute) | match_mask[1],
+            hours_to_register(hour)? | match_mask[2],
+            decimal_to_packed_bcd(day) | match_mask[3],
         ];
         self.iface.write_data(&mut data)
     }
 
     /// Set Alarm1 for weekday.
     ///
-    /// Will return an `Error::InvalidInputData` if any of the parameters is out of range.
+    /// Will return an `Error::InvalidInputData` if any of the used parameters
+    /// (depending on the matching startegy) is out of range. Any unused
+    /// parameter is set to basic valid value:
+    /// - second, minute, hour: 0
+    /// - weekday: 1
     pub fn set_alarm1_weekday(
         &mut self,
         when: WeekdayAlarm1,
         matching: Alarm1Matching,
     ) -> Result<(), Error<CommE, PinE>> {
-        if when.weekday < 1 || when.weekday > 7 || when.minute > 59 || when.second > 59 {
+        let weekday_invalid = when.weekday < 1 || when.weekday > 7;
+        let hour_invalid = is_hour_valid(when.hour);
+        let minute_invalid = when.minute > 59;
+        let second_invalid = when.second > 59;
+
+        let weekday = if weekday_invalid { 1 } else { when.weekday };
+        let hour = relax_hour(when.hour);
+        let minute = if minute_invalid { 0 } else { when.minute };
+        let second = if second_invalid { 0 } else { when.second };
+
+        if ((hour_invalid || weekday_invalid) && matching == Alarm1Matching::AllMatch)
+            || (hour_invalid && matching == Alarm1Matching::HoursMinutesAndSecondsMatch)
+            || (minute_invalid
+                && (matching != Alarm1Matching::OncePerSecond
+                    && matching != Alarm1Matching::SecondsMatch))
+            || (second_invalid && matching != Alarm1Matching::OncePerSecond)
+        {
             return Err(Error::InvalidInputData);
         }
         let match_mask = get_matching_mask_alarm1(matching);
         let mut data = [
             Register::ALARM1_SECONDS,
-            decimal_to_packed_bcd(when.second) | match_mask[0],
-            decimal_to_packed_bcd(when.minute) | match_mask[1],
-            hours_to_register(when.hour)? | match_mask[2],
-            decimal_to_packed_bcd(when.weekday) | match_mask[3] | BitFlags::WEEKDAY,
+            decimal_to_packed_bcd(second) | match_mask[0],
+            decimal_to_packed_bcd(minute) | match_mask[1],
+            hours_to_register(hour)? | match_mask[2],
+            decimal_to_packed_bcd(weekday) | match_mask[3] | BitFlags::WEEKDAY,
         ];
         self.iface.write_data(&mut data)
     }
 
     /// Set Alarm2 for date (day of month).
     ///
-    /// Will return an `Error::InvalidInputData` if any of the parameters is out of range.
+    /// Will return an `Error::InvalidInputData` if any of the used parameters
+    /// (depending on the matching startegy) is out of range. Any unused
+    /// parameter is set to basic valid value:
+    /// - minute, hour: 0
+    /// - day: 1
     pub fn set_alarm2_day(
         &mut self,
         when: DayAlarm2,
         matching: Alarm2Matching,
     ) -> Result<(), Error<CommE, PinE>> {
-        if when.day < 1 || when.day > 31 || when.minute > 59 {
+        let day_invalid = when.day < 1 || when.day > 31;
+        let hour_invalid = is_hour_valid(when.hour);
+        let minute_invalid = when.minute > 59;
+
+        let day = if day_invalid { 1 } else { when.day };
+        let hour = relax_hour(when.hour);
+        let minute = if minute_invalid { 0 } else { when.minute };
+
+        if ((day_invalid || hour_invalid) && matching == Alarm2Matching::AllMatch)
+            || (hour_invalid && matching == Alarm2Matching::HoursAndMinutesMatch)
+            || (matching != Alarm2Matching::OncePerMinute && minute_invalid)
+        {
             return Err(Error::InvalidInputData);
         }
+
         let match_mask = get_matching_mask_alarm2(matching);
         let mut data = [
             Register::ALARM2_MINUTES,
-            decimal_to_packed_bcd(when.minute) | match_mask[0],
-            hours_to_register(when.hour)? | match_mask[1],
-            decimal_to_packed_bcd(when.day) | match_mask[2],
+            decimal_to_packed_bcd(minute) | match_mask[0],
+            hours_to_register(hour)? | match_mask[1],
+            decimal_to_packed_bcd(day) | match_mask[2],
         ];
         self.iface.write_data(&mut data)
     }
 
     /// Set Alarm2 for weekday.
     ///
-    /// Will return an `Error::InvalidInputData` if any of the parameters is out of range.
+    /// Will return an `Error::InvalidInputData` if any of the used parameters
+    /// (depending on the matching startegy) is out of range. Any unused
+    /// parameter is set to basic valid value:
+    /// - minute, hour: 0
+    /// - weekday: 1
     pub fn set_alarm2_weekday(
         &mut self,
         when: WeekdayAlarm2,
         matching: Alarm2Matching,
     ) -> Result<(), Error<CommE, PinE>> {
-        if when.weekday < 1 || when.weekday > 7 || when.minute > 59 {
+        let weekday_invalid = when.weekday < 1 || when.weekday > 7;
+        let hour_invalid = is_hour_valid(when.hour);
+        let minute_invalid = when.minute > 59;
+
+        let weekday = if weekday_invalid { 1 } else { when.weekday };
+        let hour = relax_hour(when.hour);
+        let minute = if minute_invalid { 0 } else { when.minute };
+
+        if (matching == Alarm2Matching::AllMatch && (weekday_invalid || hour_invalid))
+            || (matching == Alarm2Matching::HoursAndMinutesMatch && hour_invalid)
+            || (minute_invalid && matching != Alarm2Matching::OncePerMinute)
+        {
             return Err(Error::InvalidInputData);
         }
         let match_mask = get_matching_mask_alarm2(matching);
         let mut data = [
             Register::ALARM2_MINUTES,
-            decimal_to_packed_bcd(when.minute) | match_mask[0],
-            hours_to_register(when.hour)? | match_mask[1],
-            decimal_to_packed_bcd(when.weekday) | match_mask[2] | BitFlags::WEEKDAY,
+            decimal_to_packed_bcd(minute) | match_mask[0],
+            hours_to_register(hour)? | match_mask[1],
+            decimal_to_packed_bcd(weekday) | match_mask[2] | BitFlags::WEEKDAY,
         ];
         self.iface.write_data(&mut data)
     }
diff --git a/tests/alarms.rs b/tests/alarms.rs
index 6ebc786..c9f3908 100644
--- a/tests/alarms.rs
+++ b/tests/alarms.rs
@@ -14,18 +14,18 @@ use ds323x::{
 
 #[macro_export]
 macro_rules! _set_invalid_alarm_test {
-    ($name:ident, $method:ident, $create_method:ident, $destroy_method:ident, $alarm:expr, $matching:expr) => {
+    ($name:ident, $method:ident, $create_method:ident, $destroy_method:ident, $( $value:expr ),+) => {
         #[test]
         fn $name() {
             let mut dev = $create_method(&[]);
-            assert_invalid_input_data!(dev.$method($alarm, $matching));
+            assert_invalid_input_data!(dev.$method($($value),*));
             $destroy_method(dev);
         }
     };
 }
 
 macro_rules! set_invalid_alarm_test {
-    ($name:ident, $method:ident, $alarm:expr, $matching:expr) => {
+    ($name:ident, $method:ident, $( $value:expr ),+) => {
         mod $name {
             use super::*;
             _set_invalid_alarm_test!(
@@ -33,24 +33,21 @@ macro_rules! set_invalid_alarm_test {
                 $method,
                 new_ds3231,
                 destroy_ds3231,
-                $alarm,
-                $matching
+                $($value),*
             );
             _set_invalid_alarm_test!(
                 cannot_set_invalid_ds3232,
                 $method,
                 new_ds3232,
                 destroy_ds3232,
-                $alarm,
-                $matching
+                $($value),*
             );
             _set_invalid_alarm_test!(
                 cannot_set_invalid_ds3234,
                 $method,
                 new_ds3234,
                 destroy_ds3234,
-                $alarm,
-                $matching
+                $($value),*
             );
         }
     };
@@ -80,6 +77,28 @@ mod alarm1 {
         },
         A1M::AllMatch
     );
+    set_invalid_alarm_test!(
+        day_invalid_second,
+        set_alarm1_day,
+        DayAlarm1 {
+            day: 1,
+            hour: Hours::H24(1),
+            minute: 59,
+            second: 60
+        },
+        A1M::SecondsMatch
+    );
+    set_invalid_alarm_test!(
+        day_invalid_minute,
+        set_alarm1_day,
+        DayAlarm1 {
+            day: 1,
+            hour: Hours::H24(1),
+            minute: 60,
+            second: 10
+        },
+        A1M::MinutesAndSecondsMatch
+    );
     set_invalid_alarm_test!(
         day_invalid_h,
         set_alarm1_day,
@@ -91,6 +110,17 @@ mod alarm1 {
         },
         A1M::AllMatch
     );
+    set_invalid_alarm_test!(
+        day_invalid_h_hmasm,
+        set_alarm1_day,
+        DayAlarm1 {
+            day: 1,
+            hour: Hours::H24(24),
+            minute: 1,
+            second: 1
+        },
+        A1M::HoursMinutesAndSecondsMatch
+    );
     set_invalid_alarm_test!(
         day_invalid_am1,
         set_alarm1_day,
@@ -191,6 +221,18 @@ mod alarm1 {
         },
         A1M::AllMatch
     );
+    set_invalid_alarm_test!(
+        wd_invalid_h_hmasm,
+        set_alarm1_weekday,
+        WeekdayAlarm1 {
+            weekday: 1,
+            hour: Hours::H24(24),
+            minute: 1,
+            second: 1
+        },
+        A1M::HoursMinutesAndSecondsMatch
+    );
+
     set_invalid_alarm_test!(
         wd_invalid_am1,
         set_alarm1_weekday,
@@ -257,10 +299,42 @@ mod alarm1 {
         },
         A1M::AllMatch
     );
+    set_invalid_alarm_test!(
+        wd_invalid_sec_sm,
+        set_alarm1_weekday,
+        WeekdayAlarm1 {
+            weekday: 1,
+            hour: Hours::H24(1),
+            minute: 1,
+            second: 60
+        },
+        A1M::SecondsMatch
+    );
+    set_invalid_alarm_test!(
+        wd_invalid_min_masm,
+        set_alarm1_weekday,
+        WeekdayAlarm1 {
+            weekday: 1,
+            hour: Hours::H24(1),
+            minute: 60,
+            second: 1
+        },
+        A1M::MinutesAndSecondsMatch
+    );
 }
 
 mod alarm2 {
     use super::*;
+    set_invalid_alarm_test!(
+        day_invalid_min_mm,
+        set_alarm2_day,
+        DayAlarm2 {
+            day: 1,
+            hour: Hours::H24(1),
+            minute: 60
+        },
+        A2M::MinutesMatch
+    );
     set_invalid_alarm_test!(
         day_invalid_min,
         set_alarm2_day,
@@ -281,6 +355,16 @@ mod alarm2 {
         },
         A2M::AllMatch
     );
+    set_invalid_alarm_test!(
+        day_invalid_h_hamm,
+        set_alarm2_day,
+        DayAlarm2 {
+            day: 1,
+            hour: Hours::H24(24),
+            minute: 1
+        },
+        A2M::HoursAndMinutesMatch
+    );
     set_invalid_alarm_test!(
         day_invalid_am1,
         set_alarm2_day,
@@ -342,6 +426,16 @@ mod alarm2 {
         A2M::AllMatch
     );
 
+    set_invalid_alarm_test!(
+        wd_invalid_min_mm,
+        set_alarm2_weekday,
+        WeekdayAlarm2 {
+            weekday: 1,
+            hour: Hours::H24(1),
+            minute: 60
+        },
+        A2M::MinutesMatch
+    );
     set_invalid_alarm_test!(
         wd_invalid_min,
         set_alarm2_weekday,
@@ -362,6 +456,16 @@ mod alarm2 {
         },
         A2M::AllMatch
     );
+    set_invalid_alarm_test!(
+        wd_invalid_h_hmm,
+        set_alarm2_weekday,
+        WeekdayAlarm2 {
+            weekday: 1,
+            hour: Hours::H24(24),
+            minute: 1
+        },
+        A2M::HoursAndMinutesMatch
+    );
     set_invalid_alarm_test!(
         wd_invalid_am1,
         set_alarm2_weekday,
@@ -422,22 +526,32 @@ mod alarm2 {
         },
         A2M::AllMatch
     );
+    set_invalid_alarm_test!(
+        wd_invalid_minute,
+        set_alarm2_weekday,
+        WeekdayAlarm2 {
+            weekday: 1,
+            hour: Hours::H24(1),
+            minute: 60
+        },
+        A2M::HoursAndMinutesMatch
+    );
 }
 
 macro_rules! _set_values_test {
-    ($name:ident, $method:ident, $create_method:ident, $destroy_method:ident, $value1:expr, $value2:expr, $transactions:expr) => {
+    ($name:ident, $method:ident, $create_method:ident, $destroy_method:ident, $transactions:expr, $( $value:expr ),+) => {
         #[test]
         fn $name() {
             let trans = $transactions;
             let mut dev = $create_method(&trans);
-            dev.$method($value1, $value2).unwrap();
+            dev.$method($($value),*).unwrap();
             $destroy_method(dev);
         }
     };
 }
 
 macro_rules! set_values_test {
-    ($name:ident, $method:ident, $value1:expr, $value2:expr, $i2c_transactions:expr, $spi_transactions:expr) => {
+    ($name:ident, $method:ident, $i2c_transactions:expr, $spi_transactions:expr, $( $value:expr ),+) => {
         mod $name {
             use super::*;
             _set_values_test!(
@@ -445,37 +559,36 @@ macro_rules! set_values_test {
                 $method,
                 new_ds3231,
                 destroy_ds3231,
-                $value1,
-                $value2,
-                $i2c_transactions
+                $i2c_transactions,
+                $($value),*
             );
             _set_values_test!(
                 can_set_ds3232,
                 $method,
                 new_ds3232,
                 destroy_ds3232,
-                $value1,
-                $value2,
-                $i2c_transactions
+                $i2c_transactions,
+                $($value),*
             );
             _set_values_test!(
                 can_set_ds3234,
                 $method,
                 new_ds3234,
                 destroy_ds3234,
-                $value1,
-                $value2,
-                $spi_transactions
+                $spi_transactions,
+                $($value),*
             );
         }
     };
 }
 
 macro_rules! set_alarm_test {
-    ($name:ident, $method:ident, $alarm:expr, $matching:expr, $register:ident, [ $( $registers:expr ),+ ]) => {
-        set_values_test!($name, $method, $alarm, $matching,
+    ($name:ident, $method:ident, $register:ident, [ $( $registers:expr ),+ ], $( $value:expr ),+) => {
+        set_values_test!($name, $method,
             [ I2cTrans::write(DEV_ADDR, vec![Register::$register, $( $registers ),*]) ],
-            [ SpiTrans::write(vec![Register::$register + 0x80, $( $registers ),*]) ]);
+            [ SpiTrans::write(vec![Register::$register + 0x80, $( $registers ),*]) ],
+            $($value),*
+        );
     };
 }
 
@@ -486,94 +599,146 @@ mod alarm1_day {
     set_alarm_test!(
         h24,
         set_alarm1_day,
+        ALARM1_SECONDS,
+        [4, 3, 2, 1],
         DayAlarm1 {
             day: 1,
             hour: Hours::H24(2),
             minute: 3,
             second: 4
         },
-        A1M::AllMatch,
-        ALARM1_SECONDS,
-        [4, 3, 2, 1]
+        A1M::AllMatch
     );
     set_alarm_test!(
         am,
         set_alarm1_day,
+        ALARM1_SECONDS,
+        [4, 3, 0b0100_0010, 1],
         DayAlarm1 {
             day: 1,
             hour: Hours::AM(2),
             minute: 3,
             second: 4
         },
-        A1M::AllMatch,
-        ALARM1_SECONDS,
-        [4, 3, 0b0100_0010, 1]
+        A1M::AllMatch
     );
     set_alarm_test!(
         pm,
         set_alarm1_day,
+        ALARM1_SECONDS,
+        [4, 3, 0b0110_0010, 1],
         DayAlarm1 {
             day: 1,
             hour: Hours::PM(2),
             minute: 3,
             second: 4
         },
-        A1M::AllMatch,
-        ALARM1_SECONDS,
-        [4, 3, 0b0110_0010, 1]
+        A1M::AllMatch
     );
 
     set_alarm_test!(
         match_hms,
         set_alarm1_day,
+        ALARM1_SECONDS,
+        [4, 3, 2, AM | 1],
         DayAlarm1 {
             day: 1,
             hour: Hours::H24(2),
             minute: 3,
             second: 4
         },
-        A1M::HoursMinutesAndSecondsMatch,
+        A1M::HoursMinutesAndSecondsMatch
+    );
+    set_alarm_test!(
+        match_hms_ignore_incorrect_day,
+        set_alarm1_day,
         ALARM1_SECONDS,
-        [4, 3, 2, AM | 1]
+        [4, 3, 2, AM | 1],
+        DayAlarm1 {
+            day: 0,
+            hour: Hours::H24(2),
+            minute: 3,
+            second: 4
+        },
+        A1M::HoursMinutesAndSecondsMatch
+    );
+    set_alarm_test!(
+        match_ms_ignore_invalid_hour,
+        set_alarm1_day,
+        ALARM1_SECONDS,
+        [4, 3, AM | 0, AM | 1],
+        DayAlarm1 {
+            day: 1,
+            hour: Hours::H24(24),
+            minute: 3,
+            second: 4
+        },
+        A1M::MinutesAndSecondsMatch
     );
     set_alarm_test!(
         match_ms,
         set_alarm1_day,
+        ALARM1_SECONDS,
+        [4, 3, AM | 2, AM | 1],
         DayAlarm1 {
             day: 1,
             hour: Hours::H24(2),
             minute: 3,
             second: 4
         },
-        A1M::MinutesAndSecondsMatch,
+        A1M::MinutesAndSecondsMatch
+    );
+    set_alarm_test!(
+        match_ms_ignore_incorrect_day,
+        set_alarm1_day,
         ALARM1_SECONDS,
-        [4, 3, AM | 2, AM | 1]
+        [4, 3, AM | 2, AM | 1],
+        DayAlarm1 {
+            day: 0,
+            hour: Hours::H24(2),
+            minute: 3,
+            second: 4
+        },
+        A1M::MinutesAndSecondsMatch
     );
     set_alarm_test!(
         match_s,
         set_alarm1_day,
+        ALARM1_SECONDS,
+        [4, AM | 3, AM | 2, AM | 1],
         DayAlarm1 {
             day: 1,
             hour: Hours::H24(2),
             minute: 3,
             second: 4
         },
-        A1M::SecondsMatch,
+        A1M::SecondsMatch
+    );
+    set_alarm_test!(
+        match_s_ignore_incorrect_min,
+        set_alarm1_day,
         ALARM1_SECONDS,
-        [4, AM | 3, AM | 2, AM | 1]
+        [4, AM | 0, AM | 2, AM | 1],
+        DayAlarm1 {
+            day: 1,
+            hour: Hours::H24(2),
+            minute: 60,
+            second: 4
+        },
+        A1M::SecondsMatch
     );
     set_alarm_test!(
         match_ops,
         set_alarm1_day,
+        ALARM1_SECONDS,
+        [AM | 4, AM | 3, AM | 2, AM | 1],
         DayAlarm1 {
             day: 1,
             hour: Hours::H24(2),
             minute: 3,
             second: 4
         },
-        A1M::OncePerSecond,
-        ALARM1_SECONDS,
-        [AM | 4, AM | 3, AM | 2, AM | 1]
+        A1M::OncePerSecond
     );
 }
 
@@ -582,94 +747,132 @@ mod alarm1_weekday {
     set_alarm_test!(
         h24,
         set_alarm1_weekday,
+        ALARM1_SECONDS,
+        [4, 3, 2, BF::WEEKDAY | 1],
         WeekdayAlarm1 {
             weekday: 1,
             hour: Hours::H24(2),
             minute: 3,
             second: 4
         },
-        A1M::AllMatch,
-        ALARM1_SECONDS,
-        [4, 3, 2, BF::WEEKDAY | 1]
+        A1M::AllMatch
     );
     set_alarm_test!(
         am,
         set_alarm1_weekday,
+        ALARM1_SECONDS,
+        [4, 3, 0b0100_0010, BF::WEEKDAY | 1],
         WeekdayAlarm1 {
             weekday: 1,
             hour: Hours::AM(2),
             minute: 3,
             second: 4
         },
-        A1M::AllMatch,
-        ALARM1_SECONDS,
-        [4, 3, 0b0100_0010, BF::WEEKDAY | 1]
+        A1M::AllMatch
     );
     set_alarm_test!(
         pm,
         set_alarm1_weekday,
+        ALARM1_SECONDS,
+        [4, 3, 0b0110_0010, BF::WEEKDAY | 1],
         WeekdayAlarm1 {
             weekday: 1,
             hour: Hours::PM(2),
             minute: 3,
             second: 4
         },
-        A1M::AllMatch,
-        ALARM1_SECONDS,
-        [4, 3, 0b0110_0010, BF::WEEKDAY | 1]
+        A1M::AllMatch
+    );
+    set_alarm_test!(
+        match_hms_ignore_incorrect_wd,
+        set_alarm1_weekday,
+        ALARM1_SECONDS,
+        [4, 3, 2, AM | BF::WEEKDAY | 1],
+        WeekdayAlarm1 {
+            weekday: 0,
+            hour: Hours::H24(2),
+            minute: 3,
+            second: 4
+        },
+        A1M::HoursMinutesAndSecondsMatch
     );
-
     set_alarm_test!(
         match_hms,
         set_alarm1_weekday,
+        ALARM1_SECONDS,
+        [4, 3, 2, AM | BF::WEEKDAY | 1],
         WeekdayAlarm1 {
             weekday: 1,
             hour: Hours::H24(2),
             minute: 3,
             second: 4
         },
-        A1M::HoursMinutesAndSecondsMatch,
-        ALARM1_SECONDS,
-        [4, 3, 2, AM | BF::WEEKDAY | 1]
+        A1M::HoursMinutesAndSecondsMatch
     );
     set_alarm_test!(
         match_ms,
         set_alarm1_weekday,
+        ALARM1_SECONDS,
+        [4, 3, AM | 2, AM | BF::WEEKDAY | 1],
         WeekdayAlarm1 {
             weekday: 1,
             hour: Hours::H24(2),
             minute: 3,
             second: 4
         },
-        A1M::MinutesAndSecondsMatch,
-        ALARM1_SECONDS,
-        [4, 3, AM | 2, AM | BF::WEEKDAY | 1]
+        A1M::MinutesAndSecondsMatch
     );
     set_alarm_test!(
         match_s,
         set_alarm1_weekday,
+        ALARM1_SECONDS,
+        [4, AM | 3, AM | 2, AM | BF::WEEKDAY | 1],
         WeekdayAlarm1 {
             weekday: 1,
             hour: Hours::H24(2),
             minute: 3,
             second: 4
         },
-        A1M::SecondsMatch,
+        A1M::SecondsMatch
+    );
+    set_alarm_test!(
+        match_s_ignore_incorrect_min,
+        set_alarm1_weekday,
         ALARM1_SECONDS,
-        [4, AM | 3, AM | 2, AM | BF::WEEKDAY | 1]
+        [4, AM | 0, AM | 2, AM | BF::WEEKDAY | 1],
+        WeekdayAlarm1 {
+            weekday: 1,
+            hour: Hours::H24(2),
+            minute: 60,
+            second: 4
+        },
+        A1M::SecondsMatch
     );
     set_alarm_test!(
         match_ops,
         set_alarm1_weekday,
+        ALARM1_SECONDS,
+        [AM | 4, AM | 3, AM | 2, AM | BF::WEEKDAY | 1],
         WeekdayAlarm1 {
             weekday: 1,
             hour: Hours::H24(2),
             minute: 3,
             second: 4
         },
-        A1M::OncePerSecond,
+        A1M::OncePerSecond
+    );
+    set_alarm_test!(
+        match_ops_ignore_incorrect_sec,
+        set_alarm1_weekday,
         ALARM1_SECONDS,
-        [AM | 4, AM | 3, AM | 2, AM | BF::WEEKDAY | 1]
+        [AM | 0, AM | 3, AM | 2, AM | BF::WEEKDAY | 1],
+        WeekdayAlarm1 {
+            weekday: 1,
+            hour: Hours::H24(2),
+            minute: 3,
+            second: 60
+        },
+        A1M::OncePerSecond
     );
 }
 
@@ -678,75 +881,111 @@ mod alarm2_day {
     set_alarm_test!(
         h24,
         set_alarm2_day,
+        ALARM2_MINUTES,
+        [3, 2, 1],
         DayAlarm2 {
             day: 1,
             hour: Hours::H24(2),
             minute: 3
         },
-        A2M::AllMatch,
-        ALARM2_MINUTES,
-        [3, 2, 1]
+        A2M::AllMatch
     );
     set_alarm_test!(
         am,
         set_alarm2_day,
+        ALARM2_MINUTES,
+        [3, 0b0100_0010, 1],
         DayAlarm2 {
             day: 1,
             hour: Hours::AM(2),
             minute: 3
         },
-        A2M::AllMatch,
-        ALARM2_MINUTES,
-        [3, 0b0100_0010, 1]
+        A2M::AllMatch
     );
     set_alarm_test!(
         pm,
         set_alarm2_day,
+        ALARM2_MINUTES,
+        [3, 0b0110_0010, 1],
         DayAlarm2 {
             day: 1,
             hour: Hours::PM(2),
             minute: 3
         },
-        A2M::AllMatch,
-        ALARM2_MINUTES,
-        [3, 0b0110_0010, 1]
+        A2M::AllMatch
     );
 
     set_alarm_test!(
         match_hm,
         set_alarm2_day,
+        ALARM2_MINUTES,
+        [3, 2, AM | 1],
         DayAlarm2 {
             day: 1,
             hour: Hours::H24(2),
             minute: 3
         },
-        A2M::HoursAndMinutesMatch,
+        A2M::HoursAndMinutesMatch
+    );
+    set_alarm_test!(
+        match_hm_ignore_incorrect_day,
+        set_alarm2_day,
         ALARM2_MINUTES,
-        [3, 2, AM | 1]
+        [3, 2, AM | 1],
+        DayAlarm2 {
+            day: 0,
+            hour: Hours::H24(2),
+            minute: 3
+        },
+        A2M::HoursAndMinutesMatch
     );
     set_alarm_test!(
         match_m,
         set_alarm2_day,
+        ALARM2_MINUTES,
+        [3, AM | 2, AM | 1],
         DayAlarm2 {
             day: 1,
             hour: Hours::H24(2),
             minute: 3
         },
-        A2M::MinutesMatch,
+        A2M::MinutesMatch
+    );
+    set_alarm_test!(
+        match_m_ignore_invalid_h,
+        set_alarm2_day,
         ALARM2_MINUTES,
-        [3, AM | 2, AM | 1]
+        [3, AM | 0, AM | 1],
+        DayAlarm2 {
+            day: 1,
+            hour: Hours::H24(25),
+            minute: 3
+        },
+        A2M::MinutesMatch
     );
     set_alarm_test!(
         match_opm,
         set_alarm2_day,
+        ALARM2_MINUTES,
+        [AM | 3, AM | 2, AM | 1],
         DayAlarm2 {
             day: 1,
             hour: Hours::H24(2),
             minute: 3
         },
-        A2M::OncePerMinute,
+        A2M::OncePerMinute
+    );
+    set_alarm_test!(
+        match_opm_ignore_incorrect_min,
+        set_alarm2_day,
         ALARM2_MINUTES,
-        [AM | 3, AM | 2, AM | 1]
+        [AM | 0, AM | 2, AM | 1],
+        DayAlarm2 {
+            day: 1,
+            hour: Hours::H24(2),
+            minute: 60
+        },
+        A2M::OncePerMinute
     );
 }
 
@@ -755,74 +994,109 @@ mod alarm2_weekday {
     set_alarm_test!(
         h24,
         set_alarm2_weekday,
+        ALARM2_MINUTES,
+        [3, 2, BF::WEEKDAY | 1],
         WeekdayAlarm2 {
             weekday: 1,
             hour: Hours::H24(2),
             minute: 3
         },
-        A2M::AllMatch,
-        ALARM2_MINUTES,
-        [3, 2, BF::WEEKDAY | 1]
+        A2M::AllMatch
     );
     set_alarm_test!(
         am,
         set_alarm2_weekday,
+        ALARM2_MINUTES,
+        [3, 0b0100_0010, BF::WEEKDAY | 1],
         WeekdayAlarm2 {
             weekday: 1,
             hour: Hours::AM(2),
             minute: 3
         },
-        A2M::AllMatch,
-        ALARM2_MINUTES,
-        [3, 0b0100_0010, BF::WEEKDAY | 1]
+        A2M::AllMatch
     );
     set_alarm_test!(
         pm,
         set_alarm2_weekday,
+        ALARM2_MINUTES,
+        [3, 0b0110_0010, BF::WEEKDAY | 1],
         WeekdayAlarm2 {
             weekday: 1,
             hour: Hours::PM(2),
             minute: 3
         },
-        A2M::AllMatch,
-        ALARM2_MINUTES,
-        [3, 0b0110_0010, BF::WEEKDAY | 1]
+        A2M::AllMatch
     );
-
     set_alarm_test!(
         match_hm,
         set_alarm2_weekday,
+        ALARM2_MINUTES,
+        [3, 2, AM | BF::WEEKDAY | 1],
         WeekdayAlarm2 {
             weekday: 1,
             hour: Hours::H24(2),
             minute: 3
         },
-        A2M::HoursAndMinutesMatch,
+        A2M::HoursAndMinutesMatch
+    );
+    set_alarm_test!(
+        match_hm_ignore_incorrect_wd,
+        set_alarm2_weekday,
         ALARM2_MINUTES,
-        [3, 2, AM | BF::WEEKDAY | 1]
+        [3, 2, AM | BF::WEEKDAY | 1],
+        WeekdayAlarm2 {
+            weekday: 0,
+            hour: Hours::H24(2),
+            minute: 3
+        },
+        A2M::HoursAndMinutesMatch
     );
     set_alarm_test!(
         match_m,
         set_alarm2_weekday,
+        ALARM2_MINUTES,
+        [3, AM | 2, AM | BF::WEEKDAY | 1],
         WeekdayAlarm2 {
             weekday: 1,
             hour: Hours::H24(2),
             minute: 3
         },
-        A2M::MinutesMatch,
+        A2M::MinutesMatch
+    );
+    set_alarm_test!(
+        match_m_ignore_invalid_hour,
+        set_alarm2_weekday,
         ALARM2_MINUTES,
-        [3, AM | 2, AM | BF::WEEKDAY | 1]
+        [3, AM | 0, AM | BF::WEEKDAY | 1],
+        WeekdayAlarm2 {
+            weekday: 1,
+            hour: Hours::H24(24),
+            minute: 3
+        },
+        A2M::MinutesMatch
     );
     set_alarm_test!(
         match_opm,
         set_alarm2_weekday,
+        ALARM2_MINUTES,
+        [AM | 3, AM | 2, AM | BF::WEEKDAY | 1],
         WeekdayAlarm2 {
             weekday: 1,
             hour: Hours::H24(2),
             minute: 3
         },
-        A2M::OncePerMinute,
+        A2M::OncePerMinute
+    );
+    set_alarm_test!(
+        match_opm_ignore_incorrect_min,
+        set_alarm2_weekday,
         ALARM2_MINUTES,
-        [AM | 3, AM | 2, AM | BF::WEEKDAY | 1]
+        [AM | 0, AM | 2, AM | BF::WEEKDAY | 1],
+        WeekdayAlarm2 {
+            weekday: 1,
+            hour: Hours::H24(2),
+            minute: 60
+        },
+        A2M::OncePerMinute
     );
 }