Esempio n. 1
0
def test_current_time_matching_rule(today):
    # Last date in the past; matches rule
    date = today.replace(day=16, hour=8)
    expected = today.replace(day=23, hour=8)
    assert expected == get_date(True, RULE_FRIDAYS, date, tz=UTC)[1]

    # Last date in the future; matches rule
    date = today.replace(day=23, hour=18)
    expected = today.replace(day=30, hour=18)
    assert expected == get_date(True, RULE_FRIDAYS, date, tz=UTC)[1]
Esempio n. 2
0
def test_last_date_in_the_future_not_matching_rule(today):
    """Last date in the future; doesn't match rule."""
    # Corresponding time has already passed, today
    date = today.replace(day=24, hour=7)
    expected = today.replace(day=29, hour=7)
    assert expected == get_date(True, RULE_THURSDAYS, date, tz=UTC)[1]

    # Corresponding time has not passed today
    date = today.replace(day=24, hour=18)
    expected = today.replace(day=29, hour=18)
    assert expected == get_date(True, RULE_THURSDAYS, date, tz=UTC)[1]
Esempio n. 3
0
def test_current_time_matching_rule_no_given_date(now, scheduling):
    """
    No last date given means we should always get the current time.

    `now` matches the rule.
    """
    assert now == get_date(scheduling, RULE_THURSDAYS, tz=UTC)[1]
Esempio n. 4
0
def test_current_time_not_matching_rule(today):
    """`today` does not match rule."""
    # No last date
    expected = today.replace(day=23)
    assert expected == get_date(True, RULE_FRIDAYS, tz=UTC)[1]
    assert expected == get_date(True, RULE_FRIDAYS, tz=UTC)[1]

    # Last date in the past; doesn't match rule
    date = today.replace(hour=7)
    expected = today.replace(day=23, hour=7)
    assert expected == get_date(True, RULE_FRIDAYS, date, tz=UTC)[1]

    # Last date in the future; doesn't match rule
    date = today.replace(day=24, hour=7)
    expected = today.replace(day=30, hour=7)
    assert expected == get_date(True, RULE_FRIDAYS, date, tz=UTC)[1]
Esempio n. 5
0
def test_last_date_in_the_past_matching_rule(today):
    """Last date in the past; matches rule."""
    # Corresponding time has already passed, today
    date = today.replace(day=15, hour=7)
    expected = today.replace(day=29, hour=7)
    assert expected == get_date(True, RULE_THURSDAYS, date, tz=UTC)[1]

    # Corresponding time has already passed, today; rule specifies HOUR
    date = today.replace(day=15, hour=7)
    expected = today.replace(day=29, hour=9)
    assert expected == get_date(True,
                                RULE_THURSDAYS + ";BYHOUR=9",
                                date,
                                tz=UTC)[1]

    # Corresponding time has not passed today
    date = today.replace(day=15, hour=18)
    expected = today.replace(day=22, hour=18)
    assert expected == get_date(True, RULE_THURSDAYS, date, tz=UTC)[1]
