文章目录
-
- 语法
- 使用
- 举例
-
- 日期转换
- 错误处理onError
-
- [空值的粗粒 onNull](#空值的粗粒 onNull)
$dateFromString
聚合运算符将日期时间字符串转换为日期对象。
语法
js
{ $dateFromString: {
dateString: <dateStringExpression>,
format: <formatStringExpression>,
timezone: <tzExpression>,
onError: <onErrorExpression>,
onNull: <onNullExpression>
} }
参数字段说明:
字段 | 必须 | 说明 |
---|---|---|
dateString |
如果没有用isoWeekYear 则必须 |
日历年度,可以是任何能解析为整数的表达式,值域为:1~9999,如果超出范围将报错。从4.4以后最小值为1,再之前的版本最小值是0 |
format |
若year没有用则必须 | ISO的周日期年,可以是任何能解析为整数的表达式,值域为:1~9999,如果超出将报错。从4.4以后最小值为1,再之前的版本最小值是0 |
timezone |
可选 | 执行操作的时区,<timezone> 可以是任何能被解析为:Olson时区标识符或UTC偏移量 |
onError |
可选 | 在解析dateString 时如果出错,则输出onError 表达式的结果,结果值可以是任意类型 |
onNull |
可选 | 如果dateString 为null 或不存在,则输出onNull 表达式的结果,可以是任意类型 |
使用
使用例子对规则进行说明
例1:
js
{ $dateFromString: {
dateString: "2017-02-08T12:10:40.787"
} }
结果:ISODate("2017-02-08T12:10:40.787Z")
例2:
js
{ $dateFromString: {
dateString: "2017-02-08T12:10:40.787",
timezone: "America/New_York"
} }
结果:ISODate("2017-02-08T12:10:40.787Z")
例3:
js
{ $dateFromString: {
dateString: "2017-02-08"
} }
结果:ISODate("2017-02-08T00:00:00Z")
例4:
js
{ $dateFromString: {
dateString: "oct 20 2020"
} }
结果:ISODate("2020-10-20T00:00:00.000Z")
例5:
js
{ $dateFromString: {
dateString: "06-15-2018",
format: "%m-%d-%Y"
} }
结果:ISODate("2018-06-15T00:00:00Z")
例6:
{ $dateFromString: {
dateString: "15-06-2018",
format: "%d-%m-%Y"
} }
结果:ISODate("2018-06-15T00:00:00Z")
js
{ $dateFromString: {
dateString: "WED jan 31 12:05:28 +03:30 1996"
} }
结果:ISODate("1996-01-31T08:35:28.000Z")
格式指示符
指示符 | 描述 | 可能的值 |
---|---|---|
%b | 月份缩写(3个字符) | jan , feb , mar , apr , may , jun , jul , aug , sep , oct , nov , dec |
%B | 完整月份 | january -december |
%d | 一个月内的第几天(2个数字,0填充) | 01 -31 |
%G | ISO8601格式 年 | 0000-9999 |
%H | 小时(2个数字,0填充,24小时时钟) | 00-23 |
%j | 一年内的第几天(3个数字,0填充) | 001-366 |
%L | 毫秒(3个数字,0填充) | 000=999 |
%m | 月(2个数字,0填充) | 01-12 |
%M | 分钟(2个数字,0填充) | 00-59 |
%S | 秒(2个数字,0填充) | 00-60 |
%u | ISO8601格式的一周内的第几天 | 1-7 |
%U | 一年内的第几周(2个数字,0填充) | 00-53 |
%V | ISO8601格式的一年内的第几周 | 1-53 |
%w | 一周内的第几天(整数,0-Sunday,6-Saturday) | 0-6 |
%Y | 年(4个数字,0填充) | 0000-9999 |
%z | 时区与UTC的偏移量 | +/-[hh][mm] |
%Z | 从 UTC 开始的分钟偏移量,用数字表示。例如,如果时区偏移(+/-[hhmm])为 +0445 ,则分钟偏移为+285 。 |
+/-mmm |
%% | 百分比字符作为字面值 | % |
举例
日期转换
集合logmessages
包含下面的数据:
js
{ _id: 1, date: "2017-02-08T12:10:40.787", timezone: "America/New_York", message: "Step 1: Started" },
{ _id: 2, date: "2017-02-08", timezone: "-05:00", message: "Step 1: Ended" },
{ _id: 3, message: " Step 1: Ended " },
{ _id: 4, date: "2017-02-09", timezone: "Europe/London", message: "Step 2: Started"},
{ _id: 5, date: "2017-02-09T03:35:02.055", timezone: "+0530", message: "Step 2: In Progress"}
下面的聚合使用$dateFromString
将日期值转换为日期对象:
js
db.logmessages.aggregate( [ {
$project: {
date: {
$dateFromString: {
dateString: '$date',
timezone: 'America/New_York'
}
}
}
} ] )
上述汇总返回以下文档,并将每个日期字段转换为东部时区:
json
{ "_id" : 1, "date" : ISODate("2017-02-08T17:10:40.787Z") }
{ "_id" : 2, "date" : ISODate("2017-02-08T05:00:00Z") }
{ "_id" : 3, "date" : null }
{ "_id" : 4, "date" : ISODate("2017-02-09T05:00:00Z") }
{ "_id" : 5, "date" : ISODate("2017-02-09T08:35:02.055Z") }
也可以通过文档字段提供时区参数,而不是硬编码参数。例如:
js
db.logmessages.aggregate( [ {
$project: {
date: {
$dateFromString: {
dateString: '$date',
timezone: '$timezone'
}
}
}
} ] )
上述汇总返回以下文档,并将每个date
字段转换为各自的 UTC 表示形式。
json
{ "_id" : 1, "date" : ISODate("2017-02-08T17:10:40.787Z") }
{ "_id" : 2, "date" : ISODate("2017-02-08T05:00:00Z") }
{ "_id" : 3, "date" : null }
{ "_id" : 4, "date" : ISODate("2017-02-09T00:00:00Z") }
{ "_id" : 5, "date" : ISODate("2017-02-08T22:05:02.055Z") }
错误处理onError
如果文档集中包含不可解析日期字符串的文档,则$dateFromString
会出错,除非给参数onError
提供一个聚合表达式。
例如,给定一个包含以下文档的日期集合:
json
{ "_id" : 1, "date" : "2017-02-08T12:10:40.787", timezone: "America/New_York" },
{ "_id" : 2, "date" : "20177-02-09T03:35:02.055", timezone: "America/New_York" }
可以使用onError
参数以原始字符串形式返回无效日期:
js
db.dates.aggregate( [ {
$project: {
date: {
$dateFromString: {
dateString: '$date',
timezone: '$timezone',
onError: '$date'
}
}
}
} ] )
返回的文档如下:
json
{ "_id" : 1, "date" : ISODate("2017-02-08T17:10:40.787Z") }
{ "_id" : 2, "date" : "20177-02-09T03:35:02.055" }
空值的粗粒 onNull
如果集合文档包含空日期字符串,$dateFromString
返回空,除非给onNull
指定一个聚合表达式。
例如,集合dates
有以下文档:
json
{ "_id" : 1, "date" : "2017-02-08T12:10:40.787", timezone: "America/New_York" },
{ "_id" : 2, "date" : null, timezone: "America/New_York" }
可以使用onNUll
参数让$dateFromString
返回代表unix纪元的日期,而不是空值:
js
db.dates.aggregate( [ {
$project: {
date: {
$dateFromString: {
dateString: '$date',
timezone: '$timezone',
onNull: new Date(0)
}
}
}
} ] )
返回下面的结果:
json
{ "_id" : 1, "date" : ISODate("2017-02-08T17:10:40.787Z") }
{ "_id" : 2, "date" : ISODate("1970-01-01T00:00:00Z") }