我是Mongo DB的新手。谁能帮我获得两个给定日期之间的工作日数。
日期的$ dayOfWeek将给出日期0(星期日)和7(星期六)的值。
但是我的问题是如何从开始日期到结束日期增加日期以查找工作日数。
样本数据:
> db.data.insert({"startDate":ISODate('2016-0101'), "endDate":ISODate('2016-02-02')})
WriteResult({ "nInserted" : 1 })
> db.data.find().pretty()
{
"_id" : ObjectId("57c6e6a6a1e49d654caca17a"),
"startDate" : ISODate("2016-01-01T00:00:00Z"),
"endDate" : ISODate("2016-02-02T00:00:00Z")
}
现在需要找到开始日期(2016-01-01)和结束日期(2016-02-02)之间的工作日数。
我可以编写一个接受开始日期和结束日期的函数,但是在该函数中如何从开始日期到结束日期进行迭代?
需要任何帮助。
要查找两个日期之间的工作日总数,您可以从总天数中减去周末的总数。这里的主要问题是找到周末的总数。
范例[2016-12-23; 2017-01-01]
_Dec23 ___ Dec24 ___ Dec25 ____... ____ Dec30 ___ Dec31 ___ Jan01 ___...
__Fri ______ Sat _____ Sun ______...______ Fri _____ Sat _____ Sun _____...
如您所见,在这些日期之间有4个周末(Dec24,Dec25,Dec31和Jan01)。
解决方案
一种以编程方式解决此问题的方法是使用具有算术和日期聚合运算符的聚合框架。
可以通过将任务分为2个子任务来完成:
startDate
和endDate
(命名weeksBetween
)。在上面的例子中weeksBetween = 1
。startDate + 7 * weeksBetween
endDate
left
left = 3
left_weekends
left_weekends = 2
那么,周末的总数为2 * weeksBetween + left_weekends
。在上面的示例中为2 * 1 + 2 = 4
。
要找到left_weekends
您可以使用$ dayOfWeek 日期聚合运算符。
dayOfWeek = 1
,left_weekends = 1
如果left
为1,2,3,4,5或left_weekends = 2
如果left
为6(包括Sun和下一个星期六)。dayOfWeek = 2
,left_weekends = 0
如果left
为1,2,3,4或left_weekends = 1
如果left
为5或left_weekends = 2
如果left
为6(包括下一个星期六和星期日)。...
dayOfWeek = 7
和left_weekends = 2
任何left
。因此,我们可以使用以下规则:
如果remainder > 7
是的话left_weekends = 2
。
如果为remainder = 7
,则left_weekends = 1
适用于周一至周六和周日left_weekends = 2
。
如果是remainder < 7
这样left_weekends = 0
,则适用于周一和周六left_weekends = 1
。
在这里,remainder = dayOfWeek + left
。
询问
db.dates.aggregate(
{
$project:
{
"daysBetween":
{
$add: [
{
$floor:
{
$divide: [
{ $subtract: [ "$endDate", "$startDate" ] },
1000 * 60 * 60 * 24
]
}
},
1
]
},
"startDay": { $dayOfWeek: "$startDate" },
"endDay": { $dayOfWeek: "$endDate" }
}
},
{
$project:
{
"daysBetween": "$daysBetween",
"weeksBetween": { $floor: { $divide: [ "$daysBetween", 7 ] } },
"startDay": "$startDay",
"remainder":
{
$add: [
{ $abs: { $subtract: [ "$endDay", "$startDay" ] } },
"$startDay"
]
}
}
},
{
$project:
{
"weekendsBetween":
{
$add: [
{ $multiply: [ "$weeksBetween", 2 ] },
{
$cond:
{
if: { $gt: [ "$remainder", 7 ] },
then: 2,
else:
{
$cond:
{
if: { $eq: [ "$remainder", 7 ] },
then: 1,
else: 0
}
}
}
},
{ $cond: { if: { $eq: [ "$startDay", 1 ] }, then: 1, else: 0 } }
]
},
"daysBetween": "$daysBetween"
}
},
{
$project:
{
"weekdaysBetween": { $subtract: [ "$daysBetween", "$weekendsBetween" ] }
}
}
);
样本
{ "_id": 1, "startDate": ISODate("2016-12-23T00:00:00Z"),
"endDate": ISODate("2017-01-01T00:00:00Z") }
{ "_id": 2, "startDate": ISODate("2016-12-23T00:00:00Z"),
"endDate": ISODate("2017-01-09T00:00:00Z") }
{ "_id": 3, "startDate": ISODate("2016-12-23T00:00:00Z"),
"endDate": ISODate("2017-01-18T00:00:00Z") }
结果
{ "_id": 1, "weekdaysBetween" : 6 }
{ "_id": 2, "weekdaysBetween" : 12 }
{ "_id": 3, "weekdaysBetween" : 19 }
PS扩展上一$project
阶段,您还可以获取2个日期之间的总天数和周末。测试查询之前,请不要忘记更改集合名称。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句