按日期搜 X:为什么你的时间区间返回的比应有的少

15 min readSocialAPI 工程团队

按日期搜 X:为什么你的时间区间返回的比应有的少

这两个操作符只有两个词,看起来不言自明:

from:nasa since:2026-01-01 until:2026-06-30

然后你跑了一下,六个月的窗口只返回 40 条,于是合理地得出结论:这个账号那段时间不活跃。它并没有。 ★你撞上的是结果上限,不是数据的尽头。★

这是 X 搜索里最被误解的一个行为,而且它会静默地污染任何建立在时间区间上的分析。


两个操作符

操作符 含义 边界
since:YYYY-MM-DD 该日期当天及之后 包含
until:YYYY-MM-DD 该日期之前 不包含

⚠️ ★until: 不包含它自己那一天。until:2026-06-30 停在 6 月 29 日结束时。想包含 30 号,要写 until:2026-07-01

这个不对称让人在每个边界上损失一天。如果你在按月扫,这里差一天意味着一年少十二天 —— 而它表现为数据里一个神秘的凹陷,而不是一个明显的报错。(每条推文返回时都带自己的时间戳,所以在本地过滤可以彻底绕开边界问题。)

两者可以独立使用。 只写 since: 表示"从那时到现在";只写 until: 表示"从最早到那时"。


时区问题

★日期是按 UTC 解释的,不是你的本地时间。★

对大多数搜索这无关紧要。但当你在衡量一件有时间敏感性的事时 —— 一次发布、一次事故、一个市场事件 —— 它关系极大:加州时间 15 号晚上 8 点发的推文,在 UTC 里已经是 16 号了。

★如果你所在时区离 UTC 很远,而你又在按天切片,那么你的"一天"和 X 的"一天"是不同的窗口。★ 做精确的活时,把区间前后各放宽一天,再用推文自带的时间戳在本地过滤


为什么窄窗口比宽窗口返回更多

这是反直觉的那部分,也是大多数时间区间分析悄悄出错的原因

每条查询返回的结果条数是有上限的。它在撞到上限时停止,而不是在穷尽你的时间区间时停止。★ 一个六个月的窗口不会返回六个月的推文 —— 它返回上限允许的那些,而且是从区间的某一端取的。

实际后果:

一条查询:   since:2026-01-01 until:2026-07-01   →  约 40 条
六条查询:   同一段时间,按月拆开                →  约 240 条

同一段时间,六倍的数据,纯粹来自把查询拆开。

⚠️ 这就是为什么"这个账号三月份不活跃"通常是一个测量假象。 ★在你对数据里的某个缺口下任何结论之前,把那一段单独作为一条窄查询再跑一次。那个缺口几乎总会被填上。★

窄到什么程度? 取决于发帖量。安静的账号按月就行;高产账号或热门关键词需要按周甚至按天。★经验法则:如果一个窗口返回的条数接近上限,它就是被截断的 —— 拆开再跑。


无缺口地扫完一段长时间

正确的模式是分块,而正确的块大小是"小到没有任何一块会撞上限":

import requests
from datetime import date, timedelta

BASE = "https://api.socialapi.tech"
KEY  = "your_api_key"
HDRS = {"X-API-Key": KEY}

def search(query, limit=100):
    r = requests.get(f"{BASE}/v1/search/advanced",
                     params={"query": query, "product": "Latest", "limit": limit},
                     headers=HDRS, timeout=60)
    r.raise_for_status()
    return r.json()["data"]

