This release is a pre-release and may not be stable for production use.
ovos-date-parser
Multilingual parsing, extraction and formatting of human date, time and duration expressions — a two-way bridge between machine timestamps and the way people actually speak and write about time.
- Text → datetime: pull a
datetimeout of "next friday at 3pm" or "amanhã às 15h30", and keep the leftover words. - Text → duration: turn "two hours and thirty minutes" into a
timedelta. - datetime → speech: render
2024-01-05 15:30as "January fifth twenty twenty four at half past three". - Dozens of languages, resolved by BCP-47 code, with an automatic dateparser fallback for the rest.
It powers date/time understanding in OpenVoiceOS, but it is a plain Python library with no voice-assistant dependency at runtime — equally useful in an NER pipeline, a TTS front-end, an ASR post-processor, or a scheduling/calendar/logging tool.
Installation
pip install ovos-date-parser
# or
uv pip install ovos-date-parser
30-second quickstart
from datetime import datetime
from ovos_date_parser import extract_datetime, extract_duration, nice_time, nice_duration
# 1. text -> datetime (+ the words left over)
when, leftover = extract_datetime("lets meet next friday at 8am", "en",
anchorDate=datetime(2024, 1, 5))
print(when) # 2024-01-12 08:00:00
print(leftover) # 'lets meet'
# 2. text -> timedelta
delta, leftover = extract_duration("set a timer for 5 minutes", "en")
print(delta) # 0:05:00
# 3. datetime -> speakable words
print(nice_time(datetime(2024, 1, 5, 15, 30), "en")) # 'half past three'
print(nice_duration(3690, "en")) # 'one hour one minute thirty seconds'
Every snippet above and in examples/ runs with nothing installed
but this package.
Use it outside OVOS
The same handful of functions solve everyday text/speech problems that have nothing to do with voice assistants.
Temporal entity extraction (NER)
Tag dates, times and durations in free text and keep the non-temporal remainder — useful for log mining, ticket triage or note-taking apps.
from datetime import datetime
from ovos_date_parser import extract_datetime
text = "call the supplier next monday at 2pm about the delayed order"
when, rest = extract_datetime(text, "en", anchorDate=datetime(2024, 1, 5))
# when -> 2024-01-08 14:00 ; rest -> 'call supplier delayed order'
anchorDate is the "now" that relative phrases resolve against — pass a fixed
value for reproducible extraction, or datetime.now() live. See
examples/ner_temporal.py.
TTS normalization
Speech engines mangle raw digits. Normalize a timestamp to words before synthesis:
from datetime import datetime
from ovos_date_parser import nice_date, nice_time
dt = datetime(2024, 1, 5, 15, 30)
spoken = f"{nice_date(dt, 'en')} at {nice_time(dt, 'en')}"
# 'friday, january fifth, twenty twenty four at half past three'
See examples/tts_normalization.py.
ASR post-processing
Speech-to-text emits words; downstream logic needs structure. Convert a transcript into a real datetime and an action payload:
from datetime import datetime
from ovos_date_parser import extract_datetime
utterance = "remind me next tuesday at nine thirty to water the plants"
when, action = extract_datetime(utterance, "en", anchorDate=datetime(2024, 1, 5))
# when -> 2024-01-09 09:30 ; action -> 'remind me to water plants'
In an OVOS skill vs. standalone
The library behaves identically in both settings; only who calls it changes.
# In an OVOS skill: language and anchor come from the session
when, _ = extract_datetime(utterance, self.lang)
# Standalone scheduler / calendar / cron generator: you supply them
when, _ = extract_datetime(user_text, "en", anchorDate=datetime.now())
Core API
| Function | Direction | Purpose |
|---|---|---|
extract_datetime(text, lang, anchorDate=None, default_time=None) |
text → datetime | Date/time from a phrase + leftover text |
extract_duration(text, lang, *, resolution=..., replace_token="") |
text → duration | timedelta/relativedelta/float + leftover text |
nice_time(dt, lang, speech=True, use_24hour=False, use_ampm=False, variant=None) |
datetime → text | Speakable or digit clock time |
nice_date(dt, lang, now=None, include_weekday=True) |
datetime → text | Speakable date, shortened against now |
nice_date_time(dt, lang, now=None, use_24hour=False, use_ampm=False) |
datetime → text | Date and time combined |
nice_day / nice_weekday / nice_month / nice_year |
datetime → text | Individual date components |
nice_duration(duration, lang, speech=True) |
seconds/timedelta → text | Speakable timespan |
nice_relative_time(when, relative_to=None, lang="en-us") |
datetime → text | Short "N minutes/days" phrase |
get_date_strings(dt, lang, date_format=None, time_format="full") |
datetime → dict | Display strings for GUI clients |
Full signatures, return shapes and examples: docs/api.md.
Dialects resolve by prefix — "pt-BR", "pt-PT" and "pt" all reach the
Portuguese implementation. Unsupported languages raise NotImplementedError,
except extract_datetime, which first tries the dateparser fallback.
Language support
Twenty-plus languages have dedicated, idiomatic implementations. Extraction for
any other language falls back to dateparser; formatting falls back to a
generic word-table.
- ✅ dedicated implementation
- 🚧 partial / generic (language-agnostic helper or external library)
- ❌ not available (raises
NotImplementedError)
Parsing
| Language | extract_datetime |
extract_duration |
|---|---|---|
| ar Arabic | ✅ | ✅ |
| ast Asturian | ✅ | ✅ |
| az Azerbaijani | ✅ | ✅ |
| ca Catalan | ✅ | ✅ |
| cs Czech | ✅ | ✅ |
| da Danish | ✅ | ✅ |
| de German | ✅ | ✅ |
| en English | ✅ | ✅ |
| es Spanish | ✅ | ✅ |
| eu Basque | ✅ | ✅ |
| fa Persian | ✅ | ✅ |
| fr French | ✅ | ✅ |
| gl Galician | 🚧 | ✅ |
| hu Hungarian | 🚧 | ✅ |
| it Italian | ✅ | ✅ |
| kab Kabyle | ✅ | ✅ |
| nb Norwegian Bokmål | ✅ | ✅ |
| nl Dutch | ✅ | ✅ |
| nn Norwegian Nynorsk | ✅ | ✅ |
| oc Occitan | ✅ | ✅ |
| pl Polish | ✅ | ✅ |
| pt Portuguese | ✅ | ✅ |
| ro Romanian | ✅ | ✅ |
| ru Russian | ✅ | ✅ |
| sl Slovenian | ✅ | ✅ |
| sv Swedish | ✅ | ✅ |
| uk Ukrainian | ✅ | ✅ |
Any language not listed uses the
dateparserfallback forextract_datetime(good at absolute dates, weak at conversational relative phrases). The languages on the shared duration engine (all of the above except ar, ast, fa, kab, sv) also support theresolutionandreplace_tokenoptions ofextract_duration— see docs/api.md.
Formatting
| Language | nice_date family |
nice_time |
nice_duration |
nice_relative_time |
|---|---|---|---|---|
| ar Arabic | 🚧 | ✅ | ✅ | 🚧 |
| ast Asturian | ✅ | ✅ | ✅ | 🚧 |
| az Azerbaijani | ✅ | ✅ | ✅ | 🚧 |
| ca Catalan | ✅ | ✅ | ✅ | 🚧 |
| cs Czech | ✅ | ✅ | ✅ | 🚧 |
| da Danish | ✅ | ✅ | ✅ | 🚧 |
| de German | ✅ | ✅ | ✅ | 🚧 |
| en English | ✅ | ✅ | ✅ | 🚧 |
| es Spanish | ✅ | ✅ | ✅ | 🚧 |
| eu Basque | ✅ | ✅ | ✅ | ✅ |
| fa Persian | ✅ | ✅ | ✅ | 🚧 |
| fr French | ✅ | ✅ | ✅ | 🚧 |
| gl Galician | ✅ | ✅ | ✅ | 🚧 |
| hu Hungarian | ✅ | ✅ | ✅ | 🚧 |
| it Italian | ✅ | ✅ | ✅ | 🚧 |
| kab Kabyle | 🚧 | ✅ | ✅ | 🚧 |
| nb Norwegian Bokmål | ✅ | ✅ | ✅ | 🚧 |
| nl Dutch | ✅ | ✅ | ✅ | 🚧 |
| nn Norwegian Nynorsk | ✅ | ✅ | ✅ | 🚧 |
| oc Occitan | ✅ | ✅ | ✅ | 🚧 |
| pl Polish | ✅ | ✅ | ✅ | 🚧 |
| pt Portuguese | ✅ | ✅ | ✅ | 🚧 |
| ro Romanian | ✅ | ✅ | ✅ | 🚧 |
| ru Russian | ✅ | ✅ | ✅ | 🚧 |
| sl Slovenian | ✅ | ❌ | ✅ | 🚧 |
| sv Swedish | ✅ | ✅ | ✅ | 🚧 |
| uk Ukrainian | ✅ | ✅ | ✅ | 🚧 |
nice_relative_timeuses a shared implementation for every language except Basque, which has a dedicated one; the shared version is functional but not idiomatically tuned per language.
Per-language quirks (Catalan bell-tower time, Occitan quarter idioms, Romanian
"fără un sfert", Kabyle calendar names, Portuguese 15h30 style, ...) are
documented in docs/languages.md.
Examples
Runnable, dependency-free scripts in examples/:
| Script | Shows |
|---|---|
ner_temporal.py |
Extract date/time/duration entities from free text |
tts_normalization.py |
Render timestamps to speakable words before synthesis |
asr_postproc.py |
Turn spoken transcripts into structured datetimes |
multilingual.py |
Parse-then-render round trip across many languages |
extract.py |
Minimal extraction reference |
format.py |
Minimal formatting reference |
python examples/ner_temporal.py
Documentation
- API reference — every public function and its parameters
- Language notes — per-language behaviour and known gaps
- Adding a language — implementation guide
Related projects
- ovos-number-parser — numbers
- ovos-lang-parser — languages
- ovos-color-parser — colors
License
Apache 2.0.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ovos_date_parser-0.28.9a1.tar.gz.
File metadata
- Download URL: ovos_date_parser-0.28.9a1.tar.gz
- Upload date:
- Size: 358.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0f08e4f5610202fdef782e3707f5e41e481461bcc06468191a792001f3468af5
|
|
| MD5 |
5f0dceafdb33f54ea429a861ae0b698b
|
|
| BLAKE2b-256 |
dc81bcd544ae510f97de7182dd67f677d4ffde5a0691449c36318452fb389c3a
|
File details
Details for the file ovos_date_parser-0.28.9a1-py3-none-any.whl.
File metadata
- Download URL: ovos_date_parser-0.28.9a1-py3-none-any.whl
- Upload date:
- Size: 335.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d7bccfd397e4a29c4003a4333643cc71e792114b2430b8fe8b4edd0cd657da5d
|
|
| MD5 |
9d5f365e8fe3f2c454edfaea34c5fdc7
|
|
| BLAKE2b-256 |
3bb9aafc2b993730e1b3b9f5b3c61391135804ab76f7fb780492e9198a4aa200
|