在构建或使用RSS 2.0订阅源时,pubDate是一个描述内容发布时间的核心元素。许多自行生成feed的站点因为日期格式不合规,导致主流阅读器无法正确排序或更新文章。要写出稳定的RSS输出,就必须弄清楚pubDate背后引用的标准到底是什么。

pubDate的规范来源
RSS 2.0规范中明确写道,pubDate的值应当是符合RFC 822标准的日期和时间。RFC 822原本是电子邮件协议的消息格式标准,其中定义了如何在消息头里书写时间。RSS借用了这一约定,因此pubDate并不是自由文本,而是一种有固定结构的机器可读字符串。
具体来说,RFC 822日期格式要求依次出现:星期的英文缩写、逗号、日期的零填充两位数字、月份的英文缩写、四位年份、两位小时、冒号、两位分钟、冒号、两位秒,最后跟上时区偏移。比如“Mon, 02 Jun 2025 13:45:00 +0800”就是一个合法值。如果只写“2025-06-02”这类ISO风格字符串,虽然对人友好,但很多老牌RSS解析器会解析失败。
常见错误写法与后果
开发者常犯的第一个错误是使用本地化的中文日期,例如“2025年6月2日 下午1点”。这种写法人类能看懂,但解析器通常无法识别,会将该条目时间视为空,从而排在列表最底部或被认为未更新。第二个错误是省略时区,只给“Mon, 02 Jun 2025 13:45:00”,某些聚合器会默认当成UTC,造成国内用户看到的时间提早八小时。
第三个易错点是用数字月份代替英文缩写,比如“Mon, 02 06 2025 13:45:00 +0800”。RFC 822规定月份必须是三个字母的英文缩写,数字形式不符合规范。下面是一段有问题的Python生成代码:
# 错误示例:使用数字月份且无星期
pub_date = "02 06 2025 13:45:00 +0800"
print("<pubDate>" + pub_date + "</pubDate>")
上述输出在被严格解析的库中会引发ValueError,而在宽松库中可能被忽略。正确做法应调用语言标准库生成合规字符串。
如何用代码生成合规pubDate
几乎所有现代编程语言都内置了RFC 822或近似日期格式化工具。以Python为例,可以用email.utils.formatdate或者手动用strftime拼接。推荐使用标准库,避免自己拼字符串出错。
下面给出一段正确的Python示例,它先构造带时区的datetime对象,再格式化为RSS需要的样子:
from datetime import datetime, timezone, timedelta
# 构造东八区时间
tz = timezone(timedelta(hours=8))
dt = datetime(2025, 6, 2, 13, 45, 0, tzinfo=tz)
# 格式:Fri, 02 Jun 2025 13:45:00 +0800
rss_date = dt.strftime("%a, %d %b %Y %H:%M:%S %z")
print("<pubDate>" + rss_date + "</pubDate>")
在PHP里同样简单,date函数配合时区设置即可输出合规值。核心是确认服务器时区或显式指定偏移,不要让解析端去猜。
<?php
$date = new DateTime("2025-06-02 13:45:00", new DateTimeZone("Asia/Shanghai"));
echo "<pubDate>" . $date->format("D, d M Y H:i:s O") . "</pubDate>";
?>
验证与兼容性建议
写完feed后,可以用在线的RSS校验服务或本地XML解析器验证pubDate是否被正确读取。一些阅读器如FreshRSS、Inoreader对格式容错较高,但命令行工具rss2json或自写爬虫往往严格遵循规范。为了最大兼容,不要依赖解析器的“聪明”,而要从源头输出标准串。
如果历史数据已经用了错误格式,建议写迁移脚本统一重写。同时在生成模板里封装一个日期函数,禁止业务代码直接拼字符串。这样既能满足RSS规范,也方便以后扩展到Atom等其他格式,因为Atom用的RFC 3339和RFC 822思路相通,只是写法不同。
小结
pubDate不是随便填的展示字段,而是RSS机器交换时间信息的契约。牢牢记住它要的是RFC 822邮件头风格、英文月名、明确时区,就能避开绝大多数订阅异常。用标准库生成、用校验器复查,是整个环节里最省事的做法。
RSSpubDatedate_format修改时间:2026-08-09 20:48:31