# dateparser: parsing human-readable dates in Python

> dateparser turns strings like 'In two months' or '13 января 2015 г. в 13:34' into Python datetime objects, with autodetection across more than 200 locales. It is a good fit when the input format is unknown; it is the wrong tool when you need a strict, reproducible format contract.

**scrapinghub/dateparser** — python parser for human readable dates

- Repository: https://github.com/scrapinghub/dateparser
- Website: https://dateparser.readthedocs.org/en/latest/
- Stars: 2,861 · Forks: 523
- Language: Python
- License: BSD-3-Clause
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/scrapinghub-dateparser

## The problem: dates that arrive as text, not as timestamps

Most parsing code assumes the producer and the consumer agreed on a format. In practice they did not. A crawl returns 'Fri, 12 Dec 2014 10:55:50' on one page and '2 hours ago' on the next. A support export writes 'Martes 21 de Octubre de 2014'. A log line carries 'January 12, 2012 10:00 PM EST'. The moment you have to handle more than one of these shapes, a single strptime format string stops working, and you end up maintaining a list of formats plus a fallback for the ones that do not match.

dateparser is aimed exactly at that gap. Its description in pyproject.toml is 'Date parsing library designed to parse dates from HTML pages', which is a fair statement of the origin: the project comes from Scrapinghub (the package metadata lists opensource@zyte.com) and the use case is scraped content, where the format is whatever the site happened to emit. The README lists absolute dates, relative dates, timestamps, more than 200 language locales, language autodetection, timezone abbreviations and UTC offsets, and non-Gregorian calendars as the supported surface.

The audience is therefore narrow and specific: Python developers who receive date strings they did not generate. If you generate the strings yourself, this library is more machinery than you need.

## How dateparser decides what a string means

The public entry point is dateparser.parse(), which the README describes as wrapping around most of the module's functionality. The return value is a datetime.datetime, and the failure value is None: every example in the README shows a datetime, and the library does not raise on input it cannot interpret. That single design decision shapes how you write the calling code, and it is discussed further below.

Two mechanisms are visible in the README. The first is language selection. When you pass languages=['pt', 'es'], the README states that 'given languages are used and language detection is skipped'. Without that argument, the library detects the language itself, which is why '02-03-2016' and 'le 02-03-2016' resolve differently: the second string is detected as French and read as DMY, the first is assumed English and read as MDY. The README is explicit that this ordering is not locale-based and warns against expecting DMY for UK or Australian English.

The second is settings, a dictionary passed per call. The README shows three settings in use: DATE_ORDER to force 'DMY', SKIP_TOKENS set to an empty list for Finnish relative dates, and the languages and date_formats arguments that sit alongside it. Settings are per call rather than global, so two call sites can disagree about date order without interfering with each other.

The dependency list in pyproject.toml shows the machinery underneath: python-dateutil for the actual date arithmetic, pytz and tzlocal for timezones, and regex instead of the standard re module. Two optional extras exist. calendars pulls in convertdate and hijridate for the non-Gregorian calendar support, and langdetect pulls in langdetect for language detection. Neither is installed by default, which means the 200-locale claim and the calendar claim depend on extras you have to request.

## Installing dateparser and parsing your first string

The package installs from PyPI. The project metadata declares requires-python >=3.10 and classifies Python 3.10 through 3.14, so check your interpreter before anything else.

```bash
pip install dateparser
```

After that, the shortest useful program is a single call. The README's first example is reproduced here exactly:

```python
>>> import dateparser

>>> dateparser.parse('Fri, 12 Dec 2014 10:55:50')
datetime.datetime(2014, 12, 12, 10, 55, 50)

>>> dateparser.parse('1991-05-17')
datetime.datetime(1991, 5, 17, 0, 0)
```

What you should see is a datetime object, not a string. If the input cannot be interpreted, the call returns None, so a first real use should branch on that rather than assume success.

Relative expressions depend on the current clock, and the README notes that testing its examples may return different values depending on your environment's date and time. The same applies to timestamps:

```python
>>> dateparser.parse('In two months')  # today is 1st Aug 2020
datetime.datetime(2020, 10, 1, 11, 12, 27, 764201)

>>> dateparser.parse('1484823450')  # timestamp
datetime.datetime(2017, 1, 19, 10, 57, 30)
```

When the input language is known, pass it and skip detection. When the format is known, pass date_formats. Both come straight from the README:

```python
>>> dateparser.parse('2015, Ago 15, 1:08 pm', languages=['pt', 'es'])
datetime.datetime(2015, 8, 15, 13, 8)

>>> dateparser.parse('22 Décembre 2010', date_formats=['%d %B %Y'])
datetime.datetime(2010, 12, 22, 0, 0)
```

And when the ambiguity is numeric, force the order instead of trusting the default:

```python
>>> parse('18-12-15 06:00', settings={'DATE_ORDER': 'DMY'})
datetime.datetime(2015, 12, 18, 6, 0)
```

The pyproject.toml also registers a console script, dateparser-download, pointing at dateparser_cli.cli:entrance. That entry point exists for fetching the language data the parser uses; the README does not document its flags, so check the CLI module or the docs before relying on it in a build step.

## Where dateparser gets it wrong, and when it is the wrong tool

