Skip to content

Latest commit

 

History

History
483 lines (341 loc) · 15.8 KB

index.rst

File metadata and controls

483 lines (341 loc) · 15.8 KB

Arrow: better dates and times for Python

What?

Arrow is a Python library that offers a sensible, human-friendly approach to creating, manipulating, formatting and converting dates, times, and timestamps. It implements and updates the datetime type, plugging gaps in functionality, and provides an intelligent module API that supports many common creation scenarios. Simply put, it helps you work with dates and times with fewer imports and a lot less code.

Arrow is heavily inspired by moment.js and requests.

Why?

Python's standard library and some other low-level modules have near-complete date, time and timezone functionality but don't work very well from a usability perspective:

  • Too many modules: datetime, time, calendar, dateutil, pytz and more
  • Too many types: date, time, datetime, tzinfo, timedelta, relativedelta, etc.
  • Timezones and timestamp conversions are verbose and unpleasant
  • Timezone naivety is the norm
  • Gaps in functionality: ISO-8601 parsing, time spans, humanization

Features

  • Fully implemented, drop-in replacement for datetime
  • Supports Python 2.6, 2.7, 3.3, 3.4 and 3.5
  • Timezone-aware & UTC by default
  • Provides super-simple creation options for many common input scenarios
  • Updated .replace method with support for relative offsets, including weeks
  • Formats and parses strings automatically
  • Partial ISO-8601 support
  • Timezone conversion
  • Timestamp available as a property
  • Generates time spans, ranges, floors and ceilings in time frames from year to microsecond
  • Humanizes and supports a growing list of contributed locales
  • Extensible for your own Arrow-derived types

Quickstart

$ pip install arrow
>>> import arrow
>>> utc = arrow.utcnow()
>>> utc
<Arrow [2013-05-11T21:23:58.970460+00:00]>

>>> utc = utc.shift(hours=-1)
>>> utc
<Arrow [2013-05-11T20:23:58.970460+00:00]>

>>> local = utc.to('US/Pacific')
>>> local
<Arrow [2013-05-11T13:23:58.970460-07:00]>

>>> arrow.get('2013-05-11T21:23:58.970460+00:00')
<Arrow [2013-05-11T21:23:58.970460+00:00]>

>>> local.timestamp
1368303838

>>> local.format()
'2013-05-11 13:23:58 -07:00'

>>> local.format('YYYY-MM-DD HH:mm:ss ZZ')
'2013-05-11 13:23:58 -07:00'

>>> local.humanize()
'an hour ago'

>>> local.humanize(locale='ko_kr')
'1시간 전'

User's Guide

Creation

Get 'now' easily:

>>> arrow.utcnow()
<Arrow [2013-05-07T04:20:39.369271+00:00]>

>>> arrow.now()
<Arrow [2013-05-06T21:20:40.841085-07:00]>

>>> arrow.now('US/Pacific')
<Arrow [2013-05-06T21:20:44.761511-07:00]>

Create from timestamps (ints or floats, or strings that convert to a float):

>>> arrow.get(1367900664)
<Arrow [2013-05-07T04:24:24+00:00]>

>>> arrow.get('1367900664')
<Arrow [2013-05-07T04:24:24+00:00]>

>>> arrow.get(1367900664.152325)
<Arrow [2013-05-07T04:24:24.152325+00:00]>

>>> arrow.get('1367900664.152325')
<Arrow [2013-05-07T04:24:24.152325+00:00]>

Use a naive or timezone-aware datetime, or flexibly specify a timezone:

>>> arrow.get(datetime.utcnow())
<Arrow [2013-05-07T04:24:24.152325+00:00]>

>>> arrow.get(datetime(2013, 5, 5), 'US/Pacific')
<Arrow [2013-05-05T00:00:00-07:00]>

>>> from dateutil import tz
>>> arrow.get(datetime(2013, 5, 5), tz.gettz('US/Pacific'))
<Arrow [2013-05-05T00:00:00-07:00]>

>>> arrow.get(datetime.now(tz.gettz('US/Pacific')))
<Arrow [2013-05-06T21:24:49.552236-07:00]>

Parse from a string:

