import time
from datetime import datetime


def format_date(timestamp, precision=0):
    """
    Construct an ISO 8601 time from a timestamp.

    There are several possible sources for *timestamp*.

    - time.time() returns a floating point number of seconds since the
      UNIX epoch of Jan 1, 1970 UTC.

    - time.localtime(time.time()) returns a time tuple for the current
      time using the local time representation.

    - datetime.datetime.now() returns a datetime object for the current
      time using the local time representation, but with no information
      about time zone.

    - iso8601.parse_date(str) returns a datetime object for a previously
      stored time stamp which retains time zone information.

    In the first three cases the formatted date will use the local time
    representation but include the UTC offset for the local time.  The
    fourth case the UTC offset of the time stamp will be preserved in
    formatting.

    If *precision* is given, encode fractional seconds with this many digits
    of precision. This only works if *timestamp* is datetime object or seconds
    since epoch.
    """
    dt = None
    microsecond = 0

    # Try converting from seconds to time_struct
    try:
        microsecond = int(1000000*(timestamp-int(timestamp)))
        timestamp = time.localtime(timestamp)
    except TypeError:
        # Not a floating point timestamp; could be datetime or time_struct
        pass

    # Try converting from datetime to time_struct
    if isinstance(timestamp, datetime):
        microsecond = timestamp.microsecond
        tz = timestamp.utcoffset()
        if tz is not None:
            dt = tz.days*86400 + tz.seconds
        timestamp = timestamp.timetuple()

    # Find time zone offset
    isdst = timestamp.tm_isdst if timestamp.tm_isdst >=0 else 0
    if dt is None:
        dt = -(time.timezone,time.altzone)[isdst]

    # Do the formatting
    local = time.strftime('%Y-%m-%dT%H:%M:%S',timestamp)
    sign = "+" if dt >= 0 else "-"
    offset = "%02d:%02d"%(abs(dt)//3600,(abs(dt)%3600)//60)
    fraction = ".%0*d"%(precision,microsecond//10**(6-precision)) if precision else ""
    return "".join((local,fraction,sign,offset))