我正在尝试操纵日期值以将时间追溯到恰好1 ISO-8601年。
以下内容不起作用,但最好地描述了我要完成的工作:
date_add(date '2018-01-03', interval -1 isoyear)
我尝试将字符串转换作为中间步骤,但这也不起作用:
select parse_date('%G%V%u',safe_cast(safe_cast(format_date('%G%V%u',date '2018-01-03') as int64)-1000 as string))
为最后一个错误提供的错误是“无法解析输入字符串“ 2017013””。我不明白为什么,这应该始终解析为唯一的日期值。
我还有另一种方法可以从日期中减去ISO年吗?
答案 0 :(得分:2)
通过从日期中减去相应的星期数来给出上一个ISO年份的相应日期。我基于Wikipedia页面上weeks per year的描述进行了计算:
CREATE TEMP FUNCTION IsLongYear(d DATE) AS (
-- Year starting on Thursday
EXTRACT(DAYOFWEEK FROM DATE_TRUNC(d, YEAR)) = 5 OR
-- Leap year starting on Wednesday
(EXTRACT(DAY FROM DATE_ADD(DATE(EXTRACT(YEAR FROM d), 2, 28), INTERVAL 1 DAY)) = 29
AND EXTRACT(DAYOFWEEK FROM DATE_TRUNC(d, YEAR)) = 4)
);
CREATE TEMP FUNCTION PreviousIsoYear(d DATE) AS (
DATE_SUB(d, INTERVAL IF(IsLongYear(d), 53, 52) WEEK)
);
SELECT PreviousIsoYear('2018-01-03');
这将返回2017-01-04
,这是2017 ISO年度的第三天。 2018-01-03
是2018 ISO年度的第三天。