Esempio n. 6
0
    def test_get_date(self):
        from nikola.plugins.command.new_post import get_date

        FMT = '%Y-%m-%d %H:%M:%S %Z'
        NOW = _NOW.strftime(FMT)
        TODAY = dateutil.parser.parse(NOW)
        RULE_TH = 'RRULE:FREQ=WEEKLY;BYDAY=TH'
        RULE_FR = 'RRULE:FREQ=WEEKLY;BYDAY=FR'
        UTC = dateutil.tz.tzutc()

        # NOW does not match rule #########################################
        # No last date
        expected = TODAY.replace(day=23)
        self.assertEqual(expected, get_date(True, RULE_FR, tz=UTC)[1])
        self.assertEqual(expected, get_date(True, RULE_FR, tz=UTC)[1])

        # Last date in the past; doesn't match rule
        date = TODAY.replace(hour=7)
        expected = TODAY.replace(day=23, hour=7)
        self.assertEqual(expected, get_date(True, RULE_FR, date, tz=UTC)[1])

        # Last date in the future; doesn't match rule
        date = TODAY.replace(day=24, hour=7)
        expected = TODAY.replace(day=30, hour=7)
        self.assertEqual(expected, get_date(True, RULE_FR, date, tz=UTC)[1])

        # Last date in the past; matches rule
        date = TODAY.replace(day=16, hour=8)
        expected = TODAY.replace(day=23, hour=8)
        self.assertEqual(expected, get_date(True, RULE_FR, date, tz=UTC)[1])

        # Last date in the future; matches rule
        date = TODAY.replace(day=23, hour=18)
        expected = TODAY.replace(day=30, hour=18)
        self.assertEqual(expected, get_date(True, RULE_FR, date, tz=UTC)[1])

        # NOW matches rule ################################################
        # Not scheduling should return NOW
        self.assertEqual(_NOW, get_date(False, RULE_TH, tz=UTC)[1])
        # No last date
        self.assertEqual(_NOW, get_date(True, RULE_TH, tz=UTC)[1])
        self.assertEqual(_NOW, get_date(True, RULE_TH, tz=UTC)[1])

        # Last date in the past; doesn't match rule
        # Corresponding time has already passed, today
        date = TODAY.replace(day=21, hour=7)
        expected = TODAY.replace(day=29, hour=7)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC)[1])
        # Corresponding time has not passed today
        date = TODAY.replace(day=21, hour=18)
        expected = TODAY.replace(day=22, hour=18)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC)[1])

        # Last date in the future; doesn't match rule
        # Corresponding time has already passed, today
        date = TODAY.replace(day=24, hour=7)
        expected = TODAY.replace(day=29, hour=7)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC)[1])
        # Corresponding time has not passed today
        date = TODAY.replace(day=24, hour=18)
        expected = TODAY.replace(day=29, hour=18)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC)[1])

        # Last date in the past; matches rule
        # Corresponding time has already passed, today
        date = TODAY.replace(day=15, hour=7)
        expected = TODAY.replace(day=29, hour=7)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC)[1])
        # Corresponding time has already passed, today; rule specifies HOUR
        date = TODAY.replace(day=15, hour=7)
        expected = TODAY.replace(day=29, hour=9)
        self.assertEqual(expected, get_date(
            True, RULE_TH + ';BYHOUR=9', date, tz=UTC)[1])
        # Corresponding time has not passed today
        date = TODAY.replace(day=15, hour=18)
        expected = TODAY.replace(day=22, hour=18)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC)[1])

        # Last date in the future; matches rule
        # Corresponding time has already passed, today
        date = TODAY.replace(day=29, hour=7)
        expected = TODAY.replace(day=5, month=9, hour=7)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC)[1])
        # Corresponding time has not passed today
        date = TODAY.replace(day=22, hour=18)
        expected = TODAY.replace(day=29, hour=18)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC)[1])
