{"id":45893075,"url":"https://github.com/Stypox/dicio-numbers","last_synced_at":"2026-03-13T06:00:56.720Z","repository":{"id":65088037,"uuid":"338267016","full_name":"Stypox/dicio-numbers","owner":"Stypox","description":"Dicio's multilingual number parsing and formatting library, inspired by Mycroft's lingua-franca","archived":false,"fork":false,"pushed_at":"2026-02-24T23:53:46.000Z","size":933,"stargazers_count":31,"open_issues_count":7,"forks_count":27,"subscribers_count":4,"default_branch":"master","last_synced_at":"2026-02-25T04:51:08.516Z","etag":null,"topics":["date","dicio","dicio-assistant","i18n","multilanguage","number-formatter","number-parser","numbers"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Stypox.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"liberapay":"Stypox"}},"created_at":"2021-02-12T08:56:23.000Z","updated_at":"2026-02-24T23:53:51.000Z","dependencies_parsed_at":"2023-02-16T22:16:17.405Z","dependency_job_id":"ec8118a8-b4aa-4bbe-a076-ebb5299ba88e","html_url":"https://github.com/Stypox/dicio-numbers","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/Stypox/dicio-numbers","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stypox%2Fdicio-numbers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stypox%2Fdicio-numbers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stypox%2Fdicio-numbers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stypox%2Fdicio-numbers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Stypox","download_url":"https://codeload.github.com/Stypox/dicio-numbers/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stypox%2Fdicio-numbers/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30459760,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-13T03:55:51.346Z","status":"ssl_error","status_checked_at":"2026-03-13T03:55:33.055Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["date","dicio","dicio-assistant","i18n","multilanguage","number-formatter","number-parser","numbers"],"created_at":"2026-02-27T19:00:39.319Z","updated_at":"2026-03-13T06:00:56.713Z","avatar_url":"https://github.com/Stypox.png","language":"Java","readme":"# Number parser and formatter for Dicio assistant\nThis *multilingual* library implements methods to **extract** numbers, dates or durations from text and **format** numbers, dates or dutations into human-readable words. It is inspired by [Mycroft's lingua-franca](https://github.com/MycroftAI/lingua-franca), from which it borrows some resource files. Currently only Italian (it-it) and English (en-us) are supported, and methods to extract dates or durations are still unavailable (though formatting is).\n\nThis repository is part of the **Dicio** project. Also check out [`dicio-android`](https://github.com/Stypox/dicio-android), [`dicio-sentences-compiler`](https://github.com/Stypox/dicio-sentences-compiler/) and [`dicio-skill`](https://github.com/Stypox/dicio-skill/). *Open to contributions :-D*\n\n## Adding a language\n\nYou will need to translate some resource files, containing words but also regex, and then adapt some Java code, so be prepared for that.\n\nFirst of all you need to obtain the `language-country` pair for the language you want to add. This is important so that who is using the library can choose the language to use. For example, English is `en-us` and Italian is `it-it`. Let's call this `LANGUAGE_COUNTRY` from now on.\n\n### Resources\n\nCopy the whole folder `numbers/src/main/resources/config/en-us` into a new folder `numbers/src/main/resources/config/LANGUAGE_COUNTRY`. All of the resource files in the new folder should be translated into the new language. **DO NOT** rename any file, just edit their contents.\n\n### `*.word` files\n\nThe files named like `ENGLISH_WORD.word` should contain only one line with the lowercase translation of the word `ENGLISH_WORD` in the new language. For example, the English `second.word` contains \"second\", the Italian one contains \"secondo\" and the new language one should contain the translation of \"second\" into that language. These files are **also present in Mycroft's [lingua-franca](https://github.com/MycroftAI/lingua-franca/blob/master/lingua_franca/res/text/), so copy them from there** to save time! Then just check if everything is fine.\n\n### `date_time.json` file\n\nThis file contains the data needed to properly *format* dates, and in part also times, though that's also handled elsewhere. This file is **also present in Mycroft's [lingua-franca](https://github.com/MycroftAI/lingua-franca/blob/master/lingua_franca/res/text/), so copy it from there** to save time! Then just check if everything is fine.\n\nEach of the formats provided in this file can (and shall) contain references to other already-formatted strings to be substituted, in the form `{FORMATTED_STRING_NAME}`. For example, English uses `\"{formatted_date} at {formatted_time}\"` as the way to format together both the date and the time.\n\n#### `\"weekday\"`, `\"date\"`, `\"month\"`, `\"number\"`\n\nThese JSON objects should contain:\n- `\"weekday\"`: a numbered list of how the 7 days in the week are pronounced, where monday is at position **0**\n- `\"date\"`: a numbered list of how the at-most-31 days in the month are pronounced, where the first day is at position **1**\n- `\"month\"`: a numbered list of how the 12 months are pronounced, where january is at position **1**\n- `\"number\"`: a list of `\"NUMBER\": \"PRONOUNCIATION\"` pairs. It should contain the pronounciation of all numbers that you want to use in [`\"decade_format\"`, `\"hundreds_format\"` and `\"thousand_format\"`](#decade_format-hundreds_format-thousand_format).\n\n#### `\"decade_format\"`, `\"hundreds_format\"`, `\"thousand_format\"`\n\nThese JSON objects should contain a numbered list (starting from 1, but it doesn't matter) of `(regex, format)` pairs, along with a `\"default\"` format for when none of the regexes match. Each `(regex, format)` pair should be a JSON object:\n- `\"match\"` contains the JSON-escaped pattern to match, starting with `^` and ending with `$`. The pattern will be matched against the part of the year corresponding to `\"decade_format\"` (only last two digits), `\"hundreds_format\"` (last three digits) **or** `\"thousand_format\"` (last four digits).\n- `\"format\"` (and the `\"default\"` mentioned before) contains the format to apply. Refer to the table below for which substitutions you can do.\n\nIn these JSON object you should put partial year formatting results that will be finally used by `\"year_format\"`. It doesn't matter if for some language, instead of just formatting e.g. the thousands digit in `\"thousand_format\"`, you also sometimes format the hundreds digit (this is what happens for English). The important thing is that, at the end, `\"year_format\"` spits out correct results.\n\nThis is the table of possible `FORMATTED_STRING_NAME`s you can use when having to do with `\"decade_format\"`, `\"hundreds_format\"` or `\"thousand_format\"`. Check out [NiceYearSubstitutionTableBuilder.java](./numbers/src/main/java/org/dicio/numbers/formatter/datetime/NiceYearSubstitutionTableBuilder.java). The examples are in English and relative to the years \"2019\" and \"3865 b.c.\".\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003e\u003ccode\u003eFORMATTED_STRING_NAME\u003c/code\u003e\u003c/th\u003e\n    \u003cth\u003eExplanation\u003c/th\u003e\n    \u003cth\u003ee.g. \"2019\"\u003c/th\u003e\n    \u003cth\u003ee.g. \"-3865\"\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ex\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe last digit of the year\u003c/td\u003e\n    \u003ctd\u003e\"nine\"\u003c/td\u003e\n    \u003ctd\u003e\"five\"\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003exx\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe last two digits of the year, if there is a corresponding entry in the \u003ccode\u003e\"number\"\u003c/code\u003e list\u003c/td\u003e\n    \u003ctd\u003e\"nineteen\"\u003c/td\u003e\n    \u003ctd\u003e\"\" (65 is not special and thus has no entry in the \u003ccode\u003e\"number\"\u003c/code\u003e list)\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ex0\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe tens of the year\u003c/td\u003e\n    \u003ctd\u003e\"ten\"\u003c/td\u003e\n    \u003ctd\u003e\"sixty\"\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ex_in_x0\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe tens digit of the year\u003c/td\u003e\n    \u003ctd\u003e\"one\"\u003c/td\u003e\n    \u003ctd\u003e\"six\"\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe last three digits of the year, if there is a corresponding entry in the \u003ccode\u003e\"number\"\u003c/code\u003e list\u003c/td\u003e\n    \u003ctd\u003e\"nineteen\" (there is no hundreds digit)\u003c/td\u003e\n    \u003ctd\u003e\"\" (865 is not special and thus has no entry in the \u003ccode\u003e\"number\"\u003c/code\u003e list)\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ex00\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe hundreds of the year, if there is a corresponding entry in the \u003ccode\u003e\"number\"\u003c/code\u003e list\u003c/td\u003e\n    \u003ctd\u003e\"zero\" (probably doesn't make much sense)\u003c/td\u003e\n    \u003ctd\u003e\"\" (English pronounces hundreds by putting \"hundred\" after the unit, so there is no entry for 800 in the \u003ccode\u003e\"number\"\u003c/code\u003e list)\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ex_in_x00\u003c/code\u003e and \u003ccode\u003ex_in_0x00\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe hundreds digit of the year\u003c/td\u003e\n    \u003ctd\u003e\"zero\"\u003c/td\u003e\n    \u003ctd\u003e\"eight\"\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003exx00\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe year with its tens and its units digits set to 0, if there is a corresponding entry in the \u003ccode\u003e\"number\"\u003c/code\u003e list\u003c/td\u003e\n    \u003ctd\u003e\"\" (2000 is not special and thus has no entry in the \u003ccode\u003e\"number\"\u003c/code\u003e list)\u003c/td\u003e\n    \u003ctd\u003e\"\" (3800 is not special and thus has no entry in the \u003ccode\u003e\"number\"\u003c/code\u003e list)\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003exx_in_xx00\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe year divided by 100, if there is a corresponding entry in the \u003ccode\u003e\"number\"\u003c/code\u003e list\u003c/td\u003e\n    \u003ctd\u003e\"twenty\"\u003c/td\u003e\n    \u003ctd\u003e\"\" (38 is not special and thus has no entry in the \u003ccode\u003e\"number\"\u003c/code\u003e list)\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ex000\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe thousands of the year, if there is a corresponding entry in the \u003ccode\u003e\"number\"\u003c/code\u003e list\u003c/td\u003e\n    \u003ctd\u003e\"\" (English pronounces thousands by putting \"thousand\" after the unit, so there is no entry for 2000 in the \u003ccode\u003e\"number\"\u003c/code\u003e list)\u003c/td\u003e\n    \u003ctd\u003e\"\" (same reason, for 3000)\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ex_in_x000\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe thousands digit of the year\u003c/td\u003e\n    \u003ctd\u003e\"two\"\u003c/td\u003e\n    \u003ctd\u003e\"three\"\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ex0_in_x000\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe thousands digit of the year, multiplied by 10\u003c/td\u003e\n    \u003ctd\u003e\"twenty\"\u003c/td\u003e\n    \u003ctd\u003e\"thirty\"\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003enumber\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe non-formatted part of the year corresponding to \u003ccode\u003e\"decade_format\"\u003c/code\u003e (only last two digits), \u003ccode\u003e\"hundreds_format\"\u003c/code\u003e (last three digits) \u003cb\u003eor\u003c/b\u003e \u003ccode\u003e\"thousand_format\"\u003c/code\u003e (last four digits), to be used for \u003ccode\u003e\"default\"\u003c/code\u003e as a fallback\u003c/td\u003e\n    \u003ctd\u003e\"19\", \"19\" or \"2019\"\u003c/td\u003e\n    \u003ctd\u003e\"65\", \"865\" or \"3865\"\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### `\"year_format\"`\n\nThis JSON object follows the same structure as [`\"decade_format\"`, `\"hundreds_format\"`, `\"thousand_format\"`](#decade_format-hundreds_format-thousand_format), but there is also a `\"bc\"` field that should contain the translation of the shortened \"Before Christ\" (\"b.c.\"). In this JSON object you should put how to fully format a number as a year, using the formatted strings already calculated using `\"decade_format\"`, `\"hundreds_format\"` and `\"thousand_format\"`.\n\nThe formats have at their disposal the full table from above plus the following items (which are the ones that should actually be used).\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003e\u003ccode\u003eFORMATTED_STRING_NAME\u003c/code\u003e\u003c/th\u003e\n    \u003cth\u003eExplanation\u003c/th\u003e\n    \u003cth\u003ee.g. \"2019\"\u003c/th\u003e\n    \u003cth\u003ee.g. \"-3865\"\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eformatted_decade\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe decade formatted using \u003ccode\u003e\"decade_format\"\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\"nineteen\"\u003c/td\u003e\n    \u003ctd\u003e\"sixty five\"\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eformatted_hundreds\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe hundreds formatted using \u003ccode\u003e\"hundreds_format\"\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\"zero hundred\" (yeah, it doesn't make sense)\u003c/td\u003e\n    \u003ctd\u003e\"eight hundred\"\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eformatted_thousand\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe thousands formatted using \u003ccode\u003e\"thousand_format\"\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\"twenty\"\u003c/td\u003e\n    \u003ctd\u003e\"thirty eight\"\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ebc\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe translation of \"b.c.\" if the year is before Christ, otherwise an empty string\u003c/td\u003e\n    \u003ctd\u003e\"\"\u003c/td\u003e\n    \u003ctd\u003e\"b.c.\"\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003enumber\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe non-formatted full-year, to be used for \u003ccode\u003e\"default\"\u003c/code\u003e as a fallback\u003c/td\u003e\n    \u003ctd\u003e\"2019\"\u003c/td\u003e\n    \u003ctd\u003e\"3865\"\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### `\"date_format\"`\n\nThis JSON object should contain a format in these fields: `\"date_full\"`, `\"date_full_no_year\"`, `\"date_full_no_year_month\"`; and a translation of the field name in these fields: `\"today\"`, `\"tomorrow\"`, `\"yesterday\"`.\n\nThe formats have at their disposal this limited table.\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003e\u003ccode\u003eFORMATTED_STRING_NAME\u003c/code\u003e\u003c/th\u003e\n    \u003cth\u003eExplanation\u003c/th\u003e\n    \u003cth\u003ee.g. \"Tuesday, 2022/05/03\"\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eday\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe name of the day in the month\u003c/td\u003e\n    \u003ctd\u003e\"third\"\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eweekday\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe name of the day in the week\u003c/td\u003e\n    \u003ctd\u003e\"tuesday\"\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003emonth\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe name of the month\u003c/td\u003e\n    \u003ctd\u003e\"may\"\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eformatted_year\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe year fully formatted using \u003ccode\u003e\"year_format\"\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\"twenty twenty two\"\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### `\"date_time_format\"`\n\nThis JSON object should contain a format in this only field: `\"date_time\"`.\n\nThe format has at its disposal this limited table.\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003e\u003ccode\u003eFORMATTED_STRING_NAME\u003c/code\u003e\u003c/th\u003e\n    \u003cth\u003eExplanation\u003c/th\u003e\n    \u003cth\u003ee.g. \"Tuesday, 2022/05/03 13:22\"\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eformatted_date\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe date fully formatted using \u003ccode\u003e\"date_format\"\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\"tuesday, may second, twenty twenty two\"\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eformatted_time\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003ethe time formatted using the java method \u003ccode\u003eniceTime\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\"one twenty two p.m.\"\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n### `tokenizer.json`\n\nThis JSON file contains the information the tokenizer uses to generate the token stream corresponding to an input string.\n\n- `\"spaces\"`: a string containing all characters that should be considered spaces. This usually does not need to be *translated*.\n- `\"characters_as_word\"`: a string containing all characters that should be considered as single-character words, and not as letters possibly part of a bigger word. An example for this is `%`, since the percent sign has a meaning on its own.\n- `\"compound_word_piece_category\"`: the category that you will give in `\"number_mappings\"` to words that can be part of a compound word. A compound word is a word made of other words all connected together, and the tokenizer will split such big words using only words that can actually be part of compound words. While the value of this could be arbitrary, given that you then use the same value in `\"number_mappings\"`, there is no reason to set this to something different than \"compound_word_piece\", which is what is used in Italian. If the language you want to add has no compound words, like English, just don't add this field.\n- `\"raw_number_categories\"`: an array of all the categories that the tokenizer should give to raw numbers when it encounters them. A raw number is e.g. 2384, -392, ...\n- `\"plural_endings\"`: an array of the endings that the tokenizer should try to trim off a word if it can't recognize it otherwise. For example, in English \"tens\" would match with \"ten\" because there is \"s\" in the `\"plural_endings\"` array.\n- `\"word_matches\"`: an array of JSON objects of this form:\n  - `\"categories\"`: an array of the categories that should be assigned to the words that match any of the values\n  - `\"values\"`: an array of the words that should be assigned all of the categories\n- `\"number_mappings\"`: an array of JSON objects of this form:\n  - `\"categories\"`: an array of the categories that should be assigned to the words that match any of the values\n  - `\"values\"`: an JSON object with the words that should be assigned all of the categories paired with their corresponding (integer or decimal) numerical value\n- `\"duration_words\"`: a JSON object used to pair words with their corresponding duration. The keys in the object should be the durations (formatted as `\"number UNIT\"`, where `number` is an integer and `UNIT` (uppercase) is one of NANOS, MICROS, MILLIS, SECONDS, MINUTES, HOURS, HALF_DAYS, DAYS, WEEKS, MONTHS, YEARS, DECADES, CENTURIES, MILLENNIA, ERAS), and the values are JSON arrays of words.\n- `\"duration_restrict_after_number\"`: a list of all of the words present in `\"duration_words\"` that should not be recognized as a duration if they don't come with a number before them in the input. For example, \"hello ms\" should **not** be interpreted as \"hello (1 millisecond)\", while \"hello millisecond\" and \"hello 1 ms\" should.\n\n### Test resources\n\nCopy the whole folder `numbers/src/test/resources/config/en-us` into a new folder `numbers/src/test/resources/config/LANGUAGE_COUNTRY`. All of the resource files in the new folder are used for testing purposes and should be translated into the new language. **DO NOT** rename any file, just edit their contents.\n\n### `date_time_test.json`\n\nThis file contains some tests for the `date_time.json` file. This file is **also present in Mycroft's [lingua-franca](https://github.com/MycroftAI/lingua-franca/blob/master/lingua_franca/res/text/), so copy it from there** to save time! Then just check if everything is fine.\n\nEach of the JSON objects described below contains a numbered list of tests to run.\n\n#### `\"test_nice_year\"`\n\nThese tests are for [`\"year_format\"`](#year_format). Each test has:\n- `\"datetime_param\"` the datetime in this form: year, month, day, hour, minute, second\n- `\"bc\"` whether the datetime is before Christ (`True`) or not (`False`)\n- `\"assertEqual\"` what the provided datetime should be formatted as\n\n#### `\"test_nice_date\"`\n\nThese tests are for [`\"date_format\"`](#date_format). Each test has:\n- `\"datetime_param\"` the datetime in this form: year, month, day, hour, minute, second\n- `\"now\"` the datetime corresponding to the \"now\" time for which to test relative dates (e.g. if `datetime_param=now`, then `today` will be outputted, not the full date), in the same form, or `None` if \"now\" is unknown or unwanted\n- `\"assertEqual\"` what the provided datetime should be formatted as\n\n#### `\"test_nice_date_time\"`\n\nThese tests are for [`\"date_time_format\"`](#date_time_format). Each test has:\n- `\"datetime_param\"` the datetime in this form: year, month, day, hour, minute, second\n- `\"now\"` the datetime corresponding to the \"now\" time for which to test relative dates (e.g. if `datetime_param=now`, then `today` will be outputted, not the full date), in the same form, or `None` if \"now\" is unknown or unwanted\n- `\"use_24hour\"` whether to use the 24-hour format (`True`) or use the 12-hour one (`False`) (parameter passed to the java method `niceTime`)\n- `\"use_ampm\"` whether to show AM/PM or not (parameter passed to the java method `niceTime`)\n- `\"assertEqual\"` what the provided datetime should be formatted as\n","funding_links":["https://liberapay.com/Stypox"],"categories":["人工智能"],"sub_categories":["自然语言处理"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStypox%2Fdicio-numbers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FStypox%2Fdicio-numbers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStypox%2Fdicio-numbers/lists"}