> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 时间操作符

> 使用时间操作符发送相对于特定时刻的消息——例如事件发生后或即将到来的日期前。

## 概述

时间操作符让您能够发送相对于特定时刻的消息——例如**事件发生后**或**即将到来的日期前**。

您将该时刻作为**Unix时间戳（秒）**使用**标签**存储在用户上。OneSignal然后将当前时间与该时间戳进行比较，并让您根据已过去的时间（或剩余时间）来定位用户。

这使得自动化提醒、跟进和截止日期消息变得容易，无需手动安排消息。

**常见用例：**

* **[购物车放弃](./abandoned-cart)**：提醒在特定时间后未结账的用户
* **事件提醒**：在预定约会或续订日期前向用户发送消息
* **里程碑**：当用户在截止日期前未完成某项操作时进行跟进
* **生日**：在用户生日（或生日前后）发送自动消息

<Note>
  时间操作符仅在付费计划中可用。免费计划仍可以使用默认的基于时间的细分过滤器，如首次会话和最后会话。
</Note>

### 何时应该使用此功能？

在以下情况下使用时间操作符：

* 发送**相对于事件**的消息，而不是固定的日历时间
* 创建**移动时间窗口**（例如，"24-48小时后"）
* 为许多具有不同日期的用户重用相同的逻辑
* 随着时间推移持续评估资格

如果您需要在事件发生时立即触发消息，请考虑使用\*\*[自定义事件](./custom-events)\*\*。

### 标签 vs 自定义事件

您可以使用**标签**或**自定义事件**解决许多"提醒"用例。最佳选择取决于您需要存储的内容以及如何触发自动化。

* 当您想要在用户上存储**最新已知时间戳**（例如，`cart_updated_at` 或 `subscription_expires_at`）并根据该值随时间进行细分时，使用**标签**。
* 当您想要记录**每次事件发生**（带属性）并基于实时行为触发旅程时，使用**自定义事件**。

<Info>
  在实践中，许多实现可以同时使用两者：自定义事件用于实时追踪，标签用于以后要进行细分的用户状态。
</Info>

[标签](/docs/en/add-user-data-tags)和[自定义事件](/docs/en/custom-events)都是向用户添加数据的方式。但是，它们之间存在一些关键区别：