Esempio n. 7
0
    def test_get_date(self):
        from nikola.plugins.command.new_post import get_date

        #### NOW does not match rule #########################################
        ## No last date
        expected = TODAY.replace(day=23).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR))
        self.assertEqual(expected, get_date(True, RULE_FR, force_today=True))

        ## Last date in the past; doesn't match rule
        date = TODAY.replace(hour=7)
        expected = TODAY.replace(day=23, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date))
        self.assertEqual(expected, get_date(True, RULE_FR, date, True))

        ## Last date in the future; doesn't match rule
        date = TODAY.replace(day=24, hour=7)
        expected = TODAY.replace(day=30, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date))
        self.assertEqual(expected, get_date(True, RULE_FR, date, True))

        ## Last date in the past; matches rule
        date = TODAY.replace(day=16, hour=8)
        expected = TODAY.replace(day=23, hour=8).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date))
        self.assertEqual(expected, get_date(True, RULE_FR, date, True))

        ## Last date in the future; matches rule
        date = TODAY.replace(day=23, hour=18)
        expected = TODAY.replace(day=30, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date))
        self.assertEqual(expected, get_date(True, RULE_FR, date, True))

        #### NOW matches rule ################################################
        ## Not scheduling should return NOW
        self.assertEqual(NOW, get_date(False, RULE_TH))
        ## No last date
        self.assertEqual(NOW, get_date(True, RULE_TH))
        self.assertEqual(NOW, get_date(True, RULE_TH, force_today=True))

        ## Last date in the past; doesn't match rule
        ### Corresponding time has already passed, today
        date = TODAY.replace(day=21, hour=7)
        expected = TODAY.replace(day=29, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        expected = TODAY.replace(day=22, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, True))
        ### Corresponding time has not passed today
        date = TODAY.replace(day=21, hour=18)
        expected = TODAY.replace(day=22, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        self.assertEqual(expected, get_date(True, RULE_TH, date, True))

        ## Last date in the future; doesn't match rule
        ### Corresponding time has already passed, today
        date = TODAY.replace(day=24, hour=7)
        expected = TODAY.replace(day=29, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        self.assertEqual(expected, get_date(True, RULE_TH, date, True))
        ### Corresponding time has not passed today
        date = TODAY.replace(day=24, hour=18)
        expected = TODAY.replace(day=29, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        self.assertEqual(expected, get_date(True, RULE_TH, date, True))

        ## Last date in the past; matches rule
        ### Corresponding time has already passed, today
        date = TODAY.replace(day=15, hour=7)
        expected = TODAY.replace(day=29, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        expected = TODAY.replace(day=22, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, True))
        ### Corresponding time has already passed, today; rule specifies HOUR
        date = TODAY.replace(day=15, hour=7)
        expected = TODAY.replace(day=29, hour=9).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH + ';BYHOUR=9', date))
        expected = TODAY.replace(day=22, hour=9).strftime(FMT)
        self.assertEqual(expected,
                         get_date(True, RULE_TH + ';BYHOUR=9', date, True))
        ### Corresponding time has not passed today
        date = TODAY.replace(day=15, hour=18)
        expected = TODAY.replace(day=22, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        self.assertEqual(expected, get_date(True, RULE_TH, date, True))

        ## Last date in the future; matches rule
        ### Corresponding time has already passed, today
        date = TODAY.replace(day=29, hour=7)
        expected = TODAY.replace(day=5, month=9, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        ### Corresponding time has not passed today
        date = TODAY.replace(day=22, hour=18)
        expected = TODAY.replace(day=29, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        self.assertEqual(expected, get_date(True, RULE_TH, date, True))
Esempio n. 8
0
    def test_get_date(self):
        from nikola.plugins.command.new_post import get_date

        #### NOW does not match rule #########################################
        ## No last date
        expected = TODAY.replace(day=23).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR))
        self.assertEqual(expected, get_date(True, RULE_FR, force_today=True))

        ## Last date in the past; doesn't match rule
        date = TODAY.replace(hour=7)
        expected = TODAY.replace(day=23, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date))
        self.assertEqual(expected, get_date(True, RULE_FR, date, True))

        ## Last date in the future; doesn't match rule
        date = TODAY.replace(day=24, hour=7)
        expected = TODAY.replace(day=30, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date))
        self.assertEqual(expected, get_date(True, RULE_FR, date, True))

        ## Last date in the past; matches rule
        date = TODAY.replace(day=16, hour=8)
        expected = TODAY.replace(day=23, hour=8).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date))
        self.assertEqual(expected, get_date(True, RULE_FR, date, True))

        ## Last date in the future; matches rule
        date = TODAY.replace(day=23, hour=18)
        expected = TODAY.replace(day=30, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date))
        self.assertEqual(expected, get_date(True, RULE_FR, date, True))

        #### NOW matches rule ################################################
        ## Not scheduling should return NOW
        self.assertEqual(NOW, get_date(False, RULE_TH))
        ## No last date
        self.assertEqual(NOW, get_date(True, RULE_TH))
        self.assertEqual(NOW, get_date(True, RULE_TH, force_today=True))

        ## Last date in the past; doesn't match rule
        ### Corresponding time has already passed, today
        date = TODAY.replace(day=21, hour=7)
        expected = TODAY.replace(day=29, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        expected = TODAY.replace(day=22, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, True))
        ### Corresponding time has not passed today
        date = TODAY.replace(day=21, hour=18)
        expected = TODAY.replace(day=22, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        self.assertEqual(expected, get_date(True, RULE_TH, date, True))

        ## Last date in the future; doesn't match rule
        ### Corresponding time has already passed, today
        date = TODAY.replace(day=24, hour=7)
        expected = TODAY.replace(day=29, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        self.assertEqual(expected, get_date(True, RULE_TH, date, True))
        ### Corresponding time has not passed today
        date = TODAY.replace(day=24, hour=18)
        expected = TODAY.replace(day=29, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        self.assertEqual(expected, get_date(True, RULE_TH, date, True))

        ## Last date in the past; matches rule
        ### Corresponding time has already passed, today
        date = TODAY.replace(day=15, hour=7)
        expected = TODAY.replace(day=29, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        expected = TODAY.replace(day=22, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, True))
        ### Corresponding time has already passed, today; rule specifies HOUR
        date = TODAY.replace(day=15, hour=7)
        expected = TODAY.replace(day=29, hour=9).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH + ';BYHOUR=9', date))
        expected = TODAY.replace(day=22, hour=9).strftime(FMT)
        self.assertEqual(expected,
                         get_date(True, RULE_TH + ';BYHOUR=9', date, True))
        ### Corresponding time has not passed today
        date = TODAY.replace(day=15, hour=18)
        expected = TODAY.replace(day=22, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        self.assertEqual(expected, get_date(True, RULE_TH, date, True))

        ## Last date in the future; matches rule
        ### Corresponding time has already passed, today
        date = TODAY.replace(day=29, hour=7)
        expected = TODAY.replace(day=5, month=9, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        ### Corresponding time has not passed today
        date = TODAY.replace(day=22, hour=18)
        expected = TODAY.replace(day=29, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date))
        self.assertEqual(expected, get_date(True, RULE_TH, date, True))
Esempio n. 9
0
    def test_get_date(self):
        from nikola.plugins.command.new_post import get_date

        # This is now locale-dependent, so do it here, where
        # locale is set.
        FMT = '{0} {1} %Z'.format(
            locale.nl_langinfo(locale.D_FMT),
            locale.nl_langinfo(locale.T_FMT),
        )
        NOW = _NOW.strftime(FMT)
        TODAY = dateutil.parser.parse(NOW)
        RULE_TH = 'RRULE:FREQ=WEEKLY;BYDAY=TH'
        RULE_FR = 'RRULE:FREQ=WEEKLY;BYDAY=FR'
        UTC = dateutil.tz.tzutc()

        # NOW does not match rule #########################################
        # No last date
        expected = TODAY.replace(day=23).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, tz=UTC))
        self.assertEqual(expected, get_date(True, RULE_FR, tz=UTC))

        # Last date in the past; doesn't match rule
        date = TODAY.replace(hour=7)
        expected = TODAY.replace(day=23, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date, tz=UTC))

        # Last date in the future; doesn't match rule
        date = TODAY.replace(day=24, hour=7)
        expected = TODAY.replace(day=30, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date, tz=UTC))

        # Last date in the past; matches rule
        date = TODAY.replace(day=16, hour=8)
        expected = TODAY.replace(day=23, hour=8).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date, tz=UTC))

        # Last date in the future; matches rule
        date = TODAY.replace(day=23, hour=18)
        expected = TODAY.replace(day=30, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date, tz=UTC))

        # NOW matches rule ################################################
        # Not scheduling should return NOW
        self.assertEqual(NOW, get_date(False, RULE_TH, tz=UTC))
        # No last date
        self.assertEqual(NOW, get_date(True, RULE_TH, tz=UTC))
        self.assertEqual(NOW, get_date(True, RULE_TH, tz=UTC))

        # Last date in the past; doesn't match rule
        # Corresponding time has already passed, today
        date = TODAY.replace(day=21, hour=7)
        expected = TODAY.replace(day=29, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))
        # Corresponding time has not passed today
        date = TODAY.replace(day=21, hour=18)
        expected = TODAY.replace(day=22, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))

        # Last date in the future; doesn't match rule
        # Corresponding time has already passed, today
        date = TODAY.replace(day=24, hour=7)
        expected = TODAY.replace(day=29, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))
        # Corresponding time has not passed today
        date = TODAY.replace(day=24, hour=18)
        expected = TODAY.replace(day=29, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))

        # Last date in the past; matches rule
        # Corresponding time has already passed, today
        date = TODAY.replace(day=15, hour=7)
        expected = TODAY.replace(day=29, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))
        # Corresponding time has already passed, today; rule specifies HOUR
        date = TODAY.replace(day=15, hour=7)
        expected = TODAY.replace(day=29, hour=9).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH + ';BYHOUR=9', date, tz=UTC))
        # Corresponding time has not passed today
        date = TODAY.replace(day=15, hour=18)
        expected = TODAY.replace(day=22, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))

        # Last date in the future; matches rule
        # Corresponding time has already passed, today
        date = TODAY.replace(day=29, hour=7)
        expected = TODAY.replace(day=5, month=9, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))
        # Corresponding time has not passed today
        date = TODAY.replace(day=22, hour=18)
        expected = TODAY.replace(day=29, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))
Esempio n. 10
0
    def test_get_date(self):
        from nikola.plugins.command.new_post import get_date

        # This is now locale-dependent, so do it here, where
        # locale is set.
        FMT = '{0} {1} %Z'.format(
            locale.nl_langinfo(locale.D_FMT),
            locale.nl_langinfo(locale.T_FMT),
        )
        NOW = _NOW.strftime(FMT)
        TODAY = dateutil.parser.parse(NOW)
        RULE_TH = 'RRULE:FREQ=WEEKLY;BYDAY=TH'
        RULE_FR = 'RRULE:FREQ=WEEKLY;BYDAY=FR'
        UTC = dateutil.tz.tzutc()

        # NOW does not match rule #########################################
        # No last date
        expected = TODAY.replace(day=23).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, tz=UTC))
        self.assertEqual(expected, get_date(True, RULE_FR, tz=UTC))

        # Last date in the past; doesn't match rule
        date = TODAY.replace(hour=7)
        expected = TODAY.replace(day=23, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date, tz=UTC))

        # Last date in the future; doesn't match rule
        date = TODAY.replace(day=24, hour=7)
        expected = TODAY.replace(day=30, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date, tz=UTC))

        # Last date in the past; matches rule
        date = TODAY.replace(day=16, hour=8)
        expected = TODAY.replace(day=23, hour=8).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date, tz=UTC))

        # Last date in the future; matches rule
        date = TODAY.replace(day=23, hour=18)
        expected = TODAY.replace(day=30, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_FR, date, tz=UTC))

        # NOW matches rule ################################################
        # Not scheduling should return NOW
        self.assertEqual(NOW, get_date(False, RULE_TH, tz=UTC))
        # No last date
        self.assertEqual(NOW, get_date(True, RULE_TH, tz=UTC))
        self.assertEqual(NOW, get_date(True, RULE_TH, tz=UTC))

        # Last date in the past; doesn't match rule
        # Corresponding time has already passed, today
        date = TODAY.replace(day=21, hour=7)
        expected = TODAY.replace(day=29, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))
        # Corresponding time has not passed today
        date = TODAY.replace(day=21, hour=18)
        expected = TODAY.replace(day=22, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))

        # Last date in the future; doesn't match rule
        # Corresponding time has already passed, today
        date = TODAY.replace(day=24, hour=7)
        expected = TODAY.replace(day=29, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))
        # Corresponding time has not passed today
        date = TODAY.replace(day=24, hour=18)
        expected = TODAY.replace(day=29, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))

        # Last date in the past; matches rule
        # Corresponding time has already passed, today
        date = TODAY.replace(day=15, hour=7)
        expected = TODAY.replace(day=29, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))
        # Corresponding time has already passed, today; rule specifies HOUR
        date = TODAY.replace(day=15, hour=7)
        expected = TODAY.replace(day=29, hour=9).strftime(FMT)
        self.assertEqual(expected,
                         get_date(True, RULE_TH + ';BYHOUR=9', date, tz=UTC))
        # Corresponding time has not passed today
        date = TODAY.replace(day=15, hour=18)
        expected = TODAY.replace(day=22, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))

        # Last date in the future; matches rule
        # Corresponding time has already passed, today
        date = TODAY.replace(day=29, hour=7)
        expected = TODAY.replace(day=5, month=9, hour=7).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))
        # Corresponding time has not passed today
        date = TODAY.replace(day=22, hour=18)
        expected = TODAY.replace(day=29, hour=18).strftime(FMT)
        self.assertEqual(expected, get_date(True, RULE_TH, date, tz=UTC))