>>> arrow.get('2013-05-05 12:30:45', 'YYYY-MM-DD HH:mm:ss')
<Arrow [2013-05-05T12:30:45+00:00]>

Search a date in a string:

>>> arrow.get('June was born in May 1980', 'MMMM YYYY')
<Arrow [1980-05-01T00:00:00+00:00]>

Some ISO-8601 compliant strings are recognized and parsed without a format string:

>>> arrow.get('2013-09-30T15:34:00.000-07:00')
<Arrow [2013-09-30T15:34:00-07:00]>

Arrow objects can be instantiated directly too, with the same arguments as a datetime:

>>> arrow.get(2013, 5, 5)
<Arrow [2013-05-05T00:00:00+00:00]>

>>> arrow.Arrow(2013, 5, 5)
<Arrow [2013-05-05T00:00:00+00:00]>

Properties

Get a datetime or timestamp representation:

>>> a = arrow.utcnow()
>>> a.datetime
datetime.datetime(2013, 5, 7, 4, 38, 15, 447644, tzinfo=tzutc())

>>> a.timestamp
1367901495

Get a naive datetime, and tzinfo:

>>> a.naive
datetime.datetime(2013, 5, 7, 4, 38, 15, 447644)

>>> a.tzinfo
tzutc()

Get any datetime value:

>>> a.year
2013

Call datetime functions that return properties:

>>> a.date()
datetime.date(2013, 5, 7)

>>> a.time()
datetime.time(4, 38, 15, 447644)

Replace & shift

Get a new :class:`Arrow <arrow.arrow.Arrow>` object, with altered attributes, just as you would with a datetime:

>>> arw = arrow.utcnow()
>>> arw
<Arrow [2013-05-12T03:29:35.334214+00:00]>

>>> arw.replace(hour=4, minute=40)
<Arrow [2013-05-12T04:40:35.334214+00:00]>

Or, get one with attributes shifted forward or backward:

>>> arw.shift(weeks=+3)
<Arrow [2013-06-02T03:29:35.334214+00:00]>

Even replace the timezone without altering other attributes:

>>> arw.replace(tzinfo='US/Pacific')
<Arrow [2013-05-12T03:29:35.334214-07:00]>

Format

>>> arrow.utcnow().format('YYYY-MM-DD HH:mm:ss ZZ')
'2013-05-07 05:23:16 -00:00'

Convert

Convert to timezones by name or tzinfo:

>>> utc = arrow.utcnow()
>>> utc
<Arrow [2013-05-07T05:24:11.823627+00:00]>

>>> utc.to('US/Pacific')
<Arrow [2013-05-06T22:24:11.823627-07:00]>

>>> utc.to(tz.gettz('US/Pacific'))
<Arrow [2013-05-06T22:24:11.823627-07:00]>

Or using shorthand:

>>> utc.to('local')
<Arrow [2013-05-06T22:24:11.823627-07:00]>

>>> utc.to('local').to('utc')
<Arrow [2013-05-07T05:24:11.823627+00:00]>

Humanize

Humanize relative to now:

>>> past = arrow.utcnow().shift(hours=-1)
>>> past.humanize()
'an hour ago'

Or another Arrow, or datetime:

>>> present = arrow.utcnow()
>>> future = present.shift(hours=2)
>>> future.humanize(present)
'in 2 hours'

Support for a growing number of locales (see locales.py for supported languages):

>>> future = arrow.utcnow().shift(hours=1)
>>> future.humanize(a, locale='ru')
'через 2 час(а,ов)'

Ranges & spans

Get the time span of any unit:

>>> arrow.utcnow().span('hour')
(<Arrow [2013-05-07T05:00:00+00:00]>, <Arrow [2013-05-07T05:59:59.999999+00:00]>)

Or just get the floor and ceiling:

>>> arrow.utcnow().floor('hour')
<Arrow [2013-05-07T05:00:00+00:00]>

>>> arrow.utcnow().ceil('hour')
<Arrow [2013-05-07T05:59:59.999999+00:00]>

You can also get a range of time spans:

