# 日期表达式语法说明（DateExpressionParser）

本说明文档描述了 geotag 工具中用于筛选文件的“日期表达式”语法、功能和注意事项。

---

## 1. 表达式格式
- 表达式可以是任意布尔逻辑表达式，只要变量名为 `date`。
- 支持多条件、括号分组、and/or 逻辑。
- 例子：
  - `date > 20250101`
  - `date >= 2024-01-01 and date < 2025-01-01`
  - `date != 2025/05/25 or date = 2026-01-01`
  - `(date > 20240101 and date < 20250101) or date = 20251212`

## 2. 支持的比较运算符
- `>`、`>=`、`<`、`<=`、`=`、`==`、`!=`
- 运算符两侧允许有空格

## 3. 支持的日期格式
- 支持三种格式：
  1. **Unix 时间戳**（如 `1716633600`，单位为秒，直接与文件时间戳比较，适合精确到秒的场景）
  2. **仅日期**：`YYYYMMDD`、`YYYY-MM-DD`、`YYYY/MM/DD`
  3. **完整日期时间**：标准 ISO 8601 格式（如 `2025-05-25T12:34:56`）
- 比较时会自动将文件时间转为与表达式相同的精度（如遇到时间戳则精确到秒，遇到日期字符串则精确到天，遇到完整 datetime 则精确到秒）
- **时区说明**：所有日期和时间默认均按本地时区（local time）解析和比较。如需指定时区，必须使用 ISO 8601 格式（如 `2025-05-25T12:34:56+08:00`），否则均视为本地时区。

## 4. 逻辑运算
- 支持 `and`、`or`（不区分大小写）
- 支持括号 `()` 进行优先级分组

## 5. 变量
- 只允许 `date` 作为变量，表示“文件的日期”（通常为文件的修改时间）
- 表达式中可多次出现 `date`

## 6. 解析与转换
- 所有日期字符串在解析时会被转换为 `YYYYMMDD` 的整数形式
- 表达式会被转换为 Python 可 `eval` 的表达式，变量名为 `file_date`，如：
  - `date > 20250101 and date < 20260101`
  - 转换为：`file_date > 20250101 and file_date < 20260101`

## 7. 错误处理
- 表达式语法错误、日期格式错误、逻辑错误等，均会抛出异常并给出友好提示

## 8. 评估行为
- 传入一个 `datetime`，与表达式比较
- 返回布尔值，表示该日期是否满足表达式

---

### 典型用法举例

```python
parser = DateExpressionParser("date >= 20240101 and date < 20250101")
assert parser.evaluate(datetime(2024, 6, 1))  # True
assert not parser.evaluate(datetime(2025, 6, 1))  # False
```

---
