import pytz
from datetime import datetime


def float_to_datetime(timestamp, tzinfo=None):
    """
    Convert a timestamp to a datetime instance.
    If tzinfo is passed, interpret the timestamp in the given timezone.
    If tzinfo isn't passed, interpret the timestamp as UTC.

    For example, epoch starts at 1am CET (midnight UTC, as CET = UTC + 1h). So 1h from that time is
    2am CET.
    >> cet_tz = timezone('CET')
    >> float_to_datetime(3600, tzinfo=cet_tz)
    datetime.datetime(1970, 1, 1, 2, 0, tzinfo=<DstTzInfo 'CET' CET+1:00:00 STD>)

    Without timezone give, 3600s from the epoch start is just 1h into the epoch:
    >> float_to_datetime(3600)
    datetime.datetime(1970, 1, 1, 1, 0)

    See tests for more examples.

    Args:
        timestamp (float): e.g. 123456.123, seconds from the epoch, can include milliseconds
        tzinfo (timezone): optional timezone object

    Returns:
        datetime: if no timezone given - a timezone-naive datetime.
                  Otherwise - a datetime object in the given timezone.
    """
    _tz = tzinfo if tzinfo else pytz.UTC
    dt = datetime.fromtimestamp(timestamp, tz=_tz)

    if not tzinfo:
        dt = dt.replace(tzinfo=None)
    return dt