Dateparser: a date parsing library for Python

Dateparser turns "3 days ago", "15 Mar 2022" and non-English month names into a Python datetime. What it handles, how to set it, and where it needs help.

Marc Hernandez Cabot

11 min read ·

Dateparser: a date parsing library for Python

Dateparser turns a date written for a person into a datetime written for a program. It reads absolute dates in most formats, relative expressions such as "3 days ago" and "yesterday", timestamps, and month names in more than 200 language locales (project README).

Zyte released Dateparser, an open source library that parses human-readable dates, and in October 2020 we released version 1.0.0, a very important milestone. In this article, I'd like to introduce this library and share some insights into why it's so popular.

Dateparser was developed to make date extraction from HTML pages easier. Initially, it was used only by web scraping developers, but later it was quickly adopted by the wider community as well. It has been used for multiple applications like command-line tools, chatbots, etc.

1pip install dateparser
Copy
1import dateparser
2
3dateparser.parse('15 March 2022')
4dateparser.parse('3 days ago')
5dateparser.parse('Marzo 15, 2022')
Copy

Each of those returns a datetime, or None if the string could not be read as a date.

Zyte wrote it and maintains it. The first release on the Python Package Index was version 0.1.0 on 24 November 2014, version 1.0.0 followed on 29 October 2020, and the current release is 1.4.3, published 3 September 2026 (release history). It is free and open source under the BSD 3-Clause licence, and it supports Python 3.10 and above.

What does Dateparser handle that a hand-written parser does not?

When you are building software, dealing with date strings and parsing them can become very difficult and tedious: it is very hard to foresee all cases and build something that works efficiently. However, you should always look for ways to use existing solutions and avoid reinventing the wheel, and this is where Dateparser comes in handy: Dateparser can convert dates in all sorts of formats and locales to date time objects.

What you find on a page What a format-based parser does What Dateparser returns
15 March 2022 Works, given the right format string A datetime
15/03/2022 Ambiguous. Day 15 of month 3, or month 15? A datetime, using DATE_ORDER or the locale
03/15/2022 The same ambiguity, read the other way A datetime
2022-03-15 Works A datetime
3 days ago No format string matches this A datetime, relative to a base you set
yesterday No format string matches this A datetime
in 2 weeks No format string matches this A future datetime
Marzo 15, 2022 Fails unless you wrote Spanish month handling A datetime
August 14, 2015 EST Needs timezone handling you wrote A datetime, timezone aware
Tue, 15 Mar 2022 10:00:00 +0000 Needs a specific parser A datetime

Rows five to eight are the reason the library exists. Relative expressions and non-English month names are where a format-based approach stops, and both appear wherever a date is written the way a person would say it, such as listings and forums.

It would take a lot of time to create something so powerful from scratch, but instead, all you need to do is import Dateparser and use it.

How do I parse a date string in Python?

Using Dateparser is as simple as importing it and calling the parse() method:

1import dateparser
2
3dateparser.parse('20/11/2021')
Copy

That returns datetime.datetime(2021, 11, 20, 0, 0). If the string cannot be read as a date, it returns None rather than raising, so check the result before using it.

Of course, you can do a lot more than this. But you can start using it without any heavy setup and without reading a lot of documentation.

The same string could be March or April. How do you tell it which?

You cannot resolve 03/04/2022 from the string. Nothing can. Either convention is valid and the string carries no information about which one was used, so the answer has to come from outside it.

Set DATE_ORDER, which "specifies the order in which date components year, month and day are expected while parsing ambiguous dates" (settings reference).

1dateparser.parse(
2    '15/03/2022',
3    settings={
4        'DATE_ORDER': 'DMY',
5        'TIMEZONE': 'UTC',
6        'RETURN_AS_TIMEZONE_AWARE': True,
7    },
8)
Copy

Set it per source, not once for the whole project. A collection that reads a British listing and a United States listing in the same run needs two different values, and a single global setting silently misreads every ambiguous date from one of them.

What happens to "3 days ago" if you parse it a week later?

You get the wrong date, and nothing tells you.

A relative expression means nothing without a reference point. By default the reference is the moment you call parse, which is correct while you are reading the page and wrong the moment you store the raw string and parse it later. RELATIVE_BASE "allows setting the base datetime to use for interpreting partial or relative date strings" (settings reference).

So record the time you fetched the page, on the row, and pass it in.

1dateparser.parse(
2    '3 days ago',
3    settings={'RELATIVE_BASE': fetched_at},
4)
Copy

A wrong reference point is invisible in the output. Every value is still a plausible date, measured from the wrong moment.

Which settings do you actually need?

Even if the interface is really simple, you can handle a lot of nuances by using the settings. You can pick a reference date, select the preferred date order, adjust the timezone configuration, decide how to handle incomplete dates, etc.

Setting What it decides When you need it
DATE_ORDER How to read an ambiguous numeric date Any source that publishes dd/mm or mm/dd
RELATIVE_BASE The moment "3 days ago" is counted from Any source with relative dates, and any parsing done after the fetch
TIMEZONE The timezone used to localise the result Any source that publishes local times without an offset
TO_TIMEZONE The timezone to convert the result into When you normalise everything to one zone on the way in
RETURN_AS_TIMEZONE_AWARE Whether to return an aware datetime when the string carries zone information Almost always, if you store the result
PREFER_DATES_FROM Whether an incomplete date resolves into the past or the future Event listings, where an ambiguous date is usually upcoming
STRICT_PARSING Return nothing if day, month or year is missing When a partial date is worse than no date
REQUIRE_PARTS Which components must be present for a result to be returned When you need a full date and a bare year would corrupt the field

The full list is in the settings reference.

Is there something you want to achieve? Take a look at the settings and you will probably find what you were looking for.

