AttoTimeBuilder
================
aniso8601 builder for attodatetimes
-----------------------------------
Features
========
* Provides :code:`AttoTimeBuilder` compatible with `aniso8601 <https://bitbucket.org/nielsenb/aniso8601>`_
* Returns :code:`attodatetime` and :code:`attotimedelta` `types <https://bitbucket.org/nielsenb/attotime>`_
Installation
============
The recommended installation method is to use pip::
$ pip install attotimebuilder
Alternatively, you can download the source (git repository hosted at `Bitbucket <https://bitbucket.org/nielsenb/attotimebuilder>`_) and install directly::
$ python setup.py install
Use
===
Parsing datetimes
-----------------
To parse a typical ISO 8601 datetime string::
>>> import aniso8601
>>> from attotimebuilder import AttoTimeBuilder
>>> aniso8601.parse_datetime('1977-06-10T12:00:00', builder=AttoTimeBuilder)
attotime.attodatetime(1977, 6, 10, 12, 0, 0, 0, 0)
Alternative delimiters can be specified, for example, a space::
>>> aniso8601.parse_datetime('1977-06-10 12:00:00', delimiter=' ', builder=AttoTimeBuilder)
attotime.attodatetime(1977, 6, 10, 12, 0, 0, 0, 0)
Both UTC (Z) and UTC offsets for timezones are supported::
>>> aniso8601.parse_datetime('1977-06-10T12:00:00Z', builder=AttoTimeBuilder)
attotime.attodatetime(1977, 6, 10, 12, 0, 0, 0, 0, +0:00:00 UTC)
>>> aniso8601.parse_datetime('1979-06-05T08:00:00-08:00', builder=AttoTimeBuilder)
attotime.attodatetime(1979, 6, 5, 8, 0, 0, 0, 0, -8:00:00 UTC)
Leap seconds are explicitly not supported::
>>> aniso8601.parse_datetime('2018-03-06T23:59:60', builder=AttoTimeBuilder)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/nielsenb/Jetfuse/attotimebuilder/python2/lib/python2.7/site-packages/aniso8601/time.py", line 131, in parse_datetime
return builder.build_datetime(datepart, timepart)
File "attotimebuilder/__init__.py", line 120, in build_datetime
cls._build_object(time))
File "/home/nielsenb/Jetfuse/attotimebuilder/python2/lib/python2.7/site-packages/aniso8601/builder.py", line 71, in _build_object
ss=parsetuple[2], tz=parsetuple[3])
File "attotimebuilder/__init__.py", line 73, in build_time
raise LeapSecondError('Leap seconds are not supported.')
aniso8601.exceptions.LeapSecondError: Leap seconds are not supported.
Parsing dates
-------------
There is no :code:`attodate` type, so native Python :code:`datetime.date` objects are returned.
To parse a date represented in an ISO 8601 string::
>>> import aniso8601
>>> from attotimebuilder import AttoTimeBuilder
>>> aniso8601.parse_date('1984-04-23', builder=AttoTimeBuilder)
datetime.date(1984, 4, 23)
Basic format is supported as well::
>>> aniso8601.parse_date('19840423', builder=AttoTimeBuilder)
datetime.date(1984, 4, 23)
To parse a date using the ISO 8601 week date format::
>>> aniso8601.parse_date('1986-W38-1', builder=AttoTimeBuilder)
datetime.date(1986, 9, 15)
To parse an ISO 8601 ordinal date::
>>> aniso8601.parse_date('1988-132', builder=AttoTimeBuilder)
datetime.date(1988, 5, 11)
Parsing times
-------------
To parse a time formatted as an ISO 8601 string::
>>> import aniso8601
>>> from attotimebuilder import AttoTimeBuilder
>>> aniso8601.parse_time('11:31:14', builder=AttoTimeBuilder)
attotime.attotime(11, 31, 14, 0, 0)
As with all of the above, basic format is supported::
>>> aniso8601.parse_time('113114', builder=AttoTimeBuilder)
attotime.attotime(11, 31, 14, 0, 0)
A UTC offset can be specified for times::
>>> aniso8601.parse_time('17:18:19-02:30', builder=AttoTimeBuilder)
attotime.attotime(17, 18, 19, 0, 0, -2:30:00 UTC)
>>> aniso8601.parse_time('171819Z', builder=AttoTimeBuilder)
attotime.attotime(17, 18, 19, 0, 0, +0:00:00 UTC)
Reduced accuracy is supported::
>>> aniso8601.parse_time('21:42', builder=AttoTimeBuilder)
attotime.attotime(21, 42, 0, 0, 0)
>>> aniso8601.parse_time('22', builder=AttoTimeBuilder)
attotime.attotime(22, 0, 0, 0, 0)
A decimal fraction is always allowed on the lowest order element of an ISO 8601 formatted time::
>>> aniso8601.parse_time('22:33.5', builder=AttoTimeBuilder)
attotime.attotime(22, 33, 30, 0, 0.0)
>>> aniso8601.parse_time('23.75', builder=AttoTimeBuilder)
attotime.attotime(23, 45, 0, 0, 0.00)
Leap seconds are explicitly not supported and attempting to parse one raises a :code:`LeapSecondError`::
>>> aniso8601.parse_time('23:59:60', builder=AttoTimeBuilder)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/nielsenb/Jetfuse/attotimebuilder/python2/lib/python2.7/site-packages/aniso8601/time.py", line 116, in parse_time
return _RESOLUTION_MAP[get_time_resolution(timestr)](timestr, tz, builder)
File "/home/nielsenb/Jetfuse/attotimebuilder/python2/lib/python2.7/site-packages/aniso8601/time.py", line 165, in _parse_second_time
return builder.build_time(hh=hourstr, mm=minutestr, ss=secondstr, tz=tz)
File "attotimebuilder/__init__.py", line 73, in build_time
raise LeapSecondError('Leap seconds are not supported.')
aniso8601.exceptions.LeapSecondError: Leap seconds are not supported.
Parsing durations
-----------------
To parse a duration formatted as an ISO 8601 string::
>>> import aniso8601
>>> from attotimebuilder import AttoTimeBuilder
>>> aniso8601.parse_duration('P1Y2M3DT4H54M6S', builder=AttoTimeBuilder)
attotime.attotimedelta(428, 17646)
Reduced accuracy is supported::
>>> aniso8601.parse_duration('P1Y', builder=AttoTimeBuilder)
attotime.attotimedelta(365)
A decimal fraction is allowed on the lowest order element::
>>> aniso8601.parse_duration('P1YT3.5M', builder=AttoTimeBuilder)
attotime.attotimedelta(365, 210)
The decimal fraction can be specified with a comma instead of a full-stop::
>>> aniso8601.parse_duration('P1YT3,5M', builder=AttoTimeBuilder)
attotime.attotimedelta(365, 210)
Parsing a duration from a combined date and time is supported as well::
>>> aniso8601.parse_duration('P0001-01-02T01:30:5', builder=AttoTimeBuilder)
attotime.attotimedelta(397, 5405)
Parsing intervals
-----------------
To parse an interval specified by a start and end::
>>> import aniso8601
>>> from attotimebuilder import AttoTimeBuilder
>>> aniso8601.parse_interval('2007-03-01T13:00:00/2008-05-11T15:30:00', builder=AttoTimeBuilder)
(attotime.attodatetime(2007, 3, 1, 13, 0, 0, 0, 0), attotime.attodatetime(2008, 5, 11, 15, 30, 0, 0, 0))
Intervals specified by a start time and a duration are supported::
>>> aniso8601.parse_interval('2007-03-01T13:00:00/P1Y2M10DT2H30M', builder=AttoTimeBuilder)
(attotime.attodatetime(2007, 3, 1, 13, 0, 0, 0, 0), attotime.attodatetime(2008, 5, 9, 15, 30, 0, 0, 0))
A duration can also be specified by a duration and end time, note that no :code:`attodate` type exists, so dates are returned as native :code:`datetime.date` objects::
>>> aniso8601.parse_interval('P1M/1981-04-05', builder=AttoTimeBuilder)
(datetime.date(1981, 4, 5), datetime.date(1981, 3, 6))
Notice that the result of the above parse is not in order from earliest to latest. If sorted intervals are required, simply use the :code:`sorted` keyword as shown below::
>>> sorted(aniso8601.parse_interval('P1M/1981-04-05', builder=AttoTimeBuilder))
[datetime.date(1981, 3, 6), datetime.date(1981, 4, 5)]
The end of an interval is returned as a :code:`attodatetime` when required to maintain the resolution specified by a duration, even if the duration start is given as a date::
>>> aniso8601.parse_interval('2014-11-12/PT4H54M6.5S', builder=AttoTimeBuilder)
(datetime.date(2014, 11, 12), attotime.attodatetime(2014, 11, 12, 4, 54, 6, 500000, 0.0))
>>> aniso8601.parse_interval('2007-03-01/P1.5D', builder=AttoTimeBuilder)
(datetime.date(2007, 3, 1), attotime.objects.attodatetime(2007, 3, 2, 12, 0, 0, 0, 0.0))
Repeating intervals are supported as well, and return a generator::
>>> aniso8601.parse_repeating_interval('R3/1981-04-05/P1D', builder=AttoTimeBuilder)
<generator object _date_generator at 0x7fba29feed20>
>>> list(aniso8601.parse_repeating_interval('R3/1981-04-05/P1D', builder=AttoTimeBuilder))
[datetime.date(1981, 4, 5), datetime.date(1981, 4, 6), datetime.date(1981, 4, 7)]
Repeating intervals are allowed to go in the reverse direction::
>>> list(aniso8601.parse_repeating_interval('R2/PT1H2M/1980-03-05T01:01:00', builder=AttoTimeBuilder))
[attotime.attodatetime(1980, 3, 5, 1, 1, 0, 0, 0), attotime.attodatetime(1980, 3, 4, 23, 59, 0, 0, 0)]
Unbounded intervals are also allowed (Python 2)::
>>> result = aniso8601.parse_repeating_interval('R/PT1H2M/1980-03-05T01:01:00', builder=AttoTimeBuilder)
>>> result.next()
attotime.attodatetime(1980, 3, 5, 1, 1, 0, 0, 0)
>>> result.next()
attotime.attodatetime(1980, 3, 4, 23, 59, 0, 0, 0)
or for Python 3::
>>> result = aniso8601.parse_repeating_interval('R/PT1H2M/1980-03-05T01:01:00', builder=AttoTimeBuilder)
>>> next(result)
attotime.attodatetime(1980, 3, 5, 1, 1, 0, 0, 0)
>>> next(result)
attotime.attodatetime(1980, 3, 4, 23, 59, 0, 0, 0)
The above treat years as 365 days and months as 30 days. Fractional months and years are supported accordingly::
>>> aniso8601.parse_interval('P1.1Y/2001-02-28', builder=AttoTimeBuilder)
(datetime.date(2001, 2, 28), datetime.date(2000, 1, 23))
>>> aniso8601.parse_interval('2001-02-28/P1Y2.5M', builder=AttoTimeBuilder)
(datetime.date(2001, 2, 28), datetime.date(2002, 5, 14))
Development
===========
Setup
-----
It is recommended to develop using a `virtualenv <https://virtualenv.pypa.io/en/stable/>`_.
Inside a virtualenv, development dependencies can be installed automatically::
$ pip install -e .[dev]
`pre-commit <https://pre-commit.com/>`_ is used for managing pre-commit hooks::
$ pre-commit install
To run the pre-commit hooks manually::
$ pre-commit run --all-files
Tests
-----
Tests can be run using the `unittest testing framework <https://docs.python.org/3/library/unittest.html>`_::
$ python -m unittest discover attotimebuilder
Contributing
============
attotimebuilder is an open source project hosted on `Bitbucket <https://bitbucket.org/nielsenb/attotimebuilder>`_.
Any and all bugs are welcome on our `issue tracker <https://bitbucket.org/nielsenb/attotimebuilder/issues>`_.
References
==========
* `aniso8601 and sub-microsecond precision <https://bitbucket.org/nielsenb/aniso8601/issues/10/sub-microsecond-precision-in-durations-is>`_
Raw data
{
"_id": null,
"home_page": "https://bitbucket.org/nielsenb/attotimebuilder",
"name": "attotimebuilder",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "iso8601 attotime aniso8601 datetime",
"author": "Brandon Nielsen",
"author_email": "nielsenb@jetfuse.net",
"download_url": "https://files.pythonhosted.org/packages/2d/b4/8c99d457638bd1f81f1072b0fd8fd1d47251e25b19befd300c3f69ef01af/attotimebuilder-0.4.1.tar.gz",
"platform": null,
"description": "AttoTimeBuilder\n================\n\naniso8601 builder for attodatetimes\n-----------------------------------\n\nFeatures\n========\n* Provides :code:`AttoTimeBuilder` compatible with `aniso8601 <https://bitbucket.org/nielsenb/aniso8601>`_\n* Returns :code:`attodatetime` and :code:`attotimedelta` `types <https://bitbucket.org/nielsenb/attotime>`_\n\nInstallation\n============\n\nThe recommended installation method is to use pip::\n\n $ pip install attotimebuilder\n\nAlternatively, you can download the source (git repository hosted at `Bitbucket <https://bitbucket.org/nielsenb/attotimebuilder>`_) and install directly::\n\n $ python setup.py install\n\nUse\n===\n\nParsing datetimes\n-----------------\n\nTo parse a typical ISO 8601 datetime string::\n\n >>> import aniso8601\n >>> from attotimebuilder import AttoTimeBuilder\n >>> aniso8601.parse_datetime('1977-06-10T12:00:00', builder=AttoTimeBuilder)\n attotime.attodatetime(1977, 6, 10, 12, 0, 0, 0, 0)\n\nAlternative delimiters can be specified, for example, a space::\n\n >>> aniso8601.parse_datetime('1977-06-10 12:00:00', delimiter=' ', builder=AttoTimeBuilder)\n attotime.attodatetime(1977, 6, 10, 12, 0, 0, 0, 0)\n\nBoth UTC (Z) and UTC offsets for timezones are supported::\n\n >>> aniso8601.parse_datetime('1977-06-10T12:00:00Z', builder=AttoTimeBuilder)\n attotime.attodatetime(1977, 6, 10, 12, 0, 0, 0, 0, +0:00:00 UTC)\n >>> aniso8601.parse_datetime('1979-06-05T08:00:00-08:00', builder=AttoTimeBuilder)\n attotime.attodatetime(1979, 6, 5, 8, 0, 0, 0, 0, -8:00:00 UTC)\n\nLeap seconds are explicitly not supported::\n\n >>> aniso8601.parse_datetime('2018-03-06T23:59:60', builder=AttoTimeBuilder)\n Traceback (most recent call last):\n File \"<stdin>\", line 1, in <module>\n File \"/home/nielsenb/Jetfuse/attotimebuilder/python2/lib/python2.7/site-packages/aniso8601/time.py\", line 131, in parse_datetime\n return builder.build_datetime(datepart, timepart)\n File \"attotimebuilder/__init__.py\", line 120, in build_datetime\n cls._build_object(time))\n File \"/home/nielsenb/Jetfuse/attotimebuilder/python2/lib/python2.7/site-packages/aniso8601/builder.py\", line 71, in _build_object\n ss=parsetuple[2], tz=parsetuple[3])\n File \"attotimebuilder/__init__.py\", line 73, in build_time\n raise LeapSecondError('Leap seconds are not supported.')\n aniso8601.exceptions.LeapSecondError: Leap seconds are not supported.\n\nParsing dates\n-------------\n\nThere is no :code:`attodate` type, so native Python :code:`datetime.date` objects are returned.\n\nTo parse a date represented in an ISO 8601 string::\n\n >>> import aniso8601\n >>> from attotimebuilder import AttoTimeBuilder\n >>> aniso8601.parse_date('1984-04-23', builder=AttoTimeBuilder)\n datetime.date(1984, 4, 23)\n\nBasic format is supported as well::\n\n >>> aniso8601.parse_date('19840423', builder=AttoTimeBuilder)\n datetime.date(1984, 4, 23)\n\nTo parse a date using the ISO 8601 week date format::\n\n >>> aniso8601.parse_date('1986-W38-1', builder=AttoTimeBuilder)\n datetime.date(1986, 9, 15)\n\nTo parse an ISO 8601 ordinal date::\n\n >>> aniso8601.parse_date('1988-132', builder=AttoTimeBuilder)\n datetime.date(1988, 5, 11)\n\nParsing times\n-------------\n\nTo parse a time formatted as an ISO 8601 string::\n\n >>> import aniso8601\n >>> from attotimebuilder import AttoTimeBuilder\n >>> aniso8601.parse_time('11:31:14', builder=AttoTimeBuilder)\n attotime.attotime(11, 31, 14, 0, 0)\n\nAs with all of the above, basic format is supported::\n\n >>> aniso8601.parse_time('113114', builder=AttoTimeBuilder)\n attotime.attotime(11, 31, 14, 0, 0)\n\nA UTC offset can be specified for times::\n\n >>> aniso8601.parse_time('17:18:19-02:30', builder=AttoTimeBuilder)\n attotime.attotime(17, 18, 19, 0, 0, -2:30:00 UTC)\n >>> aniso8601.parse_time('171819Z', builder=AttoTimeBuilder)\n attotime.attotime(17, 18, 19, 0, 0, +0:00:00 UTC)\n\nReduced accuracy is supported::\n\n >>> aniso8601.parse_time('21:42', builder=AttoTimeBuilder)\n attotime.attotime(21, 42, 0, 0, 0)\n >>> aniso8601.parse_time('22', builder=AttoTimeBuilder)\n attotime.attotime(22, 0, 0, 0, 0)\n\nA decimal fraction is always allowed on the lowest order element of an ISO 8601 formatted time::\n\n >>> aniso8601.parse_time('22:33.5', builder=AttoTimeBuilder)\n attotime.attotime(22, 33, 30, 0, 0.0)\n >>> aniso8601.parse_time('23.75', builder=AttoTimeBuilder)\n attotime.attotime(23, 45, 0, 0, 0.00)\n\nLeap seconds are explicitly not supported and attempting to parse one raises a :code:`LeapSecondError`::\n\n >>> aniso8601.parse_time('23:59:60', builder=AttoTimeBuilder)\n Traceback (most recent call last):\n File \"<stdin>\", line 1, in <module>\n File \"/home/nielsenb/Jetfuse/attotimebuilder/python2/lib/python2.7/site-packages/aniso8601/time.py\", line 116, in parse_time\n return _RESOLUTION_MAP[get_time_resolution(timestr)](timestr, tz, builder)\n File \"/home/nielsenb/Jetfuse/attotimebuilder/python2/lib/python2.7/site-packages/aniso8601/time.py\", line 165, in _parse_second_time\n return builder.build_time(hh=hourstr, mm=minutestr, ss=secondstr, tz=tz)\n File \"attotimebuilder/__init__.py\", line 73, in build_time\n raise LeapSecondError('Leap seconds are not supported.')\n aniso8601.exceptions.LeapSecondError: Leap seconds are not supported.\n\nParsing durations\n-----------------\n\nTo parse a duration formatted as an ISO 8601 string::\n\n >>> import aniso8601\n >>> from attotimebuilder import AttoTimeBuilder\n >>> aniso8601.parse_duration('P1Y2M3DT4H54M6S', builder=AttoTimeBuilder)\n attotime.attotimedelta(428, 17646)\n\nReduced accuracy is supported::\n\n >>> aniso8601.parse_duration('P1Y', builder=AttoTimeBuilder)\n attotime.attotimedelta(365)\n\nA decimal fraction is allowed on the lowest order element::\n\n >>> aniso8601.parse_duration('P1YT3.5M', builder=AttoTimeBuilder)\n attotime.attotimedelta(365, 210)\n\nThe decimal fraction can be specified with a comma instead of a full-stop::\n\n >>> aniso8601.parse_duration('P1YT3,5M', builder=AttoTimeBuilder)\n attotime.attotimedelta(365, 210)\n\nParsing a duration from a combined date and time is supported as well::\n\n >>> aniso8601.parse_duration('P0001-01-02T01:30:5', builder=AttoTimeBuilder)\n attotime.attotimedelta(397, 5405)\n\nParsing intervals\n-----------------\n\nTo parse an interval specified by a start and end::\n\n >>> import aniso8601\n >>> from attotimebuilder import AttoTimeBuilder\n >>> aniso8601.parse_interval('2007-03-01T13:00:00/2008-05-11T15:30:00', builder=AttoTimeBuilder)\n (attotime.attodatetime(2007, 3, 1, 13, 0, 0, 0, 0), attotime.attodatetime(2008, 5, 11, 15, 30, 0, 0, 0))\n\nIntervals specified by a start time and a duration are supported::\n\n >>> aniso8601.parse_interval('2007-03-01T13:00:00/P1Y2M10DT2H30M', builder=AttoTimeBuilder)\n (attotime.attodatetime(2007, 3, 1, 13, 0, 0, 0, 0), attotime.attodatetime(2008, 5, 9, 15, 30, 0, 0, 0))\n\nA duration can also be specified by a duration and end time, note that no :code:`attodate` type exists, so dates are returned as native :code:`datetime.date` objects::\n\n >>> aniso8601.parse_interval('P1M/1981-04-05', builder=AttoTimeBuilder)\n (datetime.date(1981, 4, 5), datetime.date(1981, 3, 6))\n\nNotice that the result of the above parse is not in order from earliest to latest. If sorted intervals are required, simply use the :code:`sorted` keyword as shown below::\n\n >>> sorted(aniso8601.parse_interval('P1M/1981-04-05', builder=AttoTimeBuilder))\n [datetime.date(1981, 3, 6), datetime.date(1981, 4, 5)]\n\nThe end of an interval is returned as a :code:`attodatetime` when required to maintain the resolution specified by a duration, even if the duration start is given as a date::\n\n >>> aniso8601.parse_interval('2014-11-12/PT4H54M6.5S', builder=AttoTimeBuilder)\n (datetime.date(2014, 11, 12), attotime.attodatetime(2014, 11, 12, 4, 54, 6, 500000, 0.0))\n >>> aniso8601.parse_interval('2007-03-01/P1.5D', builder=AttoTimeBuilder)\n (datetime.date(2007, 3, 1), attotime.objects.attodatetime(2007, 3, 2, 12, 0, 0, 0, 0.0))\n\nRepeating intervals are supported as well, and return a generator::\n\n >>> aniso8601.parse_repeating_interval('R3/1981-04-05/P1D', builder=AttoTimeBuilder)\n <generator object _date_generator at 0x7fba29feed20>\n >>> list(aniso8601.parse_repeating_interval('R3/1981-04-05/P1D', builder=AttoTimeBuilder))\n [datetime.date(1981, 4, 5), datetime.date(1981, 4, 6), datetime.date(1981, 4, 7)]\n\nRepeating intervals are allowed to go in the reverse direction::\n\n >>> list(aniso8601.parse_repeating_interval('R2/PT1H2M/1980-03-05T01:01:00', builder=AttoTimeBuilder))\n [attotime.attodatetime(1980, 3, 5, 1, 1, 0, 0, 0), attotime.attodatetime(1980, 3, 4, 23, 59, 0, 0, 0)]\n\nUnbounded intervals are also allowed (Python 2)::\n\n >>> result = aniso8601.parse_repeating_interval('R/PT1H2M/1980-03-05T01:01:00', builder=AttoTimeBuilder)\n >>> result.next()\n attotime.attodatetime(1980, 3, 5, 1, 1, 0, 0, 0)\n >>> result.next()\n attotime.attodatetime(1980, 3, 4, 23, 59, 0, 0, 0)\n\nor for Python 3::\n\n >>> result = aniso8601.parse_repeating_interval('R/PT1H2M/1980-03-05T01:01:00', builder=AttoTimeBuilder)\n >>> next(result)\n attotime.attodatetime(1980, 3, 5, 1, 1, 0, 0, 0)\n >>> next(result)\n attotime.attodatetime(1980, 3, 4, 23, 59, 0, 0, 0)\n\nThe above treat years as 365 days and months as 30 days. Fractional months and years are supported accordingly::\n\n >>> aniso8601.parse_interval('P1.1Y/2001-02-28', builder=AttoTimeBuilder)\n (datetime.date(2001, 2, 28), datetime.date(2000, 1, 23))\n >>> aniso8601.parse_interval('2001-02-28/P1Y2.5M', builder=AttoTimeBuilder)\n (datetime.date(2001, 2, 28), datetime.date(2002, 5, 14))\n\nDevelopment\n===========\n\nSetup\n-----\n\nIt is recommended to develop using a `virtualenv <https://virtualenv.pypa.io/en/stable/>`_.\n\nInside a virtualenv, development dependencies can be installed automatically::\n\n $ pip install -e .[dev]\n\n`pre-commit <https://pre-commit.com/>`_ is used for managing pre-commit hooks::\n\n $ pre-commit install\n\nTo run the pre-commit hooks manually::\n\n $ pre-commit run --all-files\n\nTests\n-----\n\nTests can be run using the `unittest testing framework <https://docs.python.org/3/library/unittest.html>`_::\n\n $ python -m unittest discover attotimebuilder\n\nContributing\n============\n\nattotimebuilder is an open source project hosted on `Bitbucket <https://bitbucket.org/nielsenb/attotimebuilder>`_.\n\nAny and all bugs are welcome on our `issue tracker <https://bitbucket.org/nielsenb/attotimebuilder/issues>`_.\n\nReferences\n==========\n\n* `aniso8601 and sub-microsecond precision <https://bitbucket.org/nielsenb/aniso8601/issues/10/sub-microsecond-precision-in-durations-is>`_\n",
"bugtrack_url": null,
"license": null,
"summary": "A library for using the attotime datetime API with aniso8601",
"version": "0.4.1",
"project_urls": {
"Documentation": "https://attotimebuilder.readthedocs.io/",
"Homepage": "https://bitbucket.org/nielsenb/attotimebuilder",
"Source": "https://bitbucket.org/nielsenb/attotimebuilder",
"Tracker": "https://bitbucket.org/nielsenb/attotimebuilder/issues"
},
"split_keywords": [
"iso8601",
"attotime",
"aniso8601",
"datetime"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "112d8acac56fa3f6eaa4f588b757e60517326cb348dcd4fcf01f6ea2d226d428",
"md5": "684b2fe671a539c85153f53861d78e6f",
"sha256": "099d246d003856948b7f9ec554789584d8d818d48c7448da93461c3419cfed30"
},
"downloads": -1,
"filename": "attotimebuilder-0.4.1-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "684b2fe671a539c85153f53861d78e6f",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 13570,
"upload_time": "2025-01-10T01:59:20",
"upload_time_iso_8601": "2025-01-10T01:59:20.837849Z",
"url": "https://files.pythonhosted.org/packages/11/2d/8acac56fa3f6eaa4f588b757e60517326cb348dcd4fcf01f6ea2d226d428/attotimebuilder-0.4.1-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2db48c99d457638bd1f81f1072b0fd8fd1d47251e25b19befd300c3f69ef01af",
"md5": "b37b5c4cb7e5fcf4a63d91140f6e4c15",
"sha256": "a91f888e028baea6ae1e7945f6d94dc55c976b84bf544f1eb4fa761fb94fa17f"
},
"downloads": -1,
"filename": "attotimebuilder-0.4.1.tar.gz",
"has_sig": false,
"md5_digest": "b37b5c4cb7e5fcf4a63d91140f6e4c15",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 15894,
"upload_time": "2025-01-10T01:59:21",
"upload_time_iso_8601": "2025-01-10T01:59:21.946938Z",
"url": "https://files.pythonhosted.org/packages/2d/b4/8c99d457638bd1f81f1072b0fd8fd1d47251e25b19befd300c3f69ef01af/attotimebuilder-0.4.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-10 01:59:21",
"github": false,
"gitlab": false,
"bitbucket": true,
"codeberg": false,
"bitbucket_user": "nielsenb",
"bitbucket_project": "attotimebuilder",
"lcname": "attotimebuilder"
}