Source – https://analyticsindiamag.com/
Arrow is a flexible Python library designed to create, format, manipulate, and convert dates, time, and timestamps in a sensible and human-friendly manner. It provides an intelligent module API that allows dealing with dates and times with a few code lines and imports. The library is named after the “time’s arrow” concept suggesting the one-directional progress of time. It is inspired by Requests (an HTTP library) and Moment.js (a JavaScript date library).
Why Arrow?
Standard Python library and low-level conventional modules are available for the various date and time functionalities but have the following limitations from a user’s point of view:
- Too many modules available such as time, datetime, dateutil, calendar and pytz
- A large number of data types to choose from such as datetime, date, time, timedelta, tzinfo and so on
- Users may lack experience in handling different time zones
- Inefficient ways of timestamps and timezone conversions
- Gaps in functionalities such as humanization (e.g. converting a date into human-readable format) and ISO 8601 parsing
Highlighting Features of Arrow
- Supports Python 3.6+ versions
- A fully-implemented, efficient alternative to datetime standard library
- Aware of timezones (uses UTC (Coordinated Universal Time) by default) and enables easy timezone conversion.
- Automatic formatting and parsing of strings
- Widely supports ISO 8601 standard date and time format.
- Supports pytz, ZoneInfo and dateutil objects
- Can generate floors, ceilings, spans and ranges for time frames ranging from microseconds to years
- Can be extended to users’ own Arrow-derived datatypes
- Supports PEP 484-style type hints
Installing Arrow
Install Arrow using pip command as follows:
pip install -U arrow
Practical Implementation
Here’s a demonstration of performing various operations using Arrow. The experiments have been done in Google colab with Python version3.7.10. Explanation of each operation along with its output is as follows:
First, import the Arrow library
import arrow as arw
- Represent current time in the given timezone
arw.now()
With no timezone specified, an Arrow object representing current UTC time will be created. Same output results on executing
arw.utcnow()
Output: <Arrow [2021-03-16T10:39:26.746385+00:00]>
To get current time in say US/Pacific timezone:
arw.now(‘US/Pacific’)
Output: <Arrow [2021-03-16T03:48:10.893440-07:00]>
- Convert a specified integer or float number into a floating-point UTC timestamp
arw.get(1567900664)
Output: <Arrow [2019-09-07T23:57:44+00:00]>
#Try with a floating point input arw.get(17900664.5463877)
Output: <Arrow [1970-07-27T04:24:24.546388+00:00]>
Verify the converted output here.
- String parsing
arw.get('12-03-2020 22:30:25', 'MM-DD-YYYY HH:mm:ss')
Specified date and time will be represented as MM-DD-YYYY HH:mm:ss
format
Output: <Arrow [2020-12-03T22:30:25+00:00]>
- Extract date from a string
arw.get('I was born on March 12 1990','MMMM DD YYYY')
‘MMMM DD YYYY’ formatted date will be searched in the string
Output: <Arrow [1990-03-12T00:00:00+00:00]>
- Instantiate Arrow object by directly providing a datetime argument
arw.Arrow(2020,12,26)
Output: <Arrow [2020-12-26T00:00:00+00:00]>
- Get a datetime representation an Arrow object
x = arw.now()
Suppose, x is <Arrow [2021-03-16T11:49:17.908895+00:00]>
x.datetime
Output: datetime.datetime(2021, 3, 16, 11, 49, 17, 908895, tzinfo=tzlocal())
The components can then be separated as:
x.month
Output: 3
x.year
Output: 2021
x.day
Output: 16
x.hour
Output: 11
Datetime functions can be called to get properties of the Arrow object
x.time()
Output: datetime.time(11, 49, 17, 908895)
- Replace one or more components of the Arrow object
a = arw.now()
Suppose, ‘a’ is <Arrow [2021-03-16T12:00:13.500164+00:00]>
a.replace(year=2019, second=45, month=11)
will give the output: <Arrow [2019-11-16T12:00:45.500164+00:00]>
- One or more Arrow object attributes can be shifted forward or backward
present = arw.now()
Suppose, ‘present’ object is <Arrow [2021-03-16T12:08:34.530495+00:00]>
Go forward in time by 2 years
present.shift(years=+2)
Output: <Arrow [2023-03-16T12:08:34.530495+00:00]>
Go backward by 4 hours
present.shift(hours=-4)
Output: <Arrow [2021-03-16T08:08:34.530495+00:00]>
- Represent date and time in the required format
arw.now().format('HH:MM:SS MM:DD:YYYY')
Output: 12:03:00 03:16:2021
(i.e. 12 hrs 3 mins 00 sec, 16 March 2021)
- Convert default UTC to specified timezone
utc = arw.utcnow()
Suppose, utc is <Arrow [2021-03-16T12:20:43.301159+00:00]>
It can be converted to US/Pacific time zone as follows:
utc.to('US/Pacific')
Output: <Arrow [2021-03-16T05:20:43.301159-07:00]>
- Humanization examples
Humanize relative to current time:
future = arw.now().shift(minutes=+2) #advance by 2 mins future.humanize()
Output: ‘in 2 minutes’
Humanize relative to another datetime or Arrow object
present = arw.now() #current time future = present.shift(days=-3) #go back by 3 days #how far is present from future future.humanize(present)
Output: ‘3 days ago’
#how far is future from present present.humanize(future)
Output: ‘in 3 days’
To get only the distance:
future.humanize(present, only_distance=True)
Output: ‘3 days’
Indicate time difference in terms of one or more specific time granularities like hours,
minutes etc.
future.humanize(present, granularity="minute")
Output: ‘4320 minutes ago’
#3 days equals 4320 mins
Multiple granularities can be specified as:
future.humanize(present, granularity=["minute","second"])
Output: ‘in 4320 minutes and 0 seconds’
- Get the span of any time unit
arw.now().span(‘minute’)
Output:
(<Arrow [2021-03-16T12:58:00+00:00]>, <Arrow [2021-03-16T12:58:59.999999+00:00]>)
arw.now().span('day') #get the span of time for a whole day
Output:
(<Arrow [2021-03-16T00:00:00+00:00]>, <Arrow [2021-03-16T23:59:59.999999+00:00]>)
- Get floor and ceiling values of a specific time component
arw.now().floor('minute')
Output: <Arrow [2021-03-16T13:04:00+00:00]>
arw.now().ceil('minute')
Output: <Arrow [2021-03-16T13:04:59.999999+00:00]>
- Get the range of specified timespans
import datetime begin = datetime.datetime(2020, 6, 5, 2, 30) #start time end = datetime.datetime(2020, 6, 5, 4, 50) #end time for r in arw.Arrow.range('hour', begin, end): #iterate in terms of hour print(r)
We want time from 2:30 to 4:50 at the interval of an hour so output will contain 2:30, 3:30 and 4:30 times.
Output:
2020-06-05T02:30:00+00:00 2020-06-05T03:30:00+00:00 2020-06-05T04:30:00+00:00
- FACTORIES can be used for utilizing Arrow’s module API to create a custom Arrow-derive type.
Suppose, we need to find difference in terms of days between today and the Christmas day. We can define a custom class as:
class Custom(arw.Arrow): #pass an Arrow object def till_christmas(self): #define a function for computation #store christmas day of given year christmas = arw.Arrow(self.year, 12, 25) “”” If given date falls comes after Christmas of that year, compute its difference w.r.t. Christmas of the next year “”” if self > christmas: christmas = christmas.shift(years=1) return (christmas - self).days #return the difference
f = arw.ArrowFactory(Custom) #Create a factory x = f.now() #current date and time
Suppose, x is <Custom [2021-03-16T13:21:09.741500+00:00]>
Call the till_christmas() method to compute the difference
x.till_christmas()
Output: 283
i.e. Christmas of the year 2021 is 283 days away from 16 March 2021.