>>> start = datetime(2013, 5, 5, 12, 30)
>>> end = datetime(2013, 5, 5, 17, 15)
>>> for r in arrow.Arrow.span_range('hour', start, end):
...     print r
...
(<Arrow [2013-05-05T12:00:00+00:00]>, <Arrow [2013-05-05T12:59:59.999999+00:00]>)
(<Arrow [2013-05-05T13:00:00+00:00]>, <Arrow [2013-05-05T13:59:59.999999+00:00]>)
(<Arrow [2013-05-05T14:00:00+00:00]>, <Arrow [2013-05-05T14:59:59.999999+00:00]>)
(<Arrow [2013-05-05T15:00:00+00:00]>, <Arrow [2013-05-05T15:59:59.999999+00:00]>)
(<Arrow [2013-05-05T16:00:00+00:00]>, <Arrow [2013-05-05T16:59:59.999999+00:00]>)

Or just iterate over a range of time:

>>> start = datetime(2013, 5, 5, 12, 30)
>>> end = datetime(2013, 5, 5, 17, 15)
>>> for r in arrow.Arrow.range('hour', start, end):
...     print repr(r)
...
<Arrow [2013-05-05T12:30:00+00:00]>
<Arrow [2013-05-05T13:30:00+00:00]>
<Arrow [2013-05-05T14:30:00+00:00]>
<Arrow [2013-05-05T15:30:00+00:00]>
<Arrow [2013-05-05T16:30:00+00:00]>
.. toctree::
   :maxdepth: 2

Factories

Use factories to harness Arrow's module API for a custom Arrow-derived type. First, derive your type:

>>> class CustomArrow(arrow.Arrow):
...
...     def days_till_xmas(self):
...
...         xmas = arrow.Arrow(self.year, 12, 25)
...
...         if self > xmas:
...             xmas = xmas.shift(years=1)
...
...         return (xmas - self).days

Then get and use a factory for it:

>>> factory = arrow.ArrowFactory(CustomArrow)
>>> custom = factory.utcnow()
>>> custom
>>> <CustomArrow [2013-05-27T23:35:35.533160+00:00]>

>>> custom.days_till_xmas()
>>> 211

Tokens

Use the following tokens in parsing and formatting. Note that they're not the same as the tokens for strptime(3):

  Token Output
Year YYYY 2000, 2001, 2002 ... 2012, 2013
  YY 00, 01, 02 ... 12, 13
Month MMMM January, February, March ... [1]
  MMM Jan, Feb, Mar ... [1]
  MM 01, 02, 03 ... 11, 12
  M 1, 2, 3 ... 11, 12
Day of Year DDDD 001, 002, 003 ... 364, 365
  DDD 1, 2, 3 ... 4, 5
Day of Month DD 01, 02, 03 ... 30, 31
  D 1, 2, 3 ... 30, 31
  Do 1st, 2nd, 3rd ... 30th, 31st
Day of Week dddd Monday, Tuesday, Wednesday ... [2]
  ddd Mon, Tue, Wed ... [2]
  d 1, 2, 3 ... 6, 7
Hour HH 00, 01, 02 ... 23, 24
  H 0, 1, 2 ... 23, 24
  hh 01, 02, 03 ... 11, 12
  h 1, 2, 3 ... 11, 12
AM / PM A AM, PM, am, pm [1]
  a am, pm [1]
Minute mm 00, 01, 02 ... 58, 59
  m 0, 1, 2 ... 58, 59
Second ss 00, 01, 02 ... 58, 59
  s 0, 1, 2 ... 58, 59
Sub-second S... 0, 02, 003, 000006, 123123123123... [3]
Timezone ZZZ Asia/Baku, Europe/Warsaw, GMT ... [4]
  ZZ -07:00, -06:00 ... +06:00, +07:00
  Z -0700, -0600 ... +0600, +0700
Timestamp X 1381685817

Footnotes

[1](1, 2, 3, 4) localization support for parsing and formatting
[2](1, 2) localization support only for formatting
[3]the result is truncated to microseconds, with half-to-even rounding.
[4]timezone names from tz database provided via dateutil package

API Guide

arrow.arrow

.. automodule:: arrow.arrow
    :members:

arrow.factory

.. automodule:: arrow.factory
    :members:

arrow.api

.. automodule:: arrow.api
    :members:

arrow.locale

.. automodule:: arrow.locales
    :members: