1. 什么是日期时间处理 #
在实际应用中,我们经常需要处理日期、时间和持续时间。比如:
- 记录文章的发布时间
- 查找最近一周发布的内容
- 计算两个日期之间的间隔
- 筛选特定时间段的数据
1.1 前置知识:日期时间类型 #
Neo4j支持多种日期时间类型:
| 类型 | 说明 | 示例 | 使用场景 |
|---|---|---|---|
| DATE | 日期(年月日) | 2023-01-15 | 只关心日期,不关心具体时间 |
| DATETIME | 日期时间(带时区) | 2023-01-15T14:30:00Z | 需要精确时间,考虑时区 |
| LOCALDATETIME | 本地日期时间(无时区) | 2023-01-15T14:30:00 | 不需要时区的本地时间 |
| DURATION | 持续时间 | P3M30S(3分30秒) | 时间间隔、持续时间 |
1.2 为什么需要日期时间处理? #
日期时间处理可以帮助我们:
- 记录时间信息:保存数据的创建时间、更新时间等
- 时间筛选:查找特定时间段的数据
- 时间计算:计算时间差、添加时间间隔等
- 数据分析:按时间进行数据分析和统计
2. 创建日期和时间 #
在Cypher中,使用date()和datetime()函数来创建日期和时间。
2.1 前置知识:ISO 8601格式 #
ISO 8601是国际标准的日期时间格式:
- 日期格式:
YYYY-MM-DD(如:2023-01-15) - 日期时间格式:
YYYY-MM-DDTHH:mm:ssZ(如:2023-01-15T14:30:00Z) - 时区:Z表示UTC时区,+08:00表示东八区
2.2 创建日期(DATE) #
日期只包含年月日,不包含具体时间。
// 清空数据库
MATCH (n) DETACH DELETE n
// 创建带日期的节点
// 方式1:使用字符串创建日期
CREATE (article1:Article {title: '文章1', publishDate: date('2023-01-15')})
// 方式2:使用组件创建日期
CREATE (article2:Article {title: '文章2', publishDate: date({year: 2023, month: 2, day: 20})})
// 方式3:使用当前日期
CREATE (article3:Article {title: '文章3', publishDate: date()})
// 查询插入后的数据
MATCH (a:Article)
RETURN a.title, a.publishDate
// 查询最终结果
MATCH (a:Article)
RETURN a.title, a.publishDate
ORDER BY a.publishDate2.3 创建日期时间(DATETIME) #
日期时间包含年月日和具体时间,可以带时区。
// 清空数据库
MATCH (n) DETACH DELETE n
// 创建带日期时间的节点
// 方式1:使用字符串创建日期时间(带时区)
CREATE (event1:Event {name: '事件1', startTime: datetime('2023-01-15T14:30:00Z')})
// 方式2:使用组件创建日期时间
CREATE (event2:Event {name: '事件2', startTime: datetime({year: 2023, month: 1, day: 15, hour: 16, minute: 30, second: 0, timezone: 'UTC'})})
// 方式3:使用当前日期时间
CREATE (event3:Event {name: '事件3', startTime: datetime()})
// 查询插入后的数据
MATCH (e:Event)
RETURN e.name, e.startTime
// 查询最终结果
MATCH (e:Event)
RETURN e.name, e.startTime
ORDER BY e.startTime3. 创建持续时间 #
持续时间(Duration)表示时间间隔,比如"3分钟"、"7天"、"1小时30分钟"等。
3.1 前置知识:ISO 8601持续时间格式 #
ISO 8601持续时间格式:P[n]Y[n]M[n]DT[n]H[n]M[n]S
- P:表示持续时间开始
- Y:年(Years)
- M:月(Months)或分钟(Minutes)
- D:天(Days)
- T:分隔日期和时间部分
- H:小时(Hours)
- S:秒(Seconds)
示例:
PT3M30S:3分30秒P1Y2M3DT4H5M6S:1年2月3天4小时5分6秒P7D:7天
3.2 创建持续时间 #
// 清空数据库
MATCH (n) DETACH DELETE n
// 创建带持续时间的节点
// 方式1:使用ISO 8601格式字符串
CREATE (task1:Task {name: '任务1', duration: duration('PT3M30S')})
// 方式2:使用组件方式
CREATE (task2:Task {name: '任务2', duration: duration({days: 7, hours: 2, minutes: 30})})
// 方式3:只指定天数
CREATE (task3:Task {name: '任务3', duration: duration({days: 7})})
// 查询插入后的数据
MATCH (t:Task)
RETURN t.name, t.duration
// 查询最终结果
MATCH (t:Task)
RETURN t.name, t.duration4. 比较和筛选日期时间 #
可以使用比较运算符(=, <, >, <=, >=)来筛选特定日期时间范围的数据。
4.1 前置知识:日期时间比较 #
日期时间可以像数字一样进行比较:
date1 = date2:两个日期相等date1 > date2:date1晚于date2date1 < date2:date1早于date2date1 >= date2:date1晚于或等于date2date1 <= date2:date1早于或等于date2
4.2 筛选特定日期 #
// 清空数据库
MATCH (n) DETACH DELETE n
// 创建测试数据
CREATE (article1:Article {title: '文章1', publishDate: date('2023-01-15')}),
(article2:Article {title: '文章2', publishDate: date('2023-01-20')}),
(article3:Article {title: '文章3', publishDate: date('2023-02-10')})
// 查询插入后的数据
MATCH (a:Article)
RETURN a.title, a.publishDate
// 筛选特定日期(2023-01-20)
MATCH (a:Article)
WHERE a.publishDate = date('2023-01-20')
RETURN a.title, a.publishDate
// 查询最终结果
MATCH (a:Article)
WHERE a.publishDate = date('2023-01-20')
RETURN a.title, a.publishDate4.3 筛选日期范围 #
// 清空数据库
MATCH (n) DETACH DELETE n
// 创建测试数据
CREATE (article1:Article {title: '文章1', publishDate: date('2023-01-15')}),
(article2:Article {title: '文章2', publishDate: date('2023-01-20')}),
(article3:Article {title: '文章3', publishDate: date('2023-02-10')}),
(article4:Article {title: '文章4', publishDate: date('2023-02-25')})
// 查询插入后的数据
MATCH (a:Article)
RETURN a.title, a.publishDate
// 筛选日期范围(2023-01-20 到 2023-02-20)
MATCH (a:Article)
WHERE a.publishDate >= date('2023-01-20')
AND a.publishDate <= date('2023-02-20')
RETURN a.title, a.publishDate
ORDER BY a.publishDate
// 查询最终结果
MATCH (a:Article)
WHERE a.publishDate >= date('2023-01-20')
AND a.publishDate <= date('2023-02-20')
RETURN a.title, a.publishDate
ORDER BY a.publishDate4.4 筛选最近N天的数据 #
// 清空数据库
MATCH (n) DETACH DELETE n
// 创建测试数据(包含不同日期的文章)
CREATE (article1:Article {title: '文章1', publishDate: date() - duration({days: 3})}),
(article2:Article {title: '文章2', publishDate: date() - duration({days: 5})}),
(article3:Article {title: '文章3', publishDate: date() - duration({days: 10})}),
(article4:Article {title: '文章4', publishDate: date() - duration({days: 15})})
// 查询插入后的数据
MATCH (a:Article)
RETURN a.title, a.publishDate
// 筛选最近7天的数据
MATCH (a:Article)
WHERE a.publishDate >= date() - duration({days: 7})
RETURN a.title, a.publishDate
ORDER BY a.publishDate DESC
// 查询最终结果
MATCH (a:Article)
WHERE a.publishDate >= date() - duration({days: 7})
RETURN a.title, a.publishDate
ORDER BY a.publishDate DESC5. 日期时间计算 #
可以对日期时间进行加减运算,计算时间差等。
5.1 日期时间加减 #
// 清空数据库
MATCH (n) DETACH DELETE n
// 创建测试数据
CREATE (event1:Event {name: '事件1', startTime: datetime('2023-01-15T14:30:00Z')})
// 查询插入后的数据
MATCH (e:Event)
RETURN e.name, e.startTime
// 计算结束时间(开始时间 + 2小时)
MATCH (e:Event)
SET e.endTime = e.startTime + duration({hours: 2})
RETURN e.name, e.startTime, e.endTime
// 计算提醒时间(开始时间 - 30分钟)
MATCH (e:Event)
SET e.reminderTime = e.startTime - duration({minutes: 30})
RETURN e.name, e.startTime, e.reminderTime
// 查询最终结果
MATCH (e:Event)
RETURN e.name, e.startTime, e.endTime, e.reminderTime5.2 计算时间差 #
// 清空数据库
MATCH (n) DETACH DELETE n
// 创建测试数据
CREATE (event1:Event {name: '事件1', startTime: datetime('2023-01-15T14:30:00Z'), endTime: datetime('2023-01-15T16:30:00Z')})
// 查询插入后的数据
MATCH (e:Event)
RETURN e.name, e.startTime, e.endTime
// 计算持续时间(结束时间 - 开始时间)
MATCH (e:Event)
RETURN e.name,
e.startTime,
e.endTime,
e.endTime - e.startTime AS duration
// 查询最终结果
MATCH (e:Event)
RETURN e.name, e.startTime, e.endTime, e.endTime - e.startTime AS duration6. 小结 #
6.1 核心概念 #
| 概念 | 说明 | 主要用途 |
|---|---|---|
| DATE | 日期(年月日) | 只关心日期,不关心具体时间 |
| DATETIME | 日期时间(带时区) | 需要精确时间,考虑时区 |
| DURATION | 持续时间 | 时间间隔、持续时间 |
6.2 最佳实践 #
- 使用DATE存储日期:当只需要日期时,使用DATE而不是DATETIME
- 使用DATETIME存储时间戳:当需要精确时间时,使用DATETIME
- 使用ISO 8601格式:遵循国际标准格式,便于处理
- 使用DURATION进行时间计算:使用DURATION进行时间加减运算
6.3 常见用法 #
- 使用date()创建日期
- 使用datetime()创建日期时间
- 使用duration()创建持续时间
- 使用比较运算符筛选日期时间范围
- 使用日期时间进行加减运算