GithubHelp home page GithubHelp logo

arrow-py / arrow Goto Github PK

View Code? Open in Web Editor NEW
8.6K 134.0 661.0 2.3 MB

🏹 Better dates & times for Python

Home Page: https://arrow.readthedocs.io

License: Apache License 2.0

Makefile 0.17% Python 99.83%
python arrow datetime date time timestamp timezones hacktoberfest

arrow's Introduction

Arrow: Better dates & times for Python

Build Status

Coverage

PyPI Version

Supported Python Versions

License

Code Style: Black

Arrow is a Python library that offers a sensible and 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 providing 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 named after the arrow of time and is heavily inspired by moment.js and requests.

Why use Arrow over built-in modules?

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, timespans, humanization

Features

  • Fully-implemented, drop-in replacement for datetime
  • Support for Python 3.6+
  • Timezone-aware and UTC by default
  • Super-simple creation options for many common input scenarios
  • shift method with support for relative offsets, including weeks
  • Format and parse strings automatically
  • Wide support for the ISO 8601 standard
  • Timezone conversion
  • Support for dateutil, pytz, and ZoneInfo tzinfo objects
  • Generates time spans, ranges, floors and ceilings for time frames ranging from microsecond to year
  • Humanize dates and times with a growing list of contributed locales
  • Extensible for your own Arrow-derived types
  • Full support for PEP 484-style type hints

Quick Start

Installation

To install Arrow, use pip or pipenv:

$ pip install -U arrow

Example Usage

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

>>> 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]>

>>> local.timestamp()
1368303838.970460

>>> 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')
'한시간 전'

Documentation

For full documentation, please visit arrow.readthedocs.io.

Contributing

Contributions are welcome for both code and localizations (adding and updating locales). Begin by gaining familiarity with the Arrow library and its features. Then, jump into contributing:

  1. Find an issue or feature to tackle on the issue tracker. Issues marked with the "good first issue" label may be a great place to start!
  2. Fork this repository on GitHub and begin making changes in a branch.
  3. Add a few tests to ensure that the bug was fixed or the feature works as expected.
  4. Run the entire test suite and linting checks by running one of the following commands: tox && tox -e lint,docs (if you have tox installed) OR make build39 && make test && make lint (if you do not have Python 3.9 installed, replace build39 with the latest Python version on your system).
  5. Submit a pull request and await feedback 😃.

If you have any questions along the way, feel free to ask them here.

Support Arrow

Open Collective is an online funding platform that provides tools to raise money and share your finances with full transparency. It is the platform of choice for individuals and companies to make one-time or recurring donations directly to the project. If you are interested in making a financial contribution, please visit the Arrow collective.

arrow's People

Contributors

andrewchouman avatar andrewelkins avatar anishnya avatar ankurdedania avatar beucismis avatar chingyi-ax avatar chrishaines avatar cleg avatar crsmithdev avatar cryogenic-ric avatar cyriaka90 avatar elahehax avatar eumiro avatar gruebel avatar hwillard98 avatar jadchaar avatar jbkahn avatar kkoziara avatar krisfremen avatar mhworth avatar pypingou avatar ramonsaraiva avatar rgbongocan avatar satiani avatar sipp11 avatar syeberman avatar systemcatch avatar tirkarthi avatar zakhar avatar zcribe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arrow's Issues

Parse ISO 8601 basic format (hhmmss)

At the moment being, arrow.get ignores the seconds if the datetime is in the basic format (hhmmss) and not in the extended format (hh:mm:ss) (see wikipedia article for more info)

In [1]: arrow.get('19980119T070100')
Out[1]: <Arrow [1998-01-19T07:01:00+00:00]>

In [2]: arrow.get('19980119T070101') # added 1 sec but output is the same
Out[2]: <Arrow [1998-01-19T07:01:00+00:00]>

If I add microseconds, output is correct

In [3]: arrow.get('19980119T070101.0')
Out[3]: <Arrow [1998-01-19T07:01:01+00:00]>

A part of the problem looks like the has_seconds detection in arrow/parser.py:70 is wrong. (Sould check len(time_parts[0]) if no : were found)

