예제 #1
0
def test_serialize_complex_schedule():
    dt = pendulum.datetime(2019, 1, 3)
    s = schedules.Schedule(
        # fire every hour
        clocks=[clocks.IntervalClock(timedelta(hours=1))],
        # only on weekdays
        filters=[filters.is_weekday],
        # only at 9am or 3pm
        or_filters=[
            filters.at_time(pendulum.time(9)),
            filters.between_times(pendulum.time(15), pendulum.time(15)),
        ],
        # not on january 8
        not_filters=[filters.between_dates(1, 8, 1, 8)],
        # add three hours
        adjustments=[adjustments.add(timedelta(hours=3))],
    )

    s2 = serialize_and_deserialize(s)

    assert s2.next(8, after=dt) == [
        dt.replace(hour=12),
        dt.replace(hour=18),
        dt.add(days=1).replace(hour=12),
        dt.add(days=1).replace(hour=18),
        # skip weekend
        dt.add(days=4).replace(hour=12),
        dt.add(days=4).replace(hour=18),
        # skip jan 8!
        dt.add(days=6).replace(hour=12),
        dt.add(days=6).replace(hour=18),
    ]
예제 #2
0
파일: models.py 프로젝트: morais90/pybill
class Bill(models.Model):
    STANDING_CHARGE = Decimal('0.36')
    CALL_CHARGE = Decimal('0.09')
    REDUCED_HOURS = (pendulum.time(22), pendulum.time(6))

    start_record = models.ForeignKey(CallRecord,
                                     related_name='start_record_bill',
                                     on_delete=models.CASCADE,
                                     help_text='The start record of the pair')
    end_record = models.ForeignKey(CallRecord,
                                   related_name='end_record_bill',
                                   on_delete=models.CASCADE,
                                   help_text='The end record of the pair')
    price = models.DecimalField(max_digits=10,
                                decimal_places=2,
                                help_text='The bill price')

    @property
    def start_date(self):
        return self.start_record.timestamp.date()

    @property
    def start_time(self):
        return self.start_record.timestamp.time()

    @property
    def duration(self):
        start_date = pendulum.instance(self.start_record.timestamp)
        end_date = pendulum.instance(self.end_record.timestamp)

        return (end_date - start_date)

    def _calculate_price(self):
        price = Decimal('0.0')
        start_date = pendulum.instance(self.start_record.timestamp)
        end_date = pendulum.instance(self.end_record.timestamp)
        period = pendulum.period(start_date, end_date)

        if period.total_minutes() >= 1:
            min_reduced_hour, max_reduced_hour = self.REDUCED_HOURS

            for date in period.range('minutes'):
                time = date.time()

                if time >= min_reduced_hour or time < max_reduced_hour:
                    continue

                if date == start_date:
                    # period.range is inclusive. We only compute complete cycles of
                    # minutes.
                    continue
                price += Decimal('0.09')
            price += self.STANDING_CHARGE

        return price.quantize(Decimal('0.01'))

    def save(self, *args, **kwargs):
        self.price = self._calculate_price()

        return super().save(*args, **kwargs)
예제 #3
0
def test_equal_to_true():
    t1 = pendulum.time(1, 2, 3)
    t2 = pendulum.time(1, 2, 3)
    t3 = time(1, 2, 3)

    assert t1 == t2
    assert t1 == t3
예제 #4
0
def test_create_schedule_multiple_filters():
    # jan 3 was a thursday
    dt = pendulum.datetime(2019, 1, 3)
    s = schedules.Schedule(
        # fire every hour
        clocks=[clocks.IntervalClock(timedelta(hours=1))],
        # only on weekdays
        filters=[filters.is_weekday],
        # only at 9am or 3pm
        or_filters=[
            filters.between_times(pendulum.time(9), pendulum.time(9)),
            filters.between_times(pendulum.time(15), pendulum.time(15)),
        ],
        # not on january 8
        not_filters=[filters.between_dates(1, 8, 1, 8)],
    )

    assert s.next(8, after=dt) == [
        dt.replace(hour=9),
        dt.replace(hour=15),
        dt.add(days=1).replace(hour=9),
        dt.add(days=1).replace(hour=15),
        # skip weekend
        dt.add(days=4).replace(hour=9),
        dt.add(days=4).replace(hour=15),
        # skip jan 8!
        dt.add(days=6).replace(hour=9),
        dt.add(days=6).replace(hour=15),
    ]