def sweep(base_query, start, end, days=7):
    """分块走完一段时间区间,把看起来被截断的块再拆开。"""
    seen, out = set(), []
    cursor_date = start

    while cursor_date < end:
        chunk_end = min(cursor_date + timedelta(days=days), end)
        q = f"{base_query} since:{cursor_date} until:{chunk_end}"
        batch = search(q)

        # 一块返回得"满满当当",多半说明我们被截断了
        if len(batch) >= 95 and days > 1:
            half = max(days // 2, 1)
            out.extend(sweep(base_query, cursor_date, chunk_end, days=half))
        else:
            for post in batch:
                if post["id"] not in seen:
                    seen.add(post["id"])
                    out.append(post)

        cursor_date = chunk_end

    return out

posts = sweep("from:nasa", date(2026, 1, 1), date(2026, 7, 1), days=30)
print(f"{len(posts)} 条")
if posts:
    dates = sorted(p["created_at"] for p in posts)
    print(f"从 {dates[0]} 到 {dates[-1]}")

自适应拆分是关键。★ 固定块大小要么在安静时段浪费调用,要么在繁忙时段被截断。只在一块返回满了才拆,能在不到处花钱的前提下拿到完整性 —— 而调用次数正是成本的来源

无论如何都要去重。 块边界和上限行为都会产生重叠。 翻页和去重在每个端点上都是同一套做法


按日期搜索真正做不到的事

测量假象真实局限分开:

老内容会稀疏。 搜索严重偏向近期。回溯好几年时,无论你把窗口切多窄,时间区间返回的都是部分结果 —— 索引里就没有。★分块能解决截断,解决不了缺失。

已删除的推文没了。 任何时间区间都找不回来。见找老推文真正有效的办法

没有"几点"这个操作符。 since:/until: 收的是日期不是时间戳。要按小时切,就把那一天取下来,用 created_at 在本地过滤。

★诚实的结论:按日期搜索对近期是可靠的,越往回越不可靠。如果你需要可信的历史,就往前采集,而不是往回重建。


大家会问的问题

怎么按日期搜推文? 在查询里加 since:YYYY-MM-DDuntil:YYYY-MM-DD记住 until: 不含当天。

我的日期搜索为什么返回这么少? 几乎肯定是结果上限,不是那段时间真的空。把区间拆成更小的窗口再跑。

until: 包含当天吗? 不包含。它停在那天之前。想包含就加一天。

推特搜索用哪个时区? UTC。 如果你离 UTC 很远又在按天切片,把区间放宽再本地过滤

怎么搜某一天? since:2026-05-01 until:2026-05-02

按日期能回溯多久? 名义上到最早;实际上结果随年代迅速稀疏。最近几个月是可靠的。

能按一天中的时间搜吗? 操作符不能。把那一天取下来,用返回的时间戳过滤。

怎么找我自己某段时间的推文? from:你的用户名 since: until:真正久远的内容,你下载的存档更完整。

同一条日期查询跑两次为什么结果不同? 搜索本身有一定波动,而且被截断的区间里你拿到哪一片并不保证稳定。这也是要分块加去重的另一个理由。

日期搜索能和其它操作符组合吗? 能,全都可以 —— from:min_faves:filter: 等等。见完整操作符集

手机上怎么搜时间范围? 把操作符直接打进普通搜索框。 高级搜索表单在 App 里没有,但语法照样生效。

日期格式是什么? YYYY-MM-DD。★其它格式会静默失败或被忽略★,看起来就像"这个操作符不管用"。

能搜推特出现之前的日期吗? 2006 年之前的日期什么都不返回,这不意外。

怎么找某个话题的第一条推文? 设一个很宽的 until:,然后分块往回走。受索引深度限制,所以把结果当作"能找到的最早",而不是"第一条"。

不登录能按日期搜吗? 退出登录的搜索总体上被限制得很厉害 —— 见退出登录还能用什么

为什么我的时间区间返回了比要求更新的推文? 通常是格式写错导致操作符被忽略。检查是不是 YYYY-MM-DD,冒号周围有没有多余空格。

怎么导出一段时间的推文? 按上面的方式分块扫、去重、再写出去。

能按日期搜已删除的推文吗? 不能。删除会把它们从索引里彻底移除。

单条查询最多返回多少? 每条查询有上限 —— 而这恰恰是"分块比任何一个具体上限数字都更重要"的原因

怎么监控往后的一段时间? 不用日期搜索 —— 未来的内容要用监控而不是搜索时间区间是用来往回看的。

Latest 和 Top 的结果为什么不一样? 排序不同,而且实际返回的结果集也不同。要完整用 Latest,要显著用 Top。

怎么按日期找推文? since:until: 和关键词组合。两者都用 YYYY-MM-DD★,而且区间末端是不含的。

怎么找某一天的推文? since: 设成那天,until: 设成第二天。一天的窗口需要两个日期,不是一个。

怎么按日期给推文排序? 用 Latest 标签页 —— ★Top 会按热门度重排,那会悄悄破坏按时间阅读★。

怎么搜某个日期之前的内容? 单用 until:YYYY-MM-DD 就能界定上界,起点保持开放。

为什么一个日期区间返回得这么少?搜索的回溯本来就不可靠★ —— 限制是存档深度,不是你的查询。什么才真的能回溯

怎么按日期找推文? since:until: 配合关键词 —— ★两者都用 YYYY-MM-DD★。

怎么按日期查找推文? 同样的运算符。 ★框住你要的那一天,把上界设成第二天。★

怎么查某一个特定日期的推文? 一天的窗口需要两个日期 —— ★since: 设那天,until: 设第二天★。

怎么查看某个特定日期的推文? 同样的查询,在 Latest 标签页里读 —— ★Top 会重排并破坏时间顺序★。

怎么搜某个日期之前的内容? 单用 until:YYYY-MM-DD 界定上界,起点保持开放。

日期格式是什么?YYYY-MM-DD★ —— 其它格式会静默失败,而不是报错。

怎么搜一个日期区间? 两个运算符一起用 —— ★上界是不含的★,这正是人们会撞上的那个差一错误。

怎么按日期给帖子排序? 用 Latest。 ★没有单独的排序控件★ —— 标签页就是排序。

能把日期和账号组合吗? 能 —— from:用户名 since:… until:… —— 在一个账号内搜索

有按日期找推文的工具吗? 运算符就是那个工具。 ★叫这个名字的工具拼的是同一个查询串。★

能按日期搜我的收藏吗? 收藏只对你自己私密 —— ★没有任何外部工具能到达★。

为什么日期好像被忽略了? ★通常是格式问题,或者这个区间在搜索的地平线以下★ —— 先不带日期测一遍那个查询。


如果你要做时段分析

要防的失败模式不是报错,而是★看起来像真实数据的静默截断★。一个季度返回 40 条看起来很合理,没有任何东西会警告你它本该是 400 条

两条规则覆盖大部分情况:★块要小到没有窗口会返回满批★,以及★把任何"满批"都当成你被截断了的证据★。

我们的 API 接收同样的操作符语法,并在上面加了基于游标的翻页 —— 所以一个确实还有更多的块可以翻页,而不必重新拆分。只读、固定按次价格、没有属于你的限流要管。

延伸阅读:仍然有效的全部操作符 · 找回真正久远的推文 · 改用往前监控