The most consequential behaviour is the None return. A typo in a format, an unexpected language, or a string that is simply not a date all produce the same result: None. There is no exception to catch, so a pipeline that forgets the check will silently write nulls into a timestamp column. The README does not document a strict mode or an exception-raising variant, and it does not document rollback or error-handling behaviour beyond the examples returning datetimes. Treat the None check as mandatory.

The second limitation is date order. The README states plainly that ordering is not locale-based and that DMY should not be expected for UK or Australian English. If your data mixes '02-03-2016' from a British source and from an American source, the library cannot tell them apart from the string alone, because both are valid under both orders. You have to supply DATE_ORDER per call, which means you have to know the provenance of each string. That is a data problem the library cannot solve for you.

The third is the optional extras. Non-Gregorian calendars and langdetect-based detection are behind the calendars and langdetect extras. Installing plain dateparser gives you the default detection path, and the README does not describe what that default path uses in place of langdetect.

Finally, the language-specific caveat for Finnish is a reminder that relative-date parsing is not uniform across the 200 locales: the README instructs Finnish users to pass settings={'SKIP_TOKENS': []}, which means the default token handling interferes with Finnish relative expressions. Expect similar edge cases elsewhere; the supported-locales page is the place to check coverage before committing to a locale.

## dateparser versus dateutil and strptime

The obvious alternative is python-dateutil, which dateparser already depends on. The difference is scope. dateutil.parser.parse is built for strings that look like ISO 8601 or RFC-style dates; it is fast and predictable for that shape, and it raises on input it cannot handle. It does not understand 'In two months', it does not autodetect language, and it does not carry a locale table.

dateparser adds a layer above exactly that: language detection, a locale table covering more than 200 languages, relative-expression handling, and a settings dictionary for date order and token skipping. The cost of that layer is weight and ambiguity. You pull in regex and pytz, and you accept that the same string can resolve differently depending on the detected language, which is the behaviour shown by the '02-03-2016' example.

A second alternative is Python's own datetime.strptime. It is the right answer when you have one known format and want a hard failure when the input deviates. strptime raises ValueError; dateparser returns None. If your contract is strict, strptime gives you the signal you want and dateparser hides it.

The practical split: strptime for formats you control, dateutil when the strings are machine-generated and roughly standard, dateparser when the strings are human-written, multilingual, or relative. The repository also lists a fuzzing/ directory, which suggests the parsing surface is treated as untrusted input, a reasonable posture for a library whose job is guessing.

## Maintenance, releases and licence

The repository is not archived. The last push was on 2026-09-23, and the most recent release, v1.4.3, is dated 2026-09-03, with v1.4.2 on 2026-08-04 and v1.4.1 on 2026-06-15. That is a steady cadence over the last several months, and version 1.4.3 matches the version field in pyproject.toml, so the tagged release and the metadata are in sync.

Upgrade cost is low by design. The runtime dependency set is four packages (python-dateutil, pytz, regex, tzlocal), and the two optional extras are separate, so a minor upgrade does not force new installs unless you use calendars or langdetect. The requires-python floor is >=3.10, which is the main thing to watch: if you are still on 3.9, you are outside the declared support range and should not expect fixes for it.

The licence is BSD-3-Clause, declared both in the repository metadata and in pyproject.toml. That is a permissive licence, which generally means you can use the library in closed-source products provided you keep the copyright notice and licence text, but the actual obligations depend on how you distribute your software. Read the LICENSE file and get your own advice; nothing here is legal advice.

## Conclusion

Adopt dateparser when date strings arrive from outside your system and their format is not guaranteed: scraped pages, user input, exported logs. Do not adopt it when you control the format and need strictness, because an unparseable string returns None rather than raising, and ambiguous numeric dates follow language-based defaults. Before rolling it out, verify the DATE_ORDER and languages settings against a sample of your own strings, and check whether your Python version meets the requires-python >=3.10 floor declared in pyproject.toml.

## FAQ

### How can I use Python to parse dates with dateparser?

Import the package and call dateparser.parse() on the string. It returns a datetime.datetime, or None if the string cannot be interpreted, so check the result before using it.

### What is a python dateparser alternative when I only have one known format?

Python's datetime.strptime handles a single known format and raises ValueError when the input deviates. dateparser instead autodetects language and returns None on failure, which is a different contract.

### Which Python versions does dateparser support?

The project metadata declares requires-python >=3.10 and classifies Python 3.10 through 3.14. Older interpreters fall outside the declared support range.

### How do I force day-month-year order in dateparser?

Pass settings={'DATE_ORDER': 'DMY'} to the parse call. The README notes that ordering is not locale-based, so UK or Australian English does not get DMY by default.

### Do I need extra packages for non-Gregorian calendars in dateparser?

Yes. The calendars extra installs convertdate and hijridate, and the langdetect extra installs langdetect. Neither is part of the default install.

## Sources

- [License: BSD-3-Clause](https://github.com/scrapinghub/dateparser/blob/master/LICENSE)
- [Project website](https://dateparser.readthedocs.org/en/latest/)
- [README](https://github.com/scrapinghub/dateparser/blob/master/README.md)
- [Releases](https://github.com/scrapinghub/dateparser/releases)
- [scrapinghub/dateparser on GitHub](https://github.com/scrapinghub/dateparser)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/scrapinghub-dateparser