예제 #5
0
def test_less_than_or_equal_true():
    t1 = pendulum.time(1, 2, 2)
    t2 = pendulum.time(1, 2, 3)
    t3 = time(1, 2, 3)

    assert t1 <= t2
    assert t1 <= t3
예제 #6
0
def test_greater_than_or_equal_false():
    t1 = pendulum.time(1, 2, 2)
    t2 = pendulum.time(1, 2, 3)
    t3 = time(1, 2, 3)

    assert not t1 >= t2
    assert not t1 >= t3
예제 #7
0
def test_less_than_true():
    t1 = pendulum.time(1, 2, 2)
    t2 = pendulum.time(1, 2, 3)
    t3 = time(1, 2, 3)

    assert t1 < t2
    assert t1 < t3
예제 #8
0
def test_less_than_false():
    t1 = pendulum.time(1, 2, 3)
    t2 = pendulum.time(1, 2, 2)
    t3 = time(1, 2, 2)

    assert not t1 < t2
    assert not t1 < t3
예제 #9
0
def test_greater_than_or_equal_true_equal():
    t1 = pendulum.time(1, 2, 3)
    t2 = pendulum.time(1, 2, 3)
    t3 = time(1, 2, 3)

    assert t1 >= t2
    assert t1 >= t3
예제 #10
0
def test_greater_than_true():
    t1 = pendulum.time(1, 2, 3)
    t2 = pendulum.time(1, 2, 2)
    t3 = time(1, 2, 2)

    assert t1 > t2
    assert t1 > t3
예제 #11
0
def test_farthest_with_time():
    instance = pendulum.time(12, 34, 56)
    t1 = pendulum.time(12, 34, 54)
    t2 = pendulum.time(12, 34, 59)
    farthest = instance.farthest(t1, t2)

    assert_time(farthest, 12, 34, 59)
예제 #12
0
def test_greater_than_or_equal_false():
    t1 = pendulum.time(1, 2, 2)
    t2 = pendulum.time(1, 2, 3)
    t3 = time(1, 2, 3)

    assert not t1 >= t2
    assert not t1 >= t3
예제 #13
0
def test_greater_than_or_equal_true_equal():
    t1 = pendulum.time(1, 2, 3)
    t2 = pendulum.time(1, 2, 3)
    t3 = time(1, 2, 3)

    assert t1 >= t2
    assert t1 >= t3
예제 #14
0
def test_less_than_or_equal_true():
    t1 = pendulum.time(1, 2, 2)
    t2 = pendulum.time(1, 2, 3)
    t3 = time(1, 2, 3)

    assert t1 <= t2
    assert t1 <= t3
예제 #15
0
def test_equal_to_true():
    t1 = pendulum.time(1, 2, 3)
    t2 = pendulum.time(1, 2, 3)
    t3 = time(1, 2, 3)

    assert t1 == t2
    assert t1 == t3
예제 #16
0
def test_closest_with_time():
    instance = pendulum.time(12, 34, 56)
    t1 = pendulum.time(12, 34, 54)
    t2 = pendulum.time(12, 34, 59)
    closest = instance.closest(t1, t2)

    assert_time(closest, 12, 34, 54)
예제 #17
0
def test_less_than_false():
    t1 = pendulum.time(1, 2, 3)
    t2 = pendulum.time(1, 2, 2)
    t3 = time(1, 2, 2)

    assert not t1 < t2
    assert not t1 < t3
예제 #18
0
def test_equal_to_false():
    t1 = pendulum.time(1, 2, 3)
    t2 = pendulum.time(1, 2, 4)
    t3 = time(1, 2, 4)

    assert t1 != t2
    assert t1 != t3
예제 #19
0
def test_closest_with_time():
    instance = pendulum.time(12, 34, 56)
    t1 = pendulum.time(12, 34, 54)
    t2 = pendulum.time(12, 34, 59)
    closest = instance.closest(t1, t2)

    assert_time(closest, 12, 34, 54)
