Differences between weekNumber in Mongo and Luxon - mongodb

I am doing some mongo aggregations on dates and have run in to an interesting problem, namely that the $week returned from mongo is different than the weekNumber returned from Luxon.
In the below code snippets, the $week from mongo returns 47, whereas the weekNumber from Luxon returns 48.
Is there a way to normalize the two so that a given date will return the same $week/weekNumber?
I can subtract one from the value returned by Luxon, but I'd like to understand why the responses are different in order to determine if there is a more appropriate/elegant way to fix this.
MONGO:
[{
'$match': {
'date': {
'$eq': datetime(2020, 11, 23, 0, 0, 0, tzinfo=timezone.utc)
}
}
}, {
'$project': {
'w': {
'$week': '$date'
}
}
}]
LUXON:
import { DateTime } from "luxon";
var week = DateTime.fromJSDate(new Date(2020,10,23)).weekNumber;
console.log(week);

Have a look at documentation:
weekNumber:
Week calendar: For ISO week calendar attributes, see the weekYear, weekNumber, and weekday accessors.
$week:
Returns the week of the year for a date as a number between 0 and 53.
Weeks begin on Sundays, and week 1 begins with the first Sunday of the year. Days preceding the first Sunday of the year are in week 0. This behavior is the same as the “%U” operator to the strftime standard library function.
If you like to get to Week number according to ISO-8601 use $isoWeek():
Returns the week number in ISO 8601 format, ranging from 1 to 53. Week numbers start at 1 with the week (Monday through Sunday) that contains the year’s first Thursday.
Looks like in Luxon does not have an equivalent to MongoDB's $week

Related

Converting StringDate to a queryable representation. Group and project sum of today,yesterday, week, month

I was about to try to figure out how to complete the given question.
It might consists of 2 parts, first one being - my collection dates are stored in plain string with a mysql format (YYYY-mm-dd HH:mm:ss), the second how to project the (today, yesterday, 7 day, month - summaries).
I have been experimenting around and this is what I came up with.
Pipe 1.
$match - nothing fancy there just a simple field = value.
Pipe 2.
$addField - trying to process the string date as a ISO date I believe? I am not sure
{
expired: {
$dateFromString: {
dateString: '$expired',
timezone: 'America/New_York'
}
}
}
Pipe 3.
$match - Quoted out wanted to select only a specific range so not more than 30 days - doesn't work
expired: {
$gt: ISODate(new Date(new Date(ISODate().getTime() - 1000*60*60*24*30)))
}
Pipe 4.
$group - Here I group and sum everything per day. So an output is
_id: 2021-09-27, theVal : 100
{
_id: {
$dateToString: {
date: { $toDate: "$expired" },
format: "%Y-%m-%d" }
},
theVal : {$sum:{$first:"$values.quantity"}} // as $values is an array [0].quantity,[1].quantity,[2].quantity - I am just interested in the first element.
}
Pipe 5.
$project - getting rid of the _id field - making it date name field, keeping theVal.
{
"date": "$_id",
"theVal": 1,
"_id": 0
}
theVal is a sum of integers within a day.
Questions
Between Pipe 1 and 2 ( temporary 3 ) I should be able to match dates
within the last 30 days to reduce the processing?
How to get a desired output like this:
{
today : 100,
yesterday : 10,
7days : 220,
month: 1000,
}
Really appreciate any help here.
Tried to "replicate" what you intend to do as you didn't provided sample test data.
You may want to do the followings in an aggregation pipeline:
$match : filter out the ids you want - same as your pipe 1
$dateFromString: use "format": "%Y-%m-%d %H:%M:%S", "timezone": "America/New_York"
$match : filter out records that are within 30 days with $expr and $$NOW
$group : group by date without time; achieved by converting to dateString with date part only
$addFields : project flags that determine if the record are within today, ``yesterday, 7days, month`
$group : As you didn't provided what is the meaning of today, ``yesterday, 7days, month, I made an assumption that they are the cumulative sum in the ranges. Simply and conditional $sum` will do the summation with the help of flags in step 5
Here is a Mongo playground for your reference.

Mongo find next Tuesday

