날짜 차이(집계)
정의
$dateDiff
버전 5.0에 추가.
두 날짜의 차이를 반환합니다.
$dateDiff
표현식의 구문은 다음과 같습니다.{ $dateDiff: { startDate: <Expression>, endDate: <Expression>, unit: <Expression>, timezone: <tzExpression>, startOfWeek: <String> } } endDate
에서startDate
를 뺍니다. 지정된unit
의 정수를 반환합니다.필드필수/선택 사항설명startDate
필수 사항endDate
필수 사항unit
필수 사항startDate
와endDate
간의 시간 측정unit
. 다음과 같은 문자열로 리졸브되는 표현식입니다.year
quarter
week
month
day
hour
minute
second
millisecond
timezone
옵션작업을 수행할 표준 시간대입니다. 은 Olson 표준 시간대
<tzExpression>
식별자 형식의 string 로 해석되는 유효한 표현식 이어야 합니다. 또는 UTC 오프셋 .timezone
이 제공되지 않으면 결과가UTC
에 표시됩니다.형식예시Olson 표준 시간대 ID"America/New_York" "Europe/London" "GMT" UTC 오프셋+/-[hh]:[mm], e.g. "+04:45" +/-[hh][mm], e.g. "-0530" +/-[hh], e.g. "+03" startOfWeek
옵션단위가
week
와(과) 같을 때 사용됩니다. 기본값은Sunday
입니다.startOfWeek
매개 변수는 대소문자를 구분하지 않는 문자열로 확인되는 표현식입니다.monday
(또는mon
)tuesday
(또는tue
)wednesday
(또는wed
)thursday
(또는thu
)friday
(또는fri
)saturday
(또는sat
)sunday
(또는sun
)
행동
분수 단위 없음
$dateDiff
표현식은 지정된 units
에서 측정된 startDate
과 endDate
간의 정수 차이를 반환합니다. 기간은 단위 경계를 통과한 횟수를 계산하여 측정됩니다. 예를 들어 18개월 간격의 두 날짜는 1.5 years
가 아닌 1 year
의 차이를 반환합니다.
주간 시작
week
의 시작은 startOfWeek
매개변수에 의해 수정되지 않는 한 Sunday
입니다. 지정된 날짜의 startDate
와 endDate
사이에 시작되는 모든 주가 계산됩니다. 주 수는 캘린더 month
또는 캘린더 year
에 의해 제한되지 않습니다.
시간대
<timezone>
필드에서 Olson 표준 시간대 ID를 사용할 때 MongoDB는 지정된 시간대에 적용 가능한 경우 DST 오프셋을 적용합니다.
예를 들어 sales
다음 문서가 있는 컬렉션을 생각해 보겠습니다.
{ "_id" : 1, "item" : "abc", "price" : 20, "quantity" : 5, "date" : ISODate("2017-05-20T10:24:51.303Z") }
다음 집계는 MongoDB가 Olson 시간대 식별자에 대한 DST 오프셋을 처리하는 방법을 보여 줍니다. 이 예시에서는 $hour
및 $minute
연산자를 사용하여 date
필드의 해당 부분을 반환합니다.
db.sales.aggregate([ { $project: { "nycHour": { $hour: { date: "$date", timezone: "-05:00" } }, "nycMinute": { $minute: { date: "$date", timezone: "-05:00" } }, "gmtHour": { $hour: { date: "$date", timezone: "GMT" } }, "gmtMinute": { $minute: { date: "$date", timezone: "GMT" } }, "nycOlsonHour": { $hour: { date: "$date", timezone: "America/New_York" } }, "nycOlsonMinute": { $minute: { date: "$date", timezone: "America/New_York" } } } }])
이 연산은 다음과 같은 결과를 반환합니다.
{ "_id": 1, "nycHour" : 5, "nycMinute" : 24, "gmtHour" : 10, "gmtMinute" : 24, "nycOlsonHour" : 6, "nycOlsonMinute" : 24 }
추가 세부 정보
이 알고리즘은 그레고리력을 사용하여 날짜 차이를 계산합니다.
윤년과 일광 절약 시간은 고려되지만 윤초는 고려되지 않습니다.
반환되는 차이는 음수일 수 있습니다.
예시
경과된 시간
고객 주문 컬렉션을 생성합니다.
db.orders.insertMany( [ { custId: 456, purchased: ISODate("2020-12-31"), delivered: ISODate("2021-01-05") }, { custId: 457, purchased: ISODate("2021-02-28"), delivered: ISODate("2021-03-07") }, { custId: 458, purchased: ISODate("2021-02-16"), delivered: ISODate("2021-02-18") } ] )
다음 예제입니다.
배송에 소요된 평균 일수를 반환합니다.
dateDiff
를 사용하여purchased
날짜와delivered
날짜 사이의 기간을 계산합니다.
db.orders.aggregate( [ { $group: { _id: null, averageTime: { $avg: { $dateDiff: { startDate: "$purchased", endDate: "$delivered", unit: "day" } } } } }, { $project: { _id: 0, numDays: { $trunc: [ "$averageTime", 1 ] } } } ] )
$group
단계의 $avg
축적자는 각 문서의 $dateDiff
를 사용하여 purchased
날짜와 delivered
날짜 사이에 있는 시간을 가져옵니다. 결과 값은 averageTime
으로 반환됩니다.
averageTime
의 소수 부분은 $project
단계에서 잘려($trunc
) 다음과 같은 출력을 생성합니다.
{ "numDays" : 4.6 }
결과 정밀도
구독의 시작 날짜와 종료 날짜를 사용하여 이 컬렉션을 만듭니다.
db.subscriptions.insertMany( [ { custId: 456, start: ISODate("2010-01-01"), end: ISODate("2011-01-01") }, { custId: 457, start: ISODate("2010-01-01"), end: ISODate("2011-06-31") }, { custId: 458, start: ISODate("2010-03-01"), end: ISODate("2010-04-30") } ] )
$dateDiff
표현식은 units
로 표현된 시간 차이를 정수로 반환합니다. 단위에는 분수가 존재하지 않습니다. 예를 들어, years
로 계산할 경우, 반년 값이 존재하지 않습니다.
이 예시에서는 unit
을 변경하면 반환되는 정밀도가 어떻게 달라지는지 확인합니다.
db.subscriptions.aggregate( [ { $project: { Start: "$start", End: "$end", years: { $dateDiff: { startDate: "$start", endDate: "$end", unit: "year" } }, months: { $dateDiff: { startDate: "$start", endDate: "$end", unit: "month" } }, days: { $dateDiff: { startDate: "$start", endDate: "$end", unit: "day" } }, _id: 0 } } ] )
결과는 이 표에 요약되어 있습니다.
시작하기 | End | 년 | 개월 | 일 |
---|---|---|---|---|
2010-01-01 | 2011-01-01 | 1 | 12 | 365 |
2010-01-01 | 2011-07-01 | 1 | 18 | 546 |
2010-03-01 | 2010-04-30 | 0 | 1 | 60 |
개수는 새로운 unit
이(가) 시작될 때만 증가하므로 두 번째 행에서 18개월은 1년으로 보고되고 세 번째 행에서 60일은 1개월로 보고됩니다.
월별 주 수
월 컬렉션을 생성합니다.
db.months.insertMany( [ { month: "January", start: ISODate("2021-01-01"), end: ISODate("2021-01-31") }, { month: "February", start: ISODate("2021-02-01"), end: ISODate("2021-02-28") }, { month: "March", start: ISODate("2021-03-01"), end: ISODate("2021-03-31") }, ] )
다음 코드를 사용해 각 주의 시작을 변경하고 이를 반영한 각 월의 주 수를 계산할 수 있습니다.
db.months.aggregate( [ { $project: { wks_default: { $dateDiff: { startDate: "$start", endDate: "$end", unit: "week" } }, wks_monday: { $dateDiff: { startDate: "$start", endDate: "$end", unit: "week", startOfWeek: "Monday" } }, wks_friday: { $dateDiff: { startDate: "$start", endDate: "$end", unit: "week", startOfWeek: "fri" } }, _id: 0 } } ] )
결과는 이 표에 요약되어 있습니다.
월 | Sunday | Monday | Friday |
---|---|---|---|
1월 | 5 | 4 | 4 |
2월 | 4 | 3 | 4 |
3월 | 4 | 4 | 4 |
결과에서 다음을 확인할 수 있습니다.
startOfWeek
가 일요일인 경우 2021년 1월의 다섯 번째week
는 31일에 시작됩니다.31일이 일요일이고
startDate
에서endDate
사이이므로 계산에week
이 하나 추가됩니다.endDate
이후 또는 다음 달력 기간에 해당 주가 끝나는 경우에도week
개수가 증가합니다.