예제 #20
0
def test_greater_than_true():
    t1 = pendulum.time(1, 2, 3)
    t2 = pendulum.time(1, 2, 2)
    t3 = time(1, 2, 2)

    assert t1 > t2
    assert t1 > t3
예제 #21
0
def test_farthest_with_equals():
    instance = pendulum.time(12, 34, 56)
    t1 = pendulum.time(12, 34, 56)
    t2 = pendulum.time(12, 34, 59)

    farthest = instance.farthest(t1, t2)
    assert t2 == farthest
예제 #22
0
def test_less_than_true():
    t1 = pendulum.time(1, 2, 2)
    t2 = pendulum.time(1, 2, 3)
    t3 = time(1, 2, 3)

    assert t1 < t2
    assert t1 < t3
예제 #23
0
def test_farthest_with_equals():
    instance = pendulum.time(12, 34, 56)
    t1 = pendulum.time(12, 34, 56)
    t2 = pendulum.time(12, 34, 59)

    farthest = instance.farthest(t1, t2)
    assert t2 == farthest
예제 #24
0
def test_farthest_with_time():
    instance = pendulum.time(12, 34, 56)
    t1 = pendulum.time(12, 34, 54)
    t2 = pendulum.time(12, 34, 59)
    farthest = instance.farthest(t1, t2)

    assert_time(farthest, 12, 34, 59)
예제 #25
0
def test_equal_to_false():
    t1 = pendulum.time(1, 2, 3)
    t2 = pendulum.time(1, 2, 4)
    t3 = time(1, 2, 4)

    assert t1 != t2
    assert t1 != t3
예제 #26
0
def test_farthest():
    instance = pendulum.time(12, 34, 56)
    t1 = pendulum.time(12, 34, 54)
    t2 = pendulum.time(12, 34, 59)
    farthest = instance.farthest(t1, t2)
    assert t2 == farthest

    farthest = instance.farthest(t2, t1)
    assert t2 == farthest
예제 #27
0
def test_farthest():
    instance = pendulum.time(12, 34, 56)
    t1 = pendulum.time(12, 34, 54)
    t2 = pendulum.time(12, 34, 59)
    farthest = instance.farthest(t1, t2)
    assert t2 == farthest

    farthest = instance.farthest(t2, t1)
    assert t2 == farthest
예제 #28
0
def test_closest():
    instance = pendulum.time(12, 34, 56)
    t1 = pendulum.time(12, 34, 54)
    t2 = pendulum.time(12, 34, 59)
    closest = instance.closest(t1, t2)
    assert t1 == closest

    closest = instance.closest(t2, t1)
    assert t1 == closest
예제 #29
0
def test_init_with_missing_values():
    t = pendulum.time(12, 34, 56)
    assert_time(t, 12, 34, 56, 0)

    t = pendulum.time(12, 34)
    assert_time(t, 12, 34, 0, 0)

    t = pendulum.time(12)
    assert_time(t, 12, 0, 0, 0)
예제 #30
0
def test_closest():
    instance = pendulum.time(12, 34, 56)
    t1 = pendulum.time(12, 34, 54)
    t2 = pendulum.time(12, 34, 59)
    closest = instance.closest(t1, t2)
    assert t1 == closest

    closest = instance.closest(t2, t1)
    assert t1 == closest
예제 #31
0
def test_create_schedule_multiple_exclusive_filters():
    dt = pendulum.datetime(2019, 1, 1)
    s = schedules.Schedule(
        clocks=[clocks.IntervalClock(timedelta(hours=1))],
        filters=[
            filters.between_times(pendulum.time(9), pendulum.time(10)),
            filters.between_times(pendulum.time(15), pendulum.time(16)),
        ],
    )
    assert s.next(6, after=dt) == []
예제 #32
0
def test_create_schedule_filters():
    dt = pendulum.datetime(2019, 1, 1)
    s = schedules.Schedule(
        clocks=[clocks.IntervalClock(timedelta(hours=1))],
        filters=[filters.between_times(pendulum.time(9), pendulum.time(10))],
    )
    assert s.next(6, after=dt) == [
        dt.add(days=0).replace(hour=9),
        dt.add(days=0).replace(hour=10),
        dt.add(days=1).replace(hour=9),
        dt.add(days=1).replace(hour=10),
        dt.add(days=2).replace(hour=9),
        dt.add(days=2).replace(hour=10),
    ]
예제 #33
0
def test_add_timedelta():
    delta = timedelta(seconds=45, microseconds=123456)
    d = pendulum.time(3, 12, 15, 654321)

    d = d.add_timedelta(delta)
    assert d.minute == 13
    assert d.second == 0
    assert d.microsecond == 777777

    d = pendulum.time(3, 12, 15, 654321)

    d = d + delta
    assert d.minute == 13
    assert d.second == 0
    assert d.microsecond == 777777
예제 #34
0
def test_addition_invalid_type():
    d = pendulum.time(3, 12, 15, 654321)

    with pytest.raises(TypeError):
        d + 3

    with pytest.raises(TypeError):
        3 + d
예제 #35
0
def offset_from_now(time):
    x = pendulum.utcnow().time()
    if time > x:
        x = x.diff(time)
        hours = x.hours
        minutes = x.minutes
    else:
        x = pendulum.time(23, 59, 59) - time.diff(x)
        hours = x.hour
        minutes = x.minute
    if hours == 0:
        return "{0}m".format(minutes)
    else:
        return "{0}h{1:02d}m".format(hours, minutes)
예제 #36
0
def test_create_schedule_filters_2():
    dt = pendulum.datetime(2019, 1, 1)
    s = schedules.Schedule(
        clocks=[clocks.IntervalClock(timedelta(minutes=15))],
        filters=[filters.at_time(pendulum.time(2, 45))],
    )
    assert s.next(6, after=dt) == [
        dt.add(days=0, hours=2, minutes=45),
        dt.add(days=1, hours=2, minutes=45),
        dt.add(days=2, hours=2, minutes=45),
        dt.add(days=3, hours=2, minutes=45),
        dt.add(days=4, hours=2, minutes=45),
        dt.add(days=5, hours=2, minutes=45),
    ]
예제 #37
0
    def _set(self, value):
        # Force to appropriate Pendulum instance for consistency
        if value is not None:
            if self.input_type != self._type_interval:
                if self.input_type == self._type_date:
                    # Pendulum date
                    if isinstance(value, date):
                        value = pendulum.DateTime.combine(
                            value, pendulum.time(0))
                elif self.input_type == self._type_time:
                    # Pendulum time
                    if isinstance(value, time):
                        value = pendulum.DateTime.combine(
                            pendulum.today().date(), value)

                # Convert to Pendulum instance in UTC
                value = UTC.convert(pendulum.instance(value))
                # Drop nanosecond precision to match Mongo precision
                value = value.set(microsecond=int(
                    math.floor(value.microsecond / 1000) * 1000))

        return super(DatetimeField, self)._set(value)
예제 #38
0
    def _set(self, value):
        self.validate_value(value)

        # Force to appropriate Pendulum instance for consistency
        if value is not None:
            if self.input_type == self._type_interval:
                # Pendulum interval
                value = pendulum.interval.instance(value)
            else:
                if self.input_type == self._type_date:
                    # Pendulum date
                    if isinstance(value, date):
                        value = pendulum.combine(value, pendulum.time(0))
                elif self.input_type == self._type_time:
                    # Pendulum time
                    if isinstance(value, time):
                        value = pendulum.combine(pendulum.date.today(), value)

                # Convert to Pendulum instance in UTC
                value = UTC.convert(pendulum.instance(value))

        return super(DatetimeField, self)._set(value)
예제 #39
0
def test_add_minutes_positive():
    assert pendulum.time(12, 34, 56).add(minutes=1).minute == 35