| 功能      |             标签            |                          自定义事件                         |
| ------- | :-----------------------: | :----------------------------------------------------: |
| 数据用途    |           细分和个性化          |               无需细分即可触发旅程、等待步骤、直接在旅程中实现个性化              |
| 数据 保留期限 |             永久            | 30天以上（[提供永久存储](/docs/en/billing-faq#streaming-events)） |
| 数据格式    |         键值对字符串或数字         |                          JSON                          |
| 数据来源    | OneSignal SDK、API 或集成（有限） |                  OneSignal SDK、API 或集成                 |
| 数据访问    |          细分和消息个性化         |                  旅程和旅程消息模板个性化、细分（即将推出）                 |

标签和自定义事件之间的关键区别在于它们的深度和使用场景。标签是用户的属性，例如姓名、账户状态或位置。事件是用户已完成的操作，例如购买商品、完成关卡或邀请好友。标签和事件都可用于细分和个性化。

在实际应用中，您可能会同时使用两者：

* 标签用于静态且不经常更改的用户属性
* 自定义事件用于实时场景、复杂细分和更复杂的旅程工作流

***

## 快速参考

1. 将事件日期转换为以**秒**为单位的Unix时间戳。
2. 设置一个[标签](./add-user-data-tags)，其中键是事件名称，值是时间戳作为**字符串**（例如，`'event_date': '1739145600'`）。
3. 使用**Time Elapsed Greater Than**操作符创建细分：
   * 对于过去日期之后，使用**Time Elapsed Greater Than**操作符和正值
   * 对于未来日期之前，使用**Time Elapsed Greater Than**操作符和负值

<Warning>
  常见错误是将时间戳设置为**毫秒**（13位数字）而不是**秒**（10位数字）。时间操作符需要**秒**。
</Warning>

***

## 在过去事件后发送消息

当您想要在某事发生后**经过一定时间后**向用户发送消息时，使用此模式。

**示例：在用户更新购物车24小时后发送购物车放弃提醒**

<Steps>
  <Step title="在事件发生时存储时间戳">
    当用户更新其购物车时，将当前时间保存为Unix时间戳（秒）：

    ```javascript theme={null}
    // SDK 示例
    const timestampSeconds = String(Math.floor(Date.now() / 1000));
    OneSignal.User.addTag("cart_updated_at", timestampSeconds);
    ```

    <Warning>
      使用秒（10位数字），不是毫秒（13位数字）。
    </Warning>
  </Step>

  <Step title="创建细分">
    1. 转到**Audience** > **Segments**
    2. 添加**User Tag**过滤器
    3. 将**Key**设置为`cart_updated_at`
    4. 选择**Time Elapsed Greater Than**
    5. 将**Value**设置为`1`天（或`24`小时或`86400`秒）

    <Frame caption="针对24小时前放弃购物车的用户的细分">
      <img src="https://mintcdn.com/onesignal/BIUS_wdfwITxcuxQ/images/segments/time-elapsed-greater-than.png?fit=max&auto=format&n=BIUS_wdfwITxcuxQ&q=85&s=fd95aaf5b4ff3d4ebf594af867a594c8" alt="使用Time Elapsed Greater Than的细分" width="1311" height="617" data-path="images/segments/time-elapsed-greater-than.png" />
    </Frame>
  </Step>

  <Step title="添加上限（推荐）">
    没有上限，用户将永远保留在细分中。添加第二个过滤器来创建窗口：

    * **Time Elapsed Greater Than** `24`小时
    * **Time Elapsed Less Than** `48`小时

    现在用户只在事件后24-48小时之间在细分中。

    <Frame caption="具有24-48小时窗口的细分">
      <img src="https://mintcdn.com/onesignal/BIUS_wdfwITxcuxQ/images/segments/time-elapsed-greater-less-than.png?fit=max&auto=format&n=BIUS_wdfwITxcuxQ&q=85&s=3cb973d5b0252683e9f804e4b04a37b4" alt="同时使用Time Elapsed Greater Than和Less Than的细分" width="1292" height="715" data-path="images/segments/time-elapsed-greater-less-than.png" />
    </Frame>
  </Step>

  <Step title="在旅程中使用细分">
    创建一个定位您细分的[旅程](./journeys-overview)来自动化消息传递。
  </Step>
</Steps>

***

## 在未来事件前发送消息

使用此模式在**即将到来的日期前**向用户发送消息，例如约会或续订。

1. 将未来日期存储为Unix时间戳标签（例如，`'future_date': '1739145600'`）
2. 使用**Time Elapsed Greater Than**和您所需的进入时间作为负值创建细分
   * 示例：`-2`天（或`-172800`秒）

<Frame caption="针对即将到来事件的用户的细分">
  <img src="https://mintcdn.com/onesignal/BIUS_wdfwITxcuxQ/images/segments/time-elapsed-greater-than-negative-value.png?fit=max&auto=format&n=BIUS_wdfwITxcuxQ&q=85&s=bea6fe1e5d4a2d3349fe05674946b910" alt="使用负值的Time Elapsed Greater Than的细分" width="1291" height="618" data-path="images/segments/time-elapsed-greater-than-negative-value.png" />
</Frame>

3. 使用相同的**Time Elapsed Greater Than**操作符和更近时间的负值添加上限
   * 示例：`-1`天（或`-86400`秒）

<Frame caption="具有上限的细分">
  <img src="https://mintcdn.com/onesignal/BIUS_wdfwITxcuxQ/images/segments/time-elapsed-greater-than-negative-value-upper-limit.png?fit=max&auto=format&n=BIUS_wdfwITxcuxQ&q=85&s=406246bb0136f1997ababc06a638408f" alt="使用负值和上限的Time Elapsed Greater Than的细分" width="1286" height="703" data-path="images/segments/time-elapsed-greater-than-negative-value-upper-limit.png" />
</Frame>

### 示例：生日消息

通过存储每个用户的**下一个即将到来的生日**作为时间戳来发送生日消息。

<Steps>
  <Step title="存储下一个生日时间戳">
    计算并存储用户的下一个即将到来的生日：

    ```javascript theme={null}
    function getNextBirthday(month, day) {
      // month: 0-11 (Jan=0), day: 1-31
      const now = new Date();
      let birthday = new Date(now.getFullYear(), month, day);

      if (birthday <= now) {
        birthday = new Date(now.getFullYear() + 1, month, day);
      }

      return String(Math.floor(birthday.getTime() / 1000));
    }

    // 示例：1月15日生日
    OneSignal.User.addTag("birthday", getNextBirthday(0, 15));
    ```
  </Step>

  <Step title="创建生日细分">
    * **User Tag**：`birthday`
    * **Time Elapsed Greater Than**：`0`秒

    一旦生日时间戳过去，用户就会进入细分。

    <Frame caption="生日细分">
      <img src="https://mintcdn.com/onesignal/BIUS_wdfwITxcuxQ/images/segments/birthday-segment.png?fit=max&auto=format&n=BIUS_wdfwITxcuxQ&q=85&s=6f431d2f592779f74a5b4e27045ad984" alt="使用Time Elapsed Greater Than 0的生日细分" width="1287" height="602" data-path="images/segments/birthday-segment.png" />
    </Frame>
  </Step>

  <Step title="设置定期旅程">
    1. 创建一个定位您生日细分的[旅程](./journeys-overview)
    2. 将重新进入设置为**52周**，以便用户可以在明年重新进入
    3. 在发送后更新`birthday`标签为明年的日期（在您的后端或旅程中）
  </Step>
</Steps>

<Note>
  尽可能使用用户的本地时区计算生日时间戳。仅使用服务器时间可能会导致消息比预期更早或更晚发送。
</Note>

<Warning>
  如果您希望消息年复一年保持准确，请在发送消息后将用户的`birthday`标签更新为下一个即将到来的生日（例如，在您的后端或旅程步骤中）。请记住，如果您这样做，使用[自定义事件](./custom-events)可能更容易。
</Warning>

<Check>
  生日消息将在用户`birthday`标签日期附近发送给用户。
</Check>

***

## FAQ

### 数学是如何工作的？（技术详细信息）

时间操作符存在是为了让您创建**相对的、移动的窗口**而不是固定日期。

OneSignal使用此公式计算经过时间：

```
time_elapsed = current_time - tag_timestamp
```

* **过去的时间戳** → 正值
* **未来的时间戳** → 负值

**操作符：**

* `Time Elapsed Greater Than X`：当`elapsed > X`时匹配
* `Time Elapsed Less Than X`：当`elapsed < X`时匹配

**为什么未来时间戳用`Less Than`立即匹配：**

任何负数都小于任何正数。所以`time_elapsed_lt 2 days`（172,800秒）会匹配未来30天的时间戳，因为：

```
-2,592,000 < 172,800  →  true（匹配）
```

因为未来时间戳总是产生负的经过时间，**您必须使用负值**来定义用户应该在即将到来的事件前进入和退出细分的时间。正值无法表示未来日期\_之前\_的时间。

### 如何测试？

1. 通过外部ID、订阅ID、电子邮件或电话号码查找您的用户。有关查找用户的详细信息，请参阅[查找和设置测试订阅](./test-users)。
2. 获取当前日期和未来日期（从现在开始5分钟）的以秒为单位的时间戳。
3. 设置两个标签，键为'current\_time'和'future\_time'，值为以秒为单位的时间戳。
4. 创建一个`current_time`细分，包含以下过滤器：
   * **User Tag**：`current_time` **Time Elapsed Greater Than**：`2`分钟
   * AND **User Tag**：`current_time` **Time Elapsed Less Than**：`5`分钟
5. 创建一个`future_time`细分，包含以下过滤器：
   * **User Tag**：`future_time` **Time Elapsed Greater Than**：`-5`分钟
   * AND **User Tag**：`future_time` **Time Elapsed Less Than**：`-2`分钟

您应该看到您的用户：

* 在当前时间日期后2分钟进入`current_time`细分，在当前时间日期后5分钟退出细分。
* 在未来时间日期前5分钟进入`future_time`细分，在未来时间日期前2分钟退出细分。

***
