2

Struggling with creating a condition to check if 30 days have passed since specified ISODate in mongo.

The field name is creationDate, Im using find function, and I want to find only these, where 30 days have passed from creation date.

User.find({ 
   creationDate: {
      $gte: ...
   }
});

In Javascript I would simply do something like

(+new Date() - +new Date(creationDate))/60/60/24 >= 30

In a brief, I want to find only these elements, where 30 days have passed from creating it in mongo db. Looking for any kind of help!

Patrickkx
  • 1,740
  • 7
  • 31
  • 60

3 Answers3

7

I think you just need calculate the 30 days before current time, and use it as the condition as follows:

let fromDate = new Date(Date.now() - 60 * 60 * 24 * 30 * 1000);
User.find({
  creationDate: {
    $gte: fromDate
  }
});
Steve Gao
  • 585
  • 2
  • 5
  • 24
  • Nice. But it doesnt matter that `new Date` is `Date` object and mongodb uses `ISODate` object? – Patrickkx Mar 26 '19 at 23:59
  • 1
    @Patrickkx ISODate() is a helper function that's built into to MongoDB and wraps the native JavaScript Date object. When you use the ISODate() constructor from the Mongo shell, it actually returns a JavaScript Date object. please check https://www.compose.com/articles/understanding-dates-in-compose-mongodb/ – Steve Gao Mar 27 '19 at 00:14
  • 1
    Conversion is wrong. Add additional `* 60` for correct result. `new Date(Date.now() - 60 * 60 * 24 * 30 * 1000);` – Hasan Sefa Ozalp Sep 28 '20 at 23:51
  • @HasanSefaOzalp you are right, just correct it, thanks. – Steve Gao Sep 29 '20 at 00:36
  • I think it can be achieved more readable like this: `new Date().setMonth(new Date().getMonth() -1)` – CommonSenseCode Aug 17 '21 at 19:08
2

Dates are a tricky topic, so I suggest you to use a dedicated library in order to avoid problems with them.

You can use momentjs:

const aMonthAgo = moment().subtract(30, 'days').toDate();

Then change your query to:

$lte: aMonthAgo 

In this way you'll find only documents with a creation date lower than "a month ago".

The toDate() function is needed to get the native Date object from momentjs date type.

lifeisfoo
  • 15,478
  • 6
  • 74
  • 115
0

As per your need and for the date-related operations, I would suggest using date-fns library. You can simply write the query as

var subDays = require('date-fns/sub_days')
var olderDate = subDays(new Date(2019, 28, 3), 30)

await User.find({ 
   creationDate: {
      $gte: olderDate
   }
});

For the function, you can take a look into date-fns/sub_days.

Shivam Pandey
  • 3,756
  • 2
  • 19
  • 26