If it's ok with you i'll send a pull request in the next few days fixing the detection, the parsing (i didn't check i it need to be fixed as well) and adding new tests.

Edit : After a rapid test it looks like adding has_seconds = not has_seconds and len(time_parts[0]) == 6 after line 70 fixes the problem. (But i still will investigate futher and write some tests)

Allow arrow.get() to take an arrow.

Using arrow is usually interweaved with using the built in datetime objects. (At least, database-driven models expect the original (often naive) datetimes or dates for storage.)

To avoid code like this:

try:
    recurrence['startTime'] = start_on.timestamp
except:
    recurrence['startTime'] = arrow.get(start_on).timestamp

or nasty isinstance checks, I propose the following to be allowed/ensured:

n = arrow.utcnow()
assert arrow.get(n) == n

Bad parse in arrow.get()

In [233]: arrow.get("1403549231", "YYYY-MM-DD")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-233-0755ee98cfcb> in <module>()
----> 1 arrow.get("1403549231", "YYYY-MM-DD")

/usr/local/lib/python2.7/dist-packages/arrow/api.pyc in get(*args, **kwargs)
     21     '''
     22 
---> 23     return _factory.get(*args, **kwargs)
     24 
     25 def utcnow():

/usr/local/lib/python2.7/dist-packages/arrow/factory.pyc in get(self, *args, **kwargs)
    182             # (str, format) -> parse.
    183             elif isstr(arg_1) and (isstr(arg_2) or isinstance(arg_2, list)):
--> 184                 dt = parser.DateTimeParser(locale).parse(args[0], args[1])
    185                 return self.type.fromdatetime(dt)
    186 

/usr/local/lib/python2.7/dist-packages/arrow/parser.pyc in parse(self, string, fmt)
    124                 raise ParserError('Failed to match token \'{0}\''.format(token))
    125 
--> 126         return self._build_datetime(parts)
    127 
    128     def _parse_token(self, token, value, parts):

/usr/local/lib/python2.7/dist-packages/arrow/parser.pyc in _build_datetime(cls, parts)
    195             day=parts.get('day', 1), hour=hour, minute=parts.get('minute', 0),
    196             second=parts.get('second', 0), microsecond=parts.get('microsecond', 0),
--> 197             tzinfo=parts.get('tzinfo'))
    198 
    199     def _parse_multiformat(self, string, formats):

ValueError: month must be in 1..12

Seems like this should fail with arrow.parser.ParserError instead. Reason being, I'd like to catch a ParserError if that ('YYYY-MM-DD') token is used, whereas the 'X' (e.g. arrow.get("1403549231", "X")) works fine.

Allow replacing the weekday too.

dateutil.relativedelta allows searching for the next monday or previous tuesday, and so on:

from dateutil.relativedelta import relativedelta, MO
n = arrow.utcnow()
n
>>> <Arrow [2013-10-22T10:19:37.595000+00:00]>
n + relativedelta(weekday=MO(+1))
>>> <Arrow [2013-10-28T10:19:37.595000+00:00]>
n + relativedelta(weekday=MO(-1))
>>> <Arrow [2013-10-21T10:19:37.595000+00:00]>

Actually, no need to cut the features of the dateutil you're using anyway.

Opinions?

arrow has no __version__ attribute

When you want to communicate the lib version to somebody else (such as in a gitub issue), it is a commun pattern to open an python shell, and do :

>>> import arrow
>>> arrow.__version__
2.4.1

But arrow lacks such a thing.

Cannot parse full microseconds.

The .isoformat() method outputs a format following the patterm YYYY-MM-DDTHH:mm:ss.SSSSSSZ. However, the parser only allows a resolution as high as milliseconds, so the parser can only handle up to YYYY-MM-DDTHH:mm:ss.SSSZ. (See code at https://github.com/crsmithdev/arrow/blob/master/arrow/parser.py#L85). This means that the parser cannot parse its own ISO output format. This can quickly be handled by accounting for 'S' strings of length 1 through 6 and adding this to the _FORMAT_RE regex. I can make this change and submit a pull request if you'd like.

humanize() has some kind of overflow error

Hi,

I wanted to contribute a German locale and while testing funny stuff happened:

In [25]: arrow.now().replace(months=-7).humanize()
Out[25]: '5 months ago'

Going back further decreases the output. Sorry for not having time to debug it properly.

FR: Implement context manager to mock time.

I just stumbled upon dmc, a different library for handling dates and times in Python. With this library you are able to mock the current time. It could be like this:

with arrow.mock('2013-05-11T21:23:58.970460+00:00'):
    assert arrow.now() == arrow.get('2013-05-11T21:23:58.970460+00:00')

This feature would be very useful for unit testing methods which use arrow.now() or a related method.

Add support for "week" as a valid 'frame' option

Currently methods that require a frame only accept one of:

['year', 'month', 'day', 'hour', 'minute', 'second', 'microsecond']

It would be very useful to have 'week' as an additional option.

Of course this would have to take into account that a week starts on different days in different countries.

Arrow seems to lose the timezone when calculating ranges

>>> import arrow
>>> 
>>> today = arrow.now().replace(minute=0, second=0, microsecond=0)
>>> daystart = today.replace(hour=7)
>>> dayend = today.replace(hour=18)
>>> 
>>> print today, daystart, dayend
2013-06-13T16:00:00-04:00 2013-06-13T07:00:00-04:00 2013-06-13T18:00:00-04:00
>>> 
>>> print filter(lambda d: d.minute % 30 is 0, arrow.Arrow.range('minute', daystart, end=dayend))
[<Arrow [2013-06-13T07:00:00+00:00]>, <Arrow [2013-06-13T07:30:00+00:00]>, <Arrow [2013-06-13T08:00:00+00:00]>, <Arrow [2013-06-13T08:30:00+00:00]>, <Arrow [2013-06-13T09:00:00+00:00]>, <Arrow [2013-06-13T09:30:00+00:00]>, <Arrow [2013-06-13T10:00:00+00:00]>, <Arrow [2013-06-13T10:30:00+00:00]>, <Arrow [2013-06-13T11:00:00+00:00]>, <Arrow [2013-06-13T11:30:00+00:00]>, <Arrow [2013-06-13T12:00:00+00:00]>, <Arrow [2013-06-13T12:30:00+00:00]>, <Arrow [2013-06-13T13:00:00+00:00]>, <Arrow [2013-06-13T13:30:00+00:00]>, <Arrow [2013-06-13T14:00:00+00:00]>, <Arrow [2013-06-13T14:30:00+00:00]>, <Arrow [2013-06-13T15:00:00+00:00]>, <Arrow [2013-06-13T15:30:00+00:00]>, <Arrow [2013-06-13T16:00:00+00:00]>, <Arrow [2013-06-13T16:30:00+00:00]>, <Arrow [2013-06-13T17:00:00+00:00]>, <Arrow [2013-06-13T17:30:00+00:00]>, <Arrow [2013-06-13T18:00:00+00:00]>]

Fractional seconds not presented correctly

It appears that fractional seconds are being treated as milliseconds, which is not what they are.

There also seems to be a difference in how fractional seconds are shown in Arrow class representation (incorrect) and with using a format string.

The Arrow class representation treats fractional seconds as 'number of microseconds.'

Problems with representation:

200 milliseconds represented as 2 microseconds

arrow.get('2013-05-05T12:30:45.2+0030')
<Arrow [2013-05-05T12:30:45.000002+00:30]>

2 milliseconds represented as 2 microseconds

arrow.get('2013-05-05T12:30:45.002+0030')
<Arrow [2013-05-05T12:30:45.000002+00:30]>

Problems with format:
Each of the examples of displaying 2 milliseconds is incorrect.

arrow.get('2013-05-05T12:30:45.002+0030').format('YYYY-MM-DD HH:mm:ss.SSS ZZ')
'2013-05-05 12:30:45.0 +00:30'

arrow.get('2013-05-05T12:30:45.002+0030').format('YYYY-MM-DD HH:mm:ss.SSSSS ZZ')
'2013-05-05 12:30:45.0 +00:30'

arrow.get('2013-05-05T12:30:45.002+0030').format('YYYY-MM-DD HH:mm:ss.SSSSSS ZZ')
'2013-05-05 12:30:45.2 +00:30'

arrow.get('2013-05-05T12:30:45.002+0030').format('YYYY-MM-DD HH:mm:ss.SSSSSSS ZZ')
'2013-05-05 12:30:45.20 +00:30'

support for PEP 396 Module Version

when I try:

arrow.version

results in:

Traceback (most recent call last):

File "", line 1, in
arrow.version

AttributeError: 'module' object has no attribute 'version'


pkg_resources yields a result, but the guidance in PEP 396 seems a good path.

pkg_resources.get_distribution("arrow").version

'0.4.2'

Thx for review! Great package!!!! Super work!

TAI64

It would be great if Arrow would support to convert from and to TAI64. It’s used a lot in log files and I’d prefer to use only one format.

Make Arrow object a transparent replacement for datetime object

lots of third party code rely on datetime.datetime type object. (like pymongo, etc)
It's better that arrow provides a way to make Arrow object a transparent replacement for the datetime object.

2 ways in my mind:

  1. make class Arrow a subclass of datetime, so that it could be used where datetime instance required
  2. export interface to converting an Arrow instance to a datetime instance

First way is prefered, however if it is not feasible, it's better to provide the 2nd option.

Make running tests easy, e.g. by tox

Attempting to create Czech locale, I was happy to find test suite in place.

However, running the test suite is difficult (and I did not get through).

Reasons making running tests difficult

using make

Testing seems to be run by

$ make test

However, `make is not always available.

Unspoken assumptions

The test in Makefile assumes, there is virtualenv in local/bin subdirectory.

Difficulties to import chai

$ nosetest tests

is failing with errors like:

======================================================================
ERROR: Failure: ImportError (No module named chai)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/nose/loader.py", line 413, in loadTestsFromName
    addr.filename, addr.module)
  File "/usr/local/lib/python2.7/dist-packages/nose/importer.py", line 47, in importFromPath
    return self.importFromDir(dir_path, fqname)
  File "/usr/local/lib/python2.7/dist-packages/nose/importer.py", line 94, in importFromDir
    mod = load_module(part_fqname, fh, filename, desc)
  File "/home/javl/sandbox/arrow/arrow/tests/util_tests.py", line 3, in <module>
    from chai import Chai
ImportError: No module named chai

----------------------------------------------------------------------
Ran 7 tests in 0.002s

Even manually installing chai did not help, the error above appears even when chai is installed:

$ pip freeze|grep chai
chai==0.4.8

Proposal: use tox

tox is written in Pyhton

No need to have make installed.

Allows using nose

tox is not forcing any testing tool, using command nosetests is natural.

Installs test dependencies

tox allows specifying, what modules are required for testing. Here it would be chai, nose and
may be few more.

Manges testing under various python versions

tox makes running tests under different python versions easy. All the tests are performed in virtualenv, no need to care about setting it up.

In case such a change sounds acceptable, I would try to modify existing framework for this, trying to preserve as much of existing test suite unchanged.

Add/use git tags for release versions

I'd like to create a FreeBSD port for arrow. The ports framework can fetch source distributions via the GitHub tarball generator for specific branches and revisions when git tags are used. Ideally, the tags are a bare x.y.z convention without a 'v' prefix or otherwise.

Thanks :)

0.4.2 tag?

The tag for 0.4.2 seems to be missing from git.

I was checking when the line recursive-include tests * has been added in the MANIFEST.in file as the tests do not seem to be included in the 0.4.2 release but I don't know which commit is the 0.4.2 :)

Btw, the tests seem to be failing atm.

Accurate handling of parsing errors

Arrow can silently fail to parse complete date string and return invalid result when date string partially matches one of formats.

Consider parsing SQLite date-time string:

>>> arrow.get('2014-01-25 01:22:58')
<Arrow [2014-01-25T00:00:00+00:00]>

Note that time part of date not parsed and were silently lost.

Or parsing even not date-time sting:

>>> arrow.get("Happy 2014!")
<Arrow [2014-01-01T00:00:00+00:00]>

Support for Julian day conversion into Arrow

Potentially a tricky implementation, but could be valuable for scientific usage

https://en.wikipedia.org/wiki/Julian_day

Suggested possible usage:

note 735017 = 21:00, 29 May 2013

Arrow.get(2456442.37553, julian=True, epoch=Arrow.get(datetime.datetime(1, 1, 1, 0, 0, 0)))

Possible issues, roadblocks:

note 2456442.37553 = 21:00, 29 May 2013

Arrow.get(2456442.37553, julian=True, epoch='?') #what would be an appropriate way to handle 12h Jan 1, 4713 BC

locale argument not respected for month names in arrow.get

Actual behavior:

>>> arrow.get('16/Okt/13 6:53 PM', 'DD/MMM/YY H:mm A', locale='de_de')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/ask/.virtualenvs/uniencoder/lib/python2.7/site-packages/arrow/api.py", line 23, in get
    return _factory.get(*args, **kwargs)
  File "/home/ask/.virtualenvs/uniencoder/lib/python2.7/site-packages/arrow/factory.py", line 154, in get
    dt = parser.DateTimeParser(locale).parse(args[0], args[1])
  File "/home/ask/.virtualenvs/uniencoder/lib/python2.7/site-packages/arrow/parser.py", line 122, in parse
    raise ParserError('Failed to match token \'{0}\''.format(token))
arrow.parser.ParserError: Failed to match token 'MMM'

Expected behavior:

>>> arrow.get('16/Okt/13 6:53 PM', 'DD/MMM/YY H:mm A', locale='de_DE')
<Arrow [2013-10-16T18:53:00+00:00]>
>>> 

Unfortunately I'm forced to work with this kind of broken date and time representation (which absolutely makes no sense). However, this shows that arrow is prone to current global locale settings and changes its behavior according to global locales instead of the given locale option.

Wrong result when a shift involves a DST change.

In paris in 2013, we changed to DST in 2013-03-31 (at 2 AM it was 3 AM), from UTC+1 to UTC+2 (DST)

Here's an example of the issue I have with arrow :

>>> import arrow, datetime

>>> just_before = arrow.get(datetime.datetime(2013, 03, 31, 1, 50, 45), "Europe/Paris").ceil("hour")
>>> just_before
<Arrow [2013-03-31T01:59:59.999999+01:00]>

>>> just_after = just_before.replace(microseconds=+1)
>>> just_after
<Arrow [2013-03-31T02:00:00+02:00]>
>>> # That is not right... It should be either 2 AM UTC+1 or preferably  3AM UTC +2
>>> # One could argue that depending on what you ask for, it may be the correct answer, but then the following is :

>>> (just_after - just_before).total_seconds()
1e-06
>>> # That is right but not consistent with the dates

>>> (just_after.to("utc") - just_before.to("utc").total_seconds()
-3599.999999
# That should be the same value as the previous computation. Plus, the value is negative because :

>>> just_before.to('utc'), just_after.to('utc')
(<Arrow [2013-03-31T00:59:59.999999+00:00]>,
 <Arrow [2013-03-31T00:00:00+00:00]>)

I think the problem is pretty clear...

Coarse-grained humanize()

I've a cron script that updates an HTML page once a day. I'd like to avoid timestamps like "5 minutes ago" on that page. Coarser approximations like "Today" or "5 days ago" would work fine for this use case.

I suggest a new granularity argument for the humanize() method, e.g.:

>>> t = arrow.utcnown().replace(minutes=-5)
>>> t.humanize(granularity='now') # default if you omit granularity
'5 minutes ago'
>>> t.humanize(granularity='minutes')
'5 minutes ago'
>>> t.humanize(granularity='hours')
'this hour'
>>> t.humanize(granularity='days')
'today'
>>> t.humanize(granularity='months')
'this month'
>>> t.humanize(granularity='years')
'this year'

If the difference between the reference point and the timestamp is less than the specified granularity, it would return a fixed string, otherwise it would do what it already does today.

Special-casing 'yesterday' and 'tomorrow' instead of ('1 day ago' and 'in 1 day') would be nice as well. Maybe 'last/next month/year' too.

Is there an easy way to get timestamp with microsecond from an arrow object, result like time.time()?

I would like to do convertion between timestamp and arrow/datetime:

  1. timestamp with microsecond ==> arrow or datetime
  2. arrow or datetime ==> timestamp with microsecond

1 has an easy way, but 2 I am frustrated to find one. time.mktime(datetime.timetuple()) does not work because timetuple() discards the microsecond portion. Does arrow already have a method to do this convertion or I miss something?

thanks.

Format code for microseconds

I am looking to generate a timestamp string like
XXXXXXXXXX.XXXXXX

However, I can only use the format code SSS to get millseconds.

ie x.format("X.SSS")

Could a format code for microseconds be added ?

Add suport for quarters in span/span_range

It would be great addition to the arrow. I thought of making a pull request with necessary changes, but it seems that the code the adds weeks to available frames is a bit tricky so I decided just to create an issue instead adding additional tricky code. :)

Allow escaping of characters in format()

In French, hours are formatted as "8 h 40" and not as "8:40". But in an arrow's format string, h displays directly the hours. Would it be possible to add a key (such as !) to force h to be displayed normally ("hh !h mm")?

The docs don’t make clear how to parse an ISO-8601 datetime string

I’ve been perusing the docs for 10 minutes now trying to figure this out. I’d think it’s a common-enough use case that it should have an example in the docs.

It seems I should use arrow.get(datetime_string, pattern_string) but I don’t know what syntax to use for the pattern, and the docs don’t say what syntax is used so I can’t look it up.

So, some suggestions:

  1. add an example of parsing an ISO-8601 datetime string (with an offset)
  2. add a link to the docs for the pattern syntax
  3. add a module containing some “constants” with common datetime pattern strings

arrow.get() with two strings should support an optional tzinfo

It would be great when you have a time stamp if could specify which tz it is in, even if the ts itself does not contain the information, such as local vs always forcing utc:
For instance something like this:

arrow.get('2014/02/05 09:23:44', 'YYYY/MM/DD HH:mm:ss', tzinfo=tz.tzlocal())

where the get factory would support something like:

        **Three** arguments, both ``str``, to parse the first according to the format of the second and the third is an optional tzinfo, defaulting to UTC::

strftime locale

Add an optional locale keyword argument to arrow.Arrow.strftime, so it will function similarly to arrow.Arrow.format.

arrows aren't pickable.

Unfortunately arrow objects aren't pickable, or to be specific unpickable

pickle.loads(pickle.dumps(arrow.utcnow()))
    299             return self.isocalendar()[1]
    300
--> 301         value = getattr(self._datetime, name, None)
    302
    303         if value is not None:

RuntimeError: maximum recursion depth exceeded while calling a Python object

How to get more from arrow?

Hi! First of all, I would like to say that arrow is very well done and suits very well for almost everything a programmer wants. The only step back in arrow, IMHO (or to my necessity), is the "factory" design for getting an instance of the Arrow class. Why? I just want to extend Arrow's class to add some of methods I often use in datetime conversions / comparison :) If I choose to inherit Arrow, I would have to duplicate everything from "api" OR monkey patch it - which I don't like at all. Any ideas on how to circumvent this? Maybe a register method in the "api" for Arrow' subclasses? I can help with that, if possible :)

Best regards,
Richard.

Properties convention consistency?

In the doc a.datetime and a.timestamp do not require to be a callable, whereas date and time do.

I think for friendliness, we either use all a callable or attribute-style decorate with @property.

Any rationale why that's there is an inconsistency? If I may suggest, I think they should be callable.

But .year, .hour can still be an attribute, although I may be biting my own comment right now suggesting consistency. Maybe we should make them all callable since we really are getting stuff back from some other representation rather than a simple attribute setting. The argument for .year though is that it's not as complex as returning a whole datetime object.

Make get() accept a timezone as a keyword argument

This doesn't work :

arrow.get('2013-05-05 12:30:45', '%Y-%m-%d %H:%M:%S', 'Paris/Europe')

But at least you could make this work :

arrow.get('2013-05-05 12:30:45', '%Y-%m-%d %H:%M:%S', tzinfo= 'Paris/Europe)

This is way easier and more intuitive than :

arrow.Arrow.strptime('2013-05-05 12:30:45', '%Y-%m-%d %H:%M:%S', tz.gettz('Paris/Europe'))

And making dates easy are the purpose of this (wonderful) lib.
<Arrow [2013-05-05T12:30:45+00:00]>

RFC 822 date parsing

Email's date times, as defined by RFC 822, are not properly parsed by Arrow factory:

>>> from email.Utils import formatdate
>>> formatdate()
'Wed, 28 May 2014 13:46:24 -0000'
>>>
>>> import arrow
>>> arrow.get(formatdate())
<Arrow [2014-01-01T00:00:00+00:00]>
>>> 

time zone conversions fail

It works only with the latest timezone for the region. DST transitions, other timezone changes are not handled correctly. Examples:

  • round-trip convert timestamp -> named timezone -> utc
    expected 2002-10-27 05:30:00.000000 UTC+0000
    got        10/27/02 06:30:00.0 +00:00 (UTC)

** convert utc datetime -> named timezone

expected 2002-10-27 01:30:00.000000 EDT-0400
got        10/27/02 01:30:00.0 -05:00 (EST)
  • convert utc to local timezone
    expected 2010-06-06 21:29:07.730000 MSD+0400
    got        06/06/10 21:29:07.730000 +04:00 (MSK)
    expected 2010-12-06 20:29:07.730000 MSK+0300
    got        12/06/10 20:29:07.730000 +04:00 (MSK)
  • date & time in named time zone
    expected 2002-10-27 00:30:00.000000 EDT-0400
    got        10/27/02 00:30:00.0 -05:00 (EST)
  • ambiguous: naive datetime to named timezone - no disambiguation
  • non-existing times
  • time zones in a distant past
    expected 1915-08-04 22:59:59.000000 WMT+0124
    got        08/04/15 22:59:59.0 +01:00 (CET)
    expected 1933-05-15 01:30:00.000000 AMT+0020
    got        05/15/33 01:30:00.0 +01:00 (CET)
    expected 1933-05-15 03:30:00.000000 NST+0120
    got        05/15/33 03:30:00.0 +01:00 (CET)

Examples are from http://pytz.sourceforge.net/

The code to produce the above output https://gist.github.com/4127162

Note: not all of it probably should be fixed but it is useful to be aware that the issues exist.

FR: Implement context manager to mock time.

I just stumbled upon dmc, a different library for handling dates and times in Python. With this library you are able to mock the current time. It could be like this:

with arrow.mock('2013-05-11T21:23:58.970460+00:00'):
    assert arrow.now() == arrow.get('2013-05-11T21:23:58.970460+00:00')

This feature would be very useful for unit testing methods which use arrow.now() or a related method.

ISO 8601 date and time parsing with space as a separator

Hi,

Would it be possible to include native support of an ISO 8601 formatted date that does not contain T as a separator between date and time but uses space.

A lot of logs contain date and time in ISO 8601 format but they don't contain the T field. When I try to parse those values, the time gets omitted.

Example:

arrow.get('2013-11-10 18:22:11')
<Arrow [2013-11-10T00:00:00+00:00]>

arrow.get('2013-11-10 18:22:11+11:00')
<Arrow [2013-11-10T00:00:00+00:00]>

arrow.get('2013-11-10T18:22:11+11:00')
<Arrow [2013-11-10T18:22:11+11:00]>

I can use a format string to parse data (arrow.get('2013-05-05 12:30:45', 'YYYY-MM-DD HH:mm:ss') but it feels like the parser should be able to deal with this type of data without needing a format specification.

Also, it would be good if we could specify the time zone as a second parameter. Assuming UTC would be valid for a default assumption.

http://stackoverflow.com/questions/9531524/in-an-iso-8601-date-is-the-t-character-mandatory

Provide some pre made formats :

This is nice :

>>> print(a.format('DD, MMMM', locale='fr_FR'))
15, Octobre

But some standard formats such as :

>>> print(a.format(arrow.SHORT_DATE, locale='fr_FR'))
15, Octobre 1995
>>> print(a.format(arrow.SHORT_DATE, locale='us_US))
Octobre 1995, the 15

Would be nice. My example is not the best, but there are a couple of standard date formats that you keep using (long date format, formal date format, YYYY-MM-DD date format), so let's embed them in some way !

How can I do a operation like `local.humanize` contrary?

local.humanize() can format a timestmap to human words like:

past = arrow.utcnow().replace(hours=-1)
past.humanize()
# 'an hour ago'

but how can I get a timestamp if I know it far away from now an hour ago?
how can I do if I can else can add this function ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.