예제 #40
0
def _parse(text, **options):
    """
    Parses a string with the given options.

    :param text: The string to parse.
    :type text: str

    :rtype: mixed
    """
    # Handling special cases
    if text == "now":
        return pendulum.now()

    parsed = base_parse(text, **options)

    if isinstance(parsed, datetime.datetime):
        return pendulum.datetime(
            parsed.year,
            parsed.month,
            parsed.day,
            parsed.hour,
            parsed.minute,
            parsed.second,
            parsed.microsecond,
            tz=parsed.tzinfo or options.get("tz", UTC),
        )

    if isinstance(parsed, datetime.date):
        return pendulum.date(parsed.year, parsed.month, parsed.day)

    if isinstance(parsed, datetime.time):
        return pendulum.time(
            parsed.hour, parsed.minute, parsed.second, parsed.microsecond
        )

    if isinstance(parsed, _Interval):
        if parsed.duration is not None:
            duration = parsed.duration

            if parsed.start is not None:
                dt = pendulum.instance(parsed.start, tz=options.get("tz", UTC))

                return pendulum.period(
                    dt,
                    dt.add(
                        years=duration.years,
                        months=duration.months,
                        weeks=duration.weeks,
                        days=duration.remaining_days,
                        hours=duration.hours,
                        minutes=duration.minutes,
                        seconds=duration.remaining_seconds,
                        microseconds=duration.microseconds,
                    ),
                )

            dt = pendulum.instance(parsed.end, tz=options.get("tz", UTC))

            return pendulum.period(
                dt.subtract(
                    years=duration.years,
                    months=duration.months,
                    weeks=duration.weeks,
                    days=duration.remaining_days,
                    hours=duration.hours,
                    minutes=duration.minutes,
                    seconds=duration.remaining_seconds,
                    microseconds=duration.microseconds,
                ),
                dt,
            )

        return pendulum.period(
            pendulum.instance(parsed.start, tz=options.get("tz", UTC)),
            pendulum.instance(parsed.end, tz=options.get("tz", UTC)),
        )

    if CDuration and isinstance(parsed, CDuration):
        return pendulum.duration(
            years=parsed.years,
            months=parsed.months,
            weeks=parsed.weeks,
            days=parsed.days,
            hours=parsed.hours,
            minutes=parsed.minutes,
            seconds=parsed.seconds,
            microseconds=parsed.microseconds,
        )

    return parsed
예제 #41
0
파일: parser.py 프로젝트: mazlum/pendulum
def _parse(text, **options):
    """
    Parses a string with the given options.

    :param text: The string to parse.
    :type text: str

    :rtype: mixed
    """
    # Handling special cases
    if text == "now":
        return pendulum.now()

    parsed = base_parse(text, **options)

    if isinstance(parsed, datetime.datetime):
        return pendulum.datetime(
            parsed.year,
            parsed.month,
            parsed.day,
            parsed.hour,
            parsed.minute,
            parsed.second,
            parsed.microsecond,
            tz=parsed.tzinfo or options.get("tz", UTC),
        )

    if isinstance(parsed, datetime.date):
        return pendulum.date(parsed.year, parsed.month, parsed.day)

    if isinstance(parsed, datetime.time):
        return pendulum.time(parsed.hour, parsed.minute, parsed.second,
                             parsed.microsecond)

    if isinstance(parsed, _Interval):
        if parsed.duration is not None:
            duration = parsed.duration

            if parsed.start is not None:
                dt = pendulum.instance(parsed.start, tz=options.get("tz", UTC))

                return pendulum.period(
                    dt,
                    dt.add(
                        years=duration.years,
                        months=duration.months,
                        weeks=duration.weeks,
                        days=duration.remaining_days,
                        hours=duration.hours,
                        minutes=duration.minutes,
                        seconds=duration.remaining_seconds,
                        microseconds=duration.microseconds,
                    ),
                )

            dt = pendulum.instance(parsed.end, tz=options.get("tz", UTC))

            return pendulum.period(
                dt.subtract(
                    years=duration.years,
                    months=duration.months,
                    weeks=duration.weeks,
                    days=duration.remaining_days,
                    hours=duration.hours,
                    minutes=duration.minutes,
                    seconds=duration.remaining_seconds,
                    microseconds=duration.microseconds,
                ),
                dt,
            )

        return pendulum.period(
            pendulum.instance(parsed.start, tz=options.get("tz", UTC)),
            pendulum.instance(parsed.end, tz=options.get("tz", UTC)),
        )

    if CDuration and isinstance(parsed, CDuration):
        return pendulum.duration(
            years=parsed.years,
            months=parsed.months,
            weeks=parsed.weeks,
            days=parsed.days,
            hours=parsed.hours,
            minutes=parsed.minutes,
            seconds=parsed.seconds,
            microseconds=parsed.microseconds,
        )

    return parsed