Where does Dateparser need help?

The library is free, and this page is written by the people who maintain it. Here is where it needs help.

Ambiguous numeric dates need a hint from you. Covered above. No parser resolves this on its own.

Timezones need a decision, not a default. A date with no zone is not a moment. Decide whether you are storing local time or normalising to one zone, and do it at collection, because reconciling a mixed column afterwards means re-reading every source to find out what each value meant.

Relative dates need a fetch time recorded. Also covered above, and it costs one column.

Speed. Trying many formats and locales is not free. Where you know a source's exact format and it does not vary, parsing it directly is faster. Use Dateparser for the sources whose format you cannot predict.

Language autodetection is a guess. If you know the source's language, pass it, rather than letting the library work it out for every string.

How do you use it inside a scraper?

Prefer a machine-readable date when the page publishes one. The HTML specification says the time element "represents its contents, along with a machine-readable form of those contents in the datetime attribute", and that the attribute's value must match a defined syntax such as 2011-11-18 (HTML Living Standard, the time element). A date in a time element or in the page's structured data was written for a program already and needs no parsing at all.

Use Dateparser for the visible date, which is the one written for a person and the one that varies by source and locale.

Normalise before you store. One format, one timezone rule, one column. A dataset with three date formats in one column cannot be sorted or compared, and fixing it later means re-reading every source.

Store the fetch time next to the date. It costs one column and it is the only thing that makes a relative date reproducible.

Store the raw string too. When a date turns out wrong six weeks later, the raw string is what tells you whether the parse was wrong or the page was.

When should you use strptime instead?

datetime.strptime Dateparser
You supply The exact format string Nothing, or a few settings
Handles a varying format No Yes
Handles relative expressions No Yes
Handles non-English month names Only with locale handling you write Yes, across more than 200 locales
Speed Faster Slower, because it tries more
On an unreadable string Raises Returns None
Use it when The format is fixed and you control the source The format varies or is unknown

Who else uses it?

What Figure Source
Downloads in the trailing month 37,182,241 PyPI download statistics
Stars on the repository 2,862 GitHub repository API
Forks 522 GitHub repository API
Repository created 24 November 2014 GitHub repository API
Last change pushed 22 September 2026 GitHub repository API

Four open source projects that list it as a dependency, each from the project's own dependency file:

Project What it does The line in its dependency file
ArchiveBox Self-hosted web archiving dateparser>=1.2.0 in pyproject.toml
AWS SAM CLI Command line tool for serverless applications dateparser==1.4.2 in requirements/reproducible-linux.txt
Home Assistant CLI Command line client for a home automation platform dateparser = "^1.2.0" in pyproject.toml
Chaos Toolkit for Kubernetes Resilience testing extension dateparser>=1.2.0 in pyproject.toml

The people who maintain it give two reasons.

Good code comes with automated tests that provide good code coverage.

Few dependencies: Installing a package should never be a pain. Keeping a small set of well-maintained dependencies helps improve the user experience.

Where do you get help with Dateparser?

Accessible (and complete) documentation: If you need to achieve anything more complex than those common examples, or you need to understand something in-depth, you only need to visit the documentation, which carries the settings reference and the API.

Support: Anything is not working? Are you searching for a new feature? You can open an issue in the issue tracker on the repository, which also carries the source and the full locale list, and you will find support directly from the maintainers.

Building and maintaining open source projects is in our DNA, and we have been really proud to see this -little- project growing during the years!

If dates are one field in a larger collection problem, Zyte API returns article and product fields as typed values, dates included, which removes the parsing step for the sources it covers. Zyte sells that. Dateparser is free and open source either way.

FAQ

Q: What is Dateparser?
A: A Python library that turns date strings written for people into datetime objects. It reads numeric formats, written month names in more than 200 language locales, and relative expressions such as "3 days ago". Zyte wrote it and maintains it, and it is free and open source under the BSD 3-Clause licence.

Q: How do I parse a date string in Python?
A: import dateparser, then dateparser.parse(your_string). It returns a datetime, or None if it could not read the string.

Q: Can it handle "3 days ago" and "yesterday"?
A: Yes. Relative expressions are one of the two reasons the library exists. Pass RELATIVE_BASE in the settings if you are parsing after the fetch, or the result is counted from the wrong moment.

Q: How many languages does it support?
A: More than 200 language locales, according to the project README. The locale data comes from the Unicode Common Locale Data Repository.

Q: How do I stop it reading 03/04/2022 the wrong way?
A: Set DATE_ORDER in the settings, to DMY, MDY or YMD. No parser resolves that ambiguity from the string alone, so you tell it which convention the source uses, per source rather than once globally.

Q: Why does it return None?
A: Because it could not read the string as a date. The string may carry extra text around the date, or it is in a format or locale the parser did not recognise. Print what you passed in before assuming the library failed.

Q: Dateparser or datetime.strptime?
A: strptime when the format is fixed and you control the source, because it is faster and exact. Dateparser when the format varies or is unknown.

Q: Does it handle timezones?
A: Yes, through TIMEZONE, TO_TIMEZONE and RETURN_AS_TIMEZONE_AWARE. Decide the rule at collection. A date with no timezone is not a moment, and a column with mixed rules cannot be fixed later without re-reading every source.

Q: Which Python versions does it support?
A: Python 3.10 and above, according to the project README.

Q: Is it free to use commercially?
A: Yes. It is published under the BSD 3-Clause licence.

Try Zyte API

Build your first scraper in minutes

Free trial, no credit card. From a single request to production in an afternoon.

Get started

Continue reading

The Community · Newsletter

The best of Zyte and the data web, in your inbox.

One curated edition — new articles, product updates, and the stories shaping the data web. No noise.