{"id":13502434,"url":"https://github.com/dabapps/periodical","last_synced_at":"2026-01-10T20:58:51.884Z","repository":{"id":12666903,"uuid":"15338830","full_name":"dabapps/periodical","owner":"dabapps","description":"NO LONGER MAINTAINED A library for working with time and date series in Python","archived":true,"fork":false,"pushed_at":"2018-11-30T11:11:54.000Z","size":42,"stargazers_count":46,"open_issues_count":2,"forks_count":0,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-03-04T06:04:53.750Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dabapps.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-12-20T13:20:40.000Z","updated_at":"2025-01-27T05:28:48.000Z","dependencies_parsed_at":"2022-08-29T22:30:46.020Z","dependency_job_id":null,"html_url":"https://github.com/dabapps/periodical","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabapps%2Fperiodical","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabapps%2Fperiodical/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabapps%2Fperiodical/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabapps%2Fperiodical/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dabapps","download_url":"https://codeload.github.com/dabapps/periodical/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246174208,"owners_count":20735406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T22:02:13.841Z","updated_at":"2025-03-29T10:32:58.684Z","avatar_url":"https://github.com/dabapps.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# Periodical\n\n**A library for working with time and date series in Python.**\n\n[![Build Status](https://travis-ci.org/dabapps/periodical.png?branch=master)](https://travis-ci.org/dabapps/periodical)\n[![Coverage Status](https://coveralls.io/repos/dabapps/periodical/badge.png?branch=master)](https://coveralls.io/r/dabapps/periodical?branch=master)\n[![PyPI version](https://badge.fury.io/py/periodical.png)](http://badge.fury.io/py/periodical)\n\nThe `periodical` Python module provides a convienient way of dealing with time and date series.  \n\nThese are particular useful for aggregating events at differing time granualities, for example when generating graphs or reports covering a given time span.\n\n### Requirements\n\n`periodical` currently supports Python 2.7, 3.2 and 3.3.\n\n### Installation\n\nYou can install the `periodical` module using pip:\n\n    pip install periodical\n\n### An example of using periodical\n\nIn this example we have a service which is logging the response times from a web application.  We'd like to generate the average response time for each hourly period over the previous 24 hours.\n\nFirst we'll get the sequence of the last 24 hour periods.\n\n    \u003e\u003e\u003e import periodical\n    \u003e\u003e\u003e hour_periods = periodical.time_periods_descending(span='hour', num_periods=24)\n    \u003e\u003e\u003e hour_periods\n    [\n        \u003cTimePeriod '2014-04-28T15:00Z'\u003e,\n        \u003cTimePeriod '2014-04-28T14:00Z'\u003e,\n        \u003cTimePeriod '2014-04-28T13:00Z'\u003e,\n        ...\n    ]\n\nLet's assume we have a list of requests in the `request_log` variable.  Let's also assume that each of the request objects has an asociated `started` property, which is a `datetime` representing the time the request was recieved, and a `duration` property, which is a float representing the number of seconds it took to generate and send a response.\n\nIn order to work with this data in periodical we need to first transform our objects into a list of two-tuple data points, of the form `(datetime, value)`, like so:\n\n    \u003e\u003e\u003e data_points = [(request.started, request.duration) for request in request_log]\n    \u003e\u003e\u003e data_points\n    [\n        (datetime.datetime(2014, 4, 28, 15, 23, 35, 682504, tzinfo=\u003cUTC\u003e), 0.24),\n        (datetime.datetime(2014, 4, 28, 15, 22, 12, 659191, tzinfo=\u003cUTC\u003e), 0.22),\n        (datetime.datetime(2014, 4, 28, 15, 21, 45, 728530, tzinfo=\u003cUTC\u003e), 0.30),\n        ...\n    ]\n\nNow that we have our data points we can get the average response time within each hour time period.  We use the `periodical.average()` function, which returns an ordered dictionary mapping each time period onto the average value of data points within that period.\n\n    \u003e\u003e\u003e average_response_times = periodical.average(hour_periods, data_points)\n    \u003e\u003e\u003e average_response_times\n    {\n        \u003cTimePeriod '2014-04-28T15:00Z'\u003e: 0.26,\n        \u003cTimePeriod '2014-04-28T14:00Z'\u003e: 0.24,\n        \u003cTimePeriod '2014-04-28T13:00Z'\u003e: 0.35,\n        ...\n    }\n\n---\n\n## TimePeriod and DatePeriod objects\n\nThe two basic building blocks of periodical are the `TimePeriod` and `DatePeriod` classes.\n\nThe `TimePeriod` class is used to represent an interval between two datetimes.\n\nThe `DatePeriod` class is used to represent an interval of dates.\n\n### Creating period instances\n\nYou can instantiate a `TimePeriod` or `DatePeriod` object by specifying a time span.  By default this will return a period that covers the current time or day in UTC timezone.\n\nFor  `DatePeriod` this may be one of `'day'`, `'week'`, `'month'`, `'quarter'` or `'year'`.\n\n    \u003e\u003e\u003e import periodical\n    \u003e\u003e\u003e period = periodical.DatePeriod(span='week')\n    \u003e\u003e\u003e period\n    \u003cDatePeriod '2014-W02'\u003e\n\nFor `TimePeriod` this may be any of the date spans, or may also be one of `'hour'`, `'minute'`, or `'second'`.\n\n    \u003e\u003e\u003e period = periodical.TimePeriod(span='hour')\n    \u003e\u003e\u003e period\n    \u003cTimePeriod '2014-01-02T14Z'\u003e\n\nYou can also explicitly provide a date or time that you wish the period to cover.\n\n\t\u003e\u003e\u003e date = datetime.date(2015, 1, 25)\n    \u003e\u003e\u003e period = periodical.DatePeriod(date=date, span='week')\n    \u003e\u003e\u003e period\n    \u003cDatePeriod '2015-W04'\u003e\n\n### A note on timezones\n\nThe default implementations for `DatePeriod` and `TimePeriod` return periods coverring the current date or time *in the UTC timezone*.  To work with local time you'll need to pass the local date or time explicitly.\n\nFor example to get the current week period, using local time to determine the current date instead of using UTC time, we would do the following:\n\n    \u003e\u003e\u003e today = datetime.date.today()\n    \u003e\u003e\u003e period = periodical.DatePeriod(date=today, span='week')\n\n#### Timezone awareness and TimePeriod objects\n\nWhen passing a `datetime` instance to `TimePeriod`, the resulting period instance will use the same timezone info as the provided argument, or be timezone-naive if no timezone info is included.\n\nInstantiating a `TimePeriod` with no timezone information:\n\n\t\u003e\u003e\u003e time = datetime.datetime(2015, 1, 25, 4)\n    \u003e\u003e\u003e period = periodical.TimePeriod(time=time, span='hour')\n    \u003e\u003e\u003e period\n    \u003cTimePeriod '2015-01-25T04'\u003e\n\nInstantiating a `TimePeriod` with an explicit UTC timezone:\n\n\t\u003e\u003e\u003e time = datetime.datetime(2015, 1, 25, 4, tzinfo=periodical.UTC())\n    \u003e\u003e\u003e period = periodical.TimePeriod(time=time, span='hour')\n    \u003e\u003e\u003e period\n    \u003cTimePeriod '2015-01-25T04Z'\u003e\n\nIf not specified, the default time is set using `periodical.utcnow()` which returns the current time with a UTC timezone.\n\nYou can determine the timezone information in use by examining the suffix of the `TimePeriod` representation.\n\n    \u003cTimePeriod '2015-01-25T04'\u003e        # 25th Jan 2015, 04:00 Timezone naive\n    \u003cTimePeriod '2015-01-25T04Z'\u003e       # 25th Jan 2015, 04:00 UTC\n    \u003cTimePeriod '2015-01-25T04-05:00'\u003e  # 25th Jan 2015, 04:00 EST\n\n### Start and end dates\n\nBoth objects provide `start` and `end` properties.  For `DatePeriod` objects these return an instance of `date`.\n\n    \u003e\u003e\u003e period = periodical.DatePeriod(span='week')\n    \u003e\u003e\u003e period.start\n    datetime.date(2014, 1, 6)\n    \u003e\u003e\u003e period.end\n    datetime.date(2014, 1, 12)\n\nFor `TimePeriod` objects these properties return `datetime` instances.\n\n    \u003e\u003e\u003e period = periodical.TimePeriod(span='month')\n    \u003e\u003e\u003e period.start\n    datetime.datetime(2014, 1, 1, 0, 0, tzinfo=\u003cUTC\u003e)\n\t\u003e\u003e\u003e period.end\n\tdatetime.datetime(2014, 2, 1, 0, 0, tzinfo=\u003cUTC\u003e)\n\nPeriod objects also provide a `contains()` method that takes a date or time object and returns `True` if the date is contained by the given period.\n\n    \u003e\u003e\u003e period = periodical.DatePeriod(span='month')\n    \u003e\u003e\u003e period.contains(datetime.date(2014, 3, 20))\n    True\n    \u003e\u003e\u003e period.contains(datetime.date(2014, 4, 20))\n    False\n\n### Differences between time and date periods\n\nWhen considering the end point of a period there is an important distinction to be made between `DatePeriod` and `TimePeriod` objects, due to the fact that dates and times represent fundamentally different concepts.\n\n* A `date` represents a discreet entity.  The `end` property of a `DatePeriod` will be the last date included in that period.\n* A `datetime` represents a point in time.  The `end` property of a `TimePeriod` will not be included in that period.\n\nFor example, the date and time periods for the month of November 2014 may be represented like so:\n\n    DatePeriod: start date \u003c= period \u003c= end date\n\n             2014-11-01                              2014-11-30\n                 |                                       |\n                 V                                       V\n            +---------+---------+--   --+----------+----------+\n            |  1 Nov. |  2 Nov. |       |  29 Nov. |  30 Nov. |\n            |  2014   |  2014   |  ...  |   2015   |   2015   |\n            +---------+---------+--   --+----------+----------+\n            ^                                                 ^\n            |                                                 |\n    2014-11-01 00:00:00                               2014-12-01 00:00:00\n    \n    TimePeriod: start time \u003c= period \u003c end time\n\n\n### Iterating through periods\n\nTo return a new `TimePeriod` or `DatePeriod` object that occurs immediately before or after the existing period, you can call the `.next()` and `.previous()` methods.\n\n    \u003e\u003e\u003e period = periodical.DatePeriod(date=datetime.date(2014, 01, 05), span='week')\n    \u003e\u003e\u003e period.next()\n    \u003cDatePeriod '2014-W02'\u003e\n    \u003e\u003e\u003e period.previous()\n    \u003cDatePeriod '2013-W52'\u003e\n\n### String representations\n\nDatePeriod objects use a unique representation that follows ISO 8601 with the following exceptions:\n\n* Only the relevant portion of the period will be included in the representation.\n* Quarterley intervals use a 'Q' prefix to the quarter.\n* If present, then timezone information is included using a `Z` or `±HH:MM` suffix.\n\nThe following are all valid representations of `DatePeriod` objects:\n\n    \u003cDatePeriod '2015'\u003e        # The 2015 year.\n    \u003cDatePeriod '2013-Q2'\u003e     # The second quarter of 2013.\n    \u003cDatePeriod '2014-03'\u003e     # March 2014.\n    \u003cDatePeriod '2013-W24'\u003e    # The 24th week of 2013.  (Numbering by ISO 8601 weeks)\n    \u003cDatePeriod '2014-04-29'\u003e  # The 29th of April 2014.\n\nThe following are all valid representations of `TimePeriod` objects:\n\n    \u003cTimePeriod '2015Z'\u003e       # The 2015 year, UTC.\n    \u003cTimePeriod '2013-Q2Z'\u003e    # The second quarter of 2013, UTC.\n    \u003cTimePeriod '2014-03'\u003e     # March 2014, timezone-naive.\n    \u003cTimePeriod '2013-W24Z'\u003e   # The 24th week of 2013, UTC.  (Numbering by ISO 8601 weeks)\n    \u003cTimePeriod '2014-04-29-05:00'\u003e           # The 29th of April 2014, EST.\n\t\u003cTimePeriod '2014-04-29T15Z'\u003e             # 15:00:00-16:00:00 UTC, 29th of April 2014.\n\t\u003cTimePeriod '2014-04-29T15:34'\u003e           # 15:34:00-15:35:00 timezone-naive, 29th of April 2014.\n\t\u003cTimePeriod '2014-04-29T15:34:24-05:00'\u003e  # 15:34:24-15:34:25 EST, 29th of April 2014.\n\nYou can also instantiate a `TimePeriod` or `DatePeriod` object using it's unique representation.\n\n    \u003e\u003e\u003e period = periodical.DatePeriod('2014-Q1')\n    \u003e\u003e\u003e period.start\n    datetime.date(2014, 1, 1)\n    \u003e\u003e\u003e period.end\n    datetime.date(2014, 3, 31)\n\nThe `isoformat()` method returns a valid ISO 8601 formatted time representing the start of the range.  Note that quarterly representations cannot be expressed in ISO 8601, so will simply return the monthly representation of the start date.\n\n    '2015'               # The 2015 year.\n    '2013-04'            # The second quarter of 2013.\n    '2014-03'            # March, 2014.\n    '2013-W24'           # The 24th week of 2013.  (Numbering by ISO 8601 weeks)\n    '2014-04-29'         # The 29th of April, 2014.\n    '2014-04-29T15:00Z'  # 15:00 UTC on 29th of April, 2014.\n\nNote that the strings returned  by `isoformat()` are not unique in the same way that the representational strings are.  For example, `'2014-04'` may represent either the quarter `2014-Q2` or the month `2014-04`.  Similarly, the isoformat string `'2014-04-29T15:00Z'` may represent either a complete hour span or a single minute span.\n\n---\n\n## Sequences of periods\n\nThe `periodical` module provides functions for returning sequences of time or date periods.  These allow you to easily return ranges such as \"the last 24 hours\", or \"all the weeks since the start of the year\".\n\n### time_periods_ascending(time, span, num_periods)\n\n### date_periods_ascending(date, span, num_periods)\n\nReturns a list of `TimePeriod` or `DatePeriod` objects in chronological order, starting with a given time or date.\n\n##### Arguments:\n\n* `time`/`date` **(Optional)** - The starting time or date.  If not provided, this defaults to the current time or day.\n* `span` - A string representing the period length.\n* `num_periods` - An integer representing the number of `DatePeriod` objects to return.\n\nExample result from `date_periods_ascending(span='monthly', num_periods=3)` on Nov 25th, 2014.\n\n       Nov 25th 2014\n           |\n           V\n    +--------+--------+--------+\n    |  Nov.  |  Dec.  |  Jan.  |\n    |  2014  |  2014  |  2015  |\n    +--------+--------+--------+\n       [0] ---\u003e [1] ---\u003e [2]\n\nExample code:\n\n    \u003e\u003e\u003e periodical.date_periods_ascending(span='monthly', num_periods=3)\n    [\u003cDatePeriod '2014-11'\u003e, \u003cDatePeriod '2014-12'\u003e, \u003cDatePeriod '2015-01'\u003e]\n\n### time_periods_descending(time, span, num_periods)\n\n### date_periods_descending(date, span, num_periods)\n\nReturns a list of `TimePeriod` or `DatePeriod` objects in reverse chronological order, starting with a given time or date.\n\n##### Arguments:\n\n* `time`/`date` **(Optional)** - The starting time or date.  If not provided, this defaults to the current time or day.\n* `span` - A string representing the period length.\n* `num_periods` - An integer representing the number of `DatePeriod` objects to return.\n\nExample result from `date_periods_descending(span='monthly', num_periods=3)` on Nov 25th, 2014.\n\n                       Nov 25th 2014\n                             |\n                             V\n    +--------+--------+--------+\n    |  Sept. |  Oct.  |  Nov.  |\n    |  2014  |  2014  |  2014  |\n    +--------+--------+--------+\n       [2] \u003c--- [1] \u003c--- [0]\n\n\nExample code:\n\n    \u003e\u003e\u003e periodical.date_periods_descending(span='monthly', num_periods=3)\n    [\u003cDatePeriod '2014-11'\u003e, \u003cDatePeriod '2014-10'\u003e, \u003cDatePeriod '2014-09'\u003e]\n\n### time_periods_between(time_from, time_until, period)\n\n### date_periods_between(date_from, date_until, period)\n\nReturns a list of `TimePeriod` or `DatePeriod` objects in *either* chronological *or* reverse chronological order, starting and ending with a pair of given datetimes or dates.\n\n##### Arguments:\n\n* `time_from`/`date_from` **(Optional)** - The starting time or date.  If not provided, this defaults to the current time or day.\n* `time_until`/`date_until` **(Optional)** - The ending time or date.  If not provided, this defaults to the current time or day.\n* `span` - A string representing the period length.\n\nExample result from `date_periods_between(date_until=datetime.date(2014, 12, 31), span='monthly')` on Sept 23rd, 2014.\n\n    Sept 23rd 2014                 Dec 31st 2014\n          |                             |\n          V                             V\n    +--------+--------+--------+--------+\n    |  Sept. |  Oct.  |  Nov.  |  Dec.  | \n    |  2014  |  2014  |  2014  |  2014  |\n    +--------+--------+--------+--------+\n       [0] ---\u003e [1] ---\u003e [2] ---\u003e [3]\n\nExample code:\n\n    \u003e\u003e\u003e periodical.date_periods_between(date_until=datetime.date(2014, 12, 31), span='monthly')\n    [\u003cDatePeriod '2014-09'\u003e, \u003cDatePeriod '2014-10'\u003e, \u003cDatePeriod '2014-11'\u003e, \u003cDatePeriod '2014-12'\u003e]\n\n---\n\n## Aggregation of values\n\nFor the following documentation we're going to need a set of data points that we're interested in aggregating, in order to demonstate how the different aggregation functions work.\n\nWe'll also need a set of periods that we're interested in aggregating the data against.\n\nOur initial data looks like this:\n\n    \u003e\u003e\u003e start = date(2014, 09, 01)\n    \u003e\u003e\u003e periods = periodical.date_periods_ascending(start, num_periods = 4)\n    \u003e\u003e\u003e data_points = [\n        (datetime.date(2014, 9, 1), 20),\n        (datetime.date(2014, 9, 2), 25),\n        (datetime.date(2014, 10, 1), 20),\n        (datetime.date(2014, 10, 1), 20),\n        (datetime.date(2014, 12, 1), 30)\n    ]\n\n### map(periods, data_points, transform=None)\n\nGiven a sequence of time periods and a set of events, maps each event into it's containing period.\n\n* `periods`: A list of DatePeriod or TimePeriod instances.\n* `times_value_pairs`: A list of two-tuples of the form `(date or datetime, value)`.\n* `transform`: If provided, this should be a function that takes a single argument. The function will be applied to the list of values contained in each period in order to generate the output for that period.\n\nReturns an ordered dictionary that maps each period to a list of the contained values.\n\n     \u003e\u003e\u003e periodical.map(periods, data_points)\n     OrderedDict([\n         (\u003cDatePeriod '2014-09'\u003e, [20, 25]),\n         (\u003cDatePeriod '2014-10'\u003e, [20, 20]),\n         (\u003cDatePeriod '2014-11'\u003e, []),\n         (\u003cDatePeriod '2014-12'\u003e, [30])\n     ])\n\n### summation(periods, data_points, zero=0)\n\nGiven a sequence of time periods and a set of data points, produces the sum of data points within each period.\n\n**Arguments**:\n\n* `periods`: A list of DatePeriod or TimePeriod instances.\n* `times_value_pairs`: A list of two-tuples of the form `(date or datetime, value)`.\n* `zero`: The initial value to use for summations.  If using non-integer type you may wish to set this to ensure that zero values in the return result have the same type as non-zero values.  For example, you might set the zero argument to `0.0` or `Decimal('0')`. **(Optional)**\n\nReturns an ordered dictionary that sums the values of the data points contained in each period.\n\n     \u003e\u003e\u003e periodical.summation(periods, data_points)\n     OrderedDict([\n         (\u003cDatePeriod '2014-09'\u003e, 45),\n         (\u003cDatePeriod '2014-10'\u003e, 40),\n         (\u003cDatePeriod '2014-11'\u003e, 0),\n         (\u003cDatePeriod '2014-12'\u003e, 30)\n     ])\n\n### average(periods, data_points)\n\nGiven a sequence of time periods and a set of data points, produces the average of data points within each period.\n\n**Arguments**:\n\n* `periods`: A list of DatePeriod or TimePeriod instances.\n* `times_value_pairs`: A list of two-tuples of the form `(date or datetime, value)`.\n\nReturns an ordered dictionary that sums the values of the data points contained in each period.  Periods which do not contain any data points will be mapped to `None`.\n\n     \u003e\u003e\u003e periodical.average(periods, data_points)\n     OrderedDict([\n         (\u003cDatePeriod '2014-09'\u003e, 22.5),\n         (\u003cDatePeriod '2014-10'\u003e, 20.0),\n         (\u003cDatePeriod '2014-11'\u003e, None),\n         (\u003cDatePeriod '2014-12'\u003e, 30.0)\n     ])\n \n### count(periods, times)\n\nCounts the number of occurances of an event within each period.\n\n**Arguments**:\n\n* `periods`: A list of DatePeriod or TimePeriod instances.\n* `times`: A list of date or datetime instances.\n\nReturns an ordered dictionary that maps each period to the corresponding count of the number of date or time instances that it contained.\n\n     \u003e\u003e\u003e times = [date for (date, value) in data_points]\n     \u003e\u003e\u003e periodical.count(periods, times)\n     OrderedDict([\n         (\u003cDatePeriod '2014-09'\u003e, 2),\n         (\u003cDatePeriod '2014-10'\u003e, 2),\n         (\u003cDatePeriod '2014-11'\u003e, 0),\n         (\u003cDatePeriod '2014-12'\u003e, 1)\n     ])\n\n## Timezone utilities\n\nThe periodical library includes a few utility classes to make it easier to work with properly timezone-aware datetime objects.\n\n### UTC\n\nA `tzinfo` class for representing the UTC timezone.\n\n    \u003e\u003e\u003e time = datetime.datetime(2014, 01, 01, tzinfo=periodical.UTC())\n    \u003e\u003e\u003e time\n    datetime.datetime(2014, 1, 1, 0, 0, tzinfo=\u003cUTC\u003e)\n\n### Offset\n\nA `tzinfo` class for representing the timezone with the given offset.  The offset string must be specified in the form `+HH:MM` or `-HH:MM`.\n\n    \u003e\u003e\u003e time = datetime.datetime(2014, 01, 01, tzinfo=periodical.Offset('-05:00'))\n    \u003e\u003e\u003e time\n    datetime.datetime(2014, 1, 1, 0, 0, tzinfo=\u003cOffset '-05:00'\u003e)\n\n### utcnow()\n\nReturns a `datetime` instance representing the current time in UTC, with an attached `UTC` timzone instance.\n\n    \u003e\u003e\u003e now = periodical.utcnow()\n    \u003e\u003e\u003e now\n    datetime.datetime(2014, 1, 30, 13, 39, 13, 515377, tzinfo=\u003cUTC\u003e)\n\n### utctoday()\n\nReturns a `datetime` instance representing the current date within the UTC timezone.\n\n    \u003e\u003e\u003e today = periodical.utctoday()\n    \u003e\u003e\u003e today\n    datetime.date(2014, 1, 30) \n\n### utc_datetime(\\*args, \\*\\*kwargs)\n\nReturns a new `datetime` instance representing the given time, with an attached `UTC` timzone instance.\n\n    \u003e\u003e\u003e time = periodical.utc_datetime(2014, 01, 01, 14, 30)\n    \u003e\u003e\u003e time\n    datetime.datetime(2014, 1, 1, 14, 30, tzinfo=\u003cUTC\u003e)\n\n---\n\n## License\n\nCopyright © 2014 Tom Christie \u0026 DabApps.\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without \nmodification, are permitted provided that the following conditions are met:\n\nRedistributions of source code must retain the above copyright notice, this \nlist of conditions and the following disclaimer.\nRedistributions in binary form must reproduce the above copyright notice, this \nlist of conditions and the following disclaimer in the documentation and/or \nother materials provided with the distribution.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND \nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE \nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL \nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR \nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER \nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n## Code of conduct\n\nFor guidelines regarding the code of conduct when contributing to this repository please review [https://www.dabapps.com/open-source/code-of-conduct/](https://www.dabapps.com/open-source/code-of-conduct/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdabapps%2Fperiodical","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdabapps%2Fperiodical","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdabapps%2Fperiodical/lists"}