I'm trying to get the next Tuesday (day 2 of ISO Week) from today on. I have the current date from the global var "$$NOW" and the current day of ISO Week by the following operator: { $dayOfWeek: "$$NOW" }. But I can't think of any way to get the date of the next Tuesday in MongoDB-Aggregation.
For example i have as Input:
"$$NOW" which is => new Date("2021-09-13T16:20:00Z") // Today Monday
And now I want to get the next Tuesday:
new Date("2021-09-14T16:20:00Z") // coming Tuesday
which is quite easy, but if there is a week shift, it gets a bit more difficult. If the NOW date would be:
"$$NOW" which is => new Date("2021-09-16T16:20:00Z") // coming Thursday would be Today
the next Tuesday would be the:
new Date("2021-09-21T16:20:00Z") // Tuesday next week
So I always want to get the next following Tuesday after Today.
At the end, I want to create a mongo pipeline like this:
[{
$addFields: {
"nextTuesday": new Date(" the date of the next Tuesday ")
}
}]
I would be very happy about any help!
MongoDB has the $dayOfWeek operator that returns 1 for Sunday, 7 for Saturday.
On that scale, the formula to find a desired day of the week would be:
(((desired_day + 6) - current_day) modulo 7) + 1
Which in the MongoDB aggregation language, would look like:
{$addFields:{
nextTuesday:{
$toDate:{
$add:[
"$$NOW",
{$multiply:[
86400000,
{$add:[
1,
{$mod:[
{$subtract:[
9,
{$dayOfWeek:"$$NOW"}
]},
7
]}
]}
]}
]
}
}
}}
Playground

Countif date includes year, month or day

I have a column containing dates in a Google sheet. How can I count the number of dates that include a specific year, month or day?
I have tried the following: =COUNTIF(G:G, YEAR(2000)) which just returns a zero, although there are multiple dates in the year 2000 in that column.
All the best!
year:
=INDEX(COUNTIF(YEAR(G:G), 2000))
month:
=INDEX(COUNTIF(MONTH(G:G), 11))
=INDEX(COUNTIFS(MONTH(G:G), 12, G:G, "<>"))
day:
=INDEX(COUNTIF(DAY(G:G), 27))
weekday:
=INDEX(COUNTIF(WEEKDAY(G:G, 1), 7))

Mongoose query by current date

So I have a mongoose collection. This collection have a day property in it.
So let's say I have 3 documents in it:
{day: "2017-07-16T17:00:00.000Z"}
{day: "2017-07-17T17:00:00.000Z"}
{day: "2017-07-18T17:00:00.000Z"}
Each date has hardcoded 17:00 time in it. Consider this as the start time.
So let's say currentDate is 2017.07.17 and it's 16h. I need to return document that has day that is 16th, because of the time.
Next one starts in an hour, and in an hour I should be returning the 17th.
I tried:
Table.find({ day: { $lt: Date.now() } })
But this, on the 18th, still returns 16th.
How do I write this query so it returns document that is currently 'active' ?

$week mongodb to datepart(wk)

I'm exporting aggregated data to MS SQL server from mongodb
mongo's $week does not evaluate to the same week as T-SQL datepart(wk, ) or datepart(isowk, ).
Does anyone know how to test the mongodb $week function so I can do some comparisons and see how best to resolve this issue?
Any help would be appreciated.
As far as I can see the differences fall into two main areas, the plain part being described in the documentation:
Weeks begin on Sundays, and week 1 begins with the first Sunday of the year. Days preceding the first Sunday of the year are in week 0. This behavior is the same as the “%U” operator to the strftime standard library function.
So the general concept here is that the value returned will be between 0 and 53 inclusive with week 0 being defined as the first week when the days are before Sunday.
So to paraphrase ( because the documentation gets the days wrong ) from the technet source for "datepart":
January 1 of any year defines the starting number for the week datepart, for example: DATEPART (wk, 'Jan 1, xxxx') = 1, where xxxx is any year.
And then (corrected):
The following table lists the return value for week and weekday datepart for '2007-04-21 ' for each SET DATEFIRST argument. January 1 is a Saturday in the year 2007. April 21 is a Saturday in the year 2007. SET DATEFIRST 7, Sunday, is the default for U.S. English.
So where you had documents like this:
{ "date" : ISODate("2007-01-01T00:00:00Z") }
{ "date" : ISODate("2006-12-31T00:00:00Z") }
{ "date" : ISODate("2006-01-01T00:00:00Z") }
The $week operator would return such as this:
{ "date" : ISODate("2007-01-01T00:00:00Z"), "week" : 0 }
{ "date" : ISODate("2006-12-31T00:00:00Z"), "week": 53 }
{ "date" : ISODate("2006-01-01T00:00:00Z"), "week" : 1 }
January 1st in 2006 was a Sunday and is considered the start of week 1, but where it was a Saturday it would be week 0 of 2007. The 31st of December in the previous year is Week 53.
In contrast the DATEPART considers Jan 1st 2007 and Dec 31st 2006 to be in Week 1 as the week ending on the first Sunday of the year. The Sunday is the default US English value but may differ and can in fact be set via SET DATEFIRST
So both have different opinions of where a date belongs in terms of the week of the year, but the general difference will be one with the other consideration days falling at the end of the previous year.