예제 #42
0
def test_closest_with_equals():
    instance = pendulum.time(12, 34, 56)
    t1 = pendulum.time(12, 34, 56)
    t2 = pendulum.time(12, 34, 59)
    closest = instance.closest(t1, t2)
    assert t1 == closest
예제 #43
0
def test_add_hours_zero():
    assert pendulum.time(12, 34, 56).add(hours=0).hour == 12
예제 #44
0
def test_not_equal_to_none():
    t1 = pendulum.time(1, 2, 3)

    assert t1 != None
예제 #45
0
def test_init():
    t = pendulum.time(12, 34, 56, 123456)

    assert_time(t, 12, 34, 56, 123456)
예제 #46
0
def test_add_hours_positive():
    assert pendulum.time(12, 34, 56).add(hours=1).hour == 13
예제 #47
0
def test_not_equal_to_none():
    t1 = pendulum.time(1, 2, 3)

    assert t1 != None  # noqa
예제 #48
0
def test_add_minutes_zero():
    assert pendulum.time(12, 34, 56).add(minutes=0).minute == 34
예제 #49
0
def test_add_minutes_negative():
    assert pendulum.time(12, 34, 56).add(minutes=-1).minute == 33
예제 #50
0
def test_add_seconds_positive():
    assert pendulum.time(12, 34, 56).add(seconds=1).second == 57
예제 #51
0
)

# Run empty_task_1 if cond1 executes between 2020-10-10 14:00:00 and 2020-10-10 15:00:00
cond1 >> [empty_task_11, empty_task_21]
# [END howto_branch_datetime_operator]

dag2 = DAG(
    dag_id="example_branch_datetime_operator_2",
    start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
    catchup=False,
    tags=["example"],
    schedule="@daily",
)
# [START howto_branch_datetime_operator_next_day]
empty_task_12 = EmptyOperator(task_id='date_in_range', dag=dag2)
empty_task_22 = EmptyOperator(task_id='date_outside_range', dag=dag2)

cond2 = BranchDateTimeOperator(
    task_id='datetime_branch',
    follow_task_ids_if_true=['date_in_range'],
    follow_task_ids_if_false=['date_outside_range'],
    target_upper=pendulum.time(0, 0, 0),
    target_lower=pendulum.time(15, 0, 0),
    dag=dag2,
)

# Since target_lower happens after target_upper, target_upper will be moved to the following day
# Run empty_task_1 if cond2 executes between 15:00:00, and 00:00:00 of the following day
cond2 >> [empty_task_12, empty_task_22]
# [END howto_branch_datetime_operator_next_day]
예제 #52
0
def test_add_timedelta_with_days():
    delta = timedelta(days=3, seconds=45, microseconds=123456)
    d = pendulum.time(3, 12, 15, 654321)

    with pytest.raises(TypeError):
        d.add_timedelta(delta)
예제 #53
0
def test_closest_with_equals():
    instance = pendulum.time(12, 34, 56)
    t1 = pendulum.time(12, 34, 56)
    t2 = pendulum.time(12, 34, 59)
    closest = instance.closest(t1, t2)
    assert t1 == closest
예제 #54
0
def test_add_hours_negative():
    assert pendulum.time(12, 34, 56).add(hours=-1).hour == 11
예제 #55
0
def test_at_time(test_times):
    test_dt, result = test_times
    filter_fn = filters.at_time(pendulum.time(3, 30))
    assert filter_fn(test_dt) is result
예제 #56
0
def test_add_seconds_zero():
    assert pendulum.time(12, 34, 56).add(seconds=0).second == 56
예제 #57
0
def test_add_seconds_negative():
    assert pendulum.time(12, 34, 56).add(seconds=-1).second == 55