Datasette 的 dateutil 函数
请在 Datasette 所在的同一环境中安装此插件。
$ datasette install datasette-dateutil
此函数添加了自定义 SQL 函数,这些函数公开了 dateutil Python 库的功能。
安装后,以下 SQL 函数即可使用
dateutil_parse(text)
- 从文本中解析并返回一个 ISO8601 日期字符串,如果输入无法解析则返回null
。dateutil_parse("10 october 2020 3pm")
返回2020-10-10T15:00:00
。dateutil_parse_fuzzy(text)
- 与dateutil_parse()
相同,但此函数也适用于包含日期的字符串 - 将返回字符串中的日期,如果没有找到日期则返回null
。dateutil_parse_fuzzy("This is due 10 september")
返回2020-09-10T00:00:00
(但如果年份是 2021,则会开始返回 2021 年的版本)。
dateutil_parse()
和 dateutil_parse_fuzzy()
函数都遵循美式惯例,假定 1/2/2020
中的月份在前,将此示例解析为 1 月 2 日。
如果您想假定日期在前,请改用以下两个函数
dateutil_parse_dayfirst(text)
dateutil_parse_fuzzy_dayfirst(text)
这是一个演示这些函数的查询
select
dateutil_parse("10 october 2020 3pm"),
dateutil_parse_fuzzy("This is due 10 september"),
dateutil_parse("1/2/2020"),
dateutil_parse("2020-03-04"),
dateutil_parse_dayfirst("2020-03-04");
dateutil_parse()
、dateutil_parse_fuzzy()
、dateutil_parse_dayfirst()
和 dateutil_parse_fuzzy_dayfirst()
函数都接受一个可选的第二个参数,用于指定一个“默认”日期时间,以考虑缺失的部分详细信息。例如,以下内容:
select dateutil_parse('1st october', '1985-01-01')
将返回 1985-10-01T00:00:00
- 缺失的年份被默认日期中的年份替换。
dateutil_easter(year)
- 返回该年份的复活节日期,例如dateutil_easter("2020")
返回2020-04-12
。
有几个函数返回日期字符串的 JSON 数组。这些数组可以与 SQLite 的 json_each()
函数一起使用,以针对特定日期范围或重复规则中的日期执行连接操作。
这些函数最多可以返回 10,000 个结果。如果将返回超过 10,000 个日期,它们将返回错误 - 这是为了防止拒绝服务攻击。
dateutil_dates_between('1 january 2020', '5 jan 2020')
- 给定两个日期(可以是dateutil_parse()
能处理的任何格式),此函数返回一个 JSON 字符串,其中包含这两个日期之间的日期(包括这两个日期)。此示例返回["2020-01-01", "2020-01-02", "2020-01-03", "2020-01-04", "2020-01-05"]
。dateutil_dates_between('1 january 2020', '5 jan 2020', 0)
- 将可选的第三个参数设置为0
,以指定您希望不包含最后一天。此示例返回["2020-01-01", "2020-01-02", "2020-01-03", "2020-01-04"]
。
dateutil_rrule()
和 dateutil_rrule_date()
函数接受 iCalendar 标准的 rrule
格式 - 更多示例请参阅 dateutil 文档。
这种格式允许您指定重复规则,例如“接下来四个月的最后一个星期一”。
dateutil_rrule(rrule, optional_dtsart)
- 给定一个 rrule,返回 ISO 日期时间 的 JSON 数组。第二个参数是可选的,将作为规则的开始日期。dateutil_rrule_date(rrule, optional_dtsart)
- 与dateutil_rrule()
相同,但返回 ISO 日期。
示例查询
select
dateutil_rrule('FREQ=HOURLY;COUNT=5'),
dateutil_rrule_date(
'FREQ=DAILY;COUNT=3',
'1st jan 2020'
);
SQLite 的 json_each() 函数 可用于将日期的 JSON 数组转换为一个表,该表可以与其他数据连接。以下是一个返回 2019 年 1 月每一天的表的查询:
select
value as date
from
json_each(
dateutil_dates_between('1 Jan 2019', '31 Jan 2019')
)
您可以使用 SQLite 的 对公共表表达式 (CTE) 的支持 为此表分配一个名称,然后对其进行连接。
此示例查询使用 substr(created, 0, 11)
检索 facetable 演示表 中 created
列的日期部分,然后与 1 月份日期的表进行连接,以计算每天创建的行数。对 days_in_january
进行 LEFT JOIN
确保了没有创建记录的日期仍然在结果中返回,计数为 0。
with created_dates as (
select
substr(created, 0, 11) as date
from
facetable
),
days_in_january as (
select
value as date
from
json_each(
dateutil_dates_between('1 Jan 2019', '31 Jan 2019')
)
)
select
days_in_january.date,
count(created_dates.date) as total
from
days_in_january
left join created_dates on days_in_january.date = created_dates.date
group by
days_in_january.date;
尝试此查询,并使用 datasette-vega 插件渲染条形图。
要在本地设置此插件,请先检出代码。然后创建一个新的虚拟环境:
cd datasette-dateutil
python3 -mvenv venv
source venv/bin/activate
或者如果您正在使用 pipenv
:
pipenv shell
现在安装依赖项和测试:
pip install -e '.[test]'
要运行测试:
pytest