PAYATHON 2026

Apache IoTDB 的 FORMAT 必须使用 %1$tY 形式的格式符吗?

数据小陈

结论

Apache IoTDB 的 FORMAT 日期时间格式遵循 Java String.format() / Formatter 规则,不能直接写成 %Y-%m-%d %H:%M:%S。在 %1$tY 中,1$ 是可以省略的参数索引,t 或 T 则是日期时间转换所需的前缀,需要保留。

要输出题目中的日期时间,可以使用较短的写法:

SELECT format('%1$tF %1$tT', `time`) FROM test;

%tF 表示年、月、日,%tT 表示 24 小时制的时、分、秒。IoTDB 官方文档也给出了这一组合的示例。IoTDB FORMAT 文档

为什么 %Y 会报错?

%Y 是 strftime 风格的日期格式写法。Java Formatter 的日期时间转换以 t 或 T 开头,后面跟具体的日期时间后缀,例如 tY 表示年份。

报错中的 Conversion = 'Y' 表明格式字符串里的 Y 被当成了独立转换字符,而 Java 没有定义这个转换。问题出在 FORMAT 的格式字符串,不能仅凭这条错误认定 SQL 语句结构有误。Java Formatter 格式语法

原格式可以逐项改为:

日期时间部分Java Formatter 写法
年%tY
月%tm
日%td
时(24 小时制)%tH
分%tM
秒%tS

这些格式符区分大小写,尤其要注意月份的 m 和分钟的 M。

为什么示例中反复使用 1$?

%1$tY 可以拆成三部分:% 开始一个格式符,1$ 选择格式字符串之后的第一个参数,tY 按年份格式化它。题目中的这个参数是 time。

只输出年份时,一个格式符对应一个参数,可以省略索引:

SELECT format('%tY', `time`) FROM test;

如果写成下面这样,三个格式符会依次取三个参数,不会自动重复使用同一个 time:

-- 这里只传了一个值,无法满足三个按顺序取参的格式符
SELECT format('%tY-%tm-%td', `time`) FROM test;

要重复使用同一个时间值,可以显式指定 1$:

SELECT format('%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS', `time`)
FROM test;

Java 还支持用 < 标志复用上一个格式符使用的参数。按其参数索引规则,也可以写成:

SELECT format('%tF %<tT', `time`) FROM test;

第一个格式符选择 time,第二个通过 < 继续使用它。Java Formatter 参数索引规则

使用时注意什么?

原始材料中的 SQL 使用了 %1\$tY 这样的反斜杠写法。Java 格式符本身是 %1$tY,其中不包含反斜杠。如果 SQL 经过 shell 或其他字符串层传递,是否需要额外转义,应按对应层的规则处理。上面的示例使用直接 SQL 写法。

题目记录的结果是 2024-11-30 09:30:00。如果替换格式后出现小时偏移,应另外检查时间值的时区解释和格式化环境;更换格式字符串本身不等于转换时区。Java 对 long、Long 和 Date 的日期时间格式化会使用 JVM 默认时区。Java Formatter 日期时间规则

备注:内容仅供参考。