When I'm doing:
db.events.ensureIndex({ "expiresAt": 1 }, { expireAfterSeconds: 0 })
What timezone the expiresAt is comparing to ??
MongoDB dates are UTC dates. Therefore, the only values you can st the "expiresAt" field would be UTC times. And the expiry is going to be at after your set expiryAfterSeconds (in your case 0) passed since your expiresAt in UTC time.
Related
My Date is in the format 2020-07-08 00:00:00 Asia/Kolkata
I want to convert it to 2020-07-08 03:30:00 Asia/Tokyo,
Then insert this date 2020-07-08 03:30:00 as ISO date to MongoDB.
I tried, with ISODate function, which takes DateFormat and Timezone, but it created the date 5 H 30 M ahead of this time, which should be 3 H 30 M ahead.
As Tokyo time is 3 H 30 M ahead of India time.
You can use $dateFromParts to manipulate ISODate to any required format.
Check if the below query helps you out
db.test4.aggregate([
{$project:{
"original": "$date",
"convertedDate": {
'$dateFromParts': {
'year': {$year:{date:'$date'}},
'month': {$month:{date:'$date'}},
'day': {$dayOfMonth:{date:'$date'}},
'hour': {$hour:{date:'$date'}},
'minute': {$minute:{date:'$date'}},
'second': {$second:{date:'$date'}},
'millisecond': {$millisecond:{date:'$date'}},
'timezone': '-0330',
}
}
}}
])
This is a sample data
[{ date: '2020-05-21T14:02:00.0123 }, { date: '2020-05-22T14:02:00.0123 }, { date: '2020-05-23T14:02:00.0123 }]
I want to filter records of 22-May or earlier, here is my expected:
[{ date: '2020-05-21T14:02:00.0123 }, { date: '2020-05-22T14:02:00.0123 }]
I tried with this query:
{ date: { $lte: new Date('2020-05-22') }}
But it returns only data earlier 22-May. I think problem is { date: { $lte: new Date('2020-05-22') }} will data.date lte 2020-05-22T00:00:00.000
How I can exclude time ?
You need to match type of input with type of date field in document, either both should be Date's or strings. I would highly suggest maintain dates as dates in DB. Also you need to know that dates in MongoDB are of format ISODate() and holds UTC date.
If your DB date field is of type date :
I want to filter records of 22-May or earlier
As you wanted to get documents <= 22-May, then sending new Date('2020-05-22') doesn't work. Cause :
when you do new Date('2020-05-22'), it will give you Fri May 22 2020 00:00:00 GMT only if you belong to UTC, for example if you're in New York America which is 4 hours behind UTC then it would result in Thu May 21 2020 20:00:00 GMT-0400 (Eastern Daylight Time) which represents EDT, basically it's your system/app server time i.e; local date time.
So if your region is behind UTC then you'll get a back date Thu May 21 2020 otherwise if it's ahead of UTC then there is no issue you'll see Fri May 22 2020.
Ok, now that we've fixed date issues, but we need to look into hours now :
Since you want docs <= 22-May then Fri May 22 2020 00:00:00 GMT doesn't work you need to have either <= Fri May 22 2020 23:59:59 GMT or Sat May 23 2020 00:00:00 GMT. In order to get that :
let date = new Date('2020-05-22')
date.setDate(date.getUTCDate()); // Setting utc date, Only useful if you're region is behind UTC
date = new Date(date.setHours(23,59,59,999)) // This overrides hours generated with 23:59:59 - which is what exactly needed here.
/** Now do your query */
{ date: { $lte: date }}
If your DB date field is of type string :
Then you don't need to convert string to date, instead you can send input date in string format :
let date = new Date('2020-05-22').toISOString() // 2020-05-22T00:00:00.000Z
/** Above would get you an ISO string no matter which region you're in,
* now since we need `2020-05-22T23:59:59.000Z` which is not easy on ISO string
* We would just do +1 on date like `new Date('2020-05-23').toISOString()` - // 2020-05-23T00:00:00.000Z */
let date = new Date('2020-05-23').toISOString(); // like this
date = date.slice(0, -1) // removing `Z` from date string as your `date` field doesn't have this.
// Now your query is just `$lt`
{ date: { $lt: date }}
Test : mongoplayground
I have dates in postgres table. The dates are stored with a UTC timezone.
Example from python.
roster = Roster.objects.get(id=266438)
roster.start_timestamp
Out[11]: datetime.datetime(2018, 9, 7, 15, 0, tzinfo=<UTC>)
When I marshall these dates from within go lib/pq my local time zone is somehow being applied.
func (nt *pq.NullTime) MarshalJSON() ([]byte, error) {
if !nt.Valid {
return []byte("\"\""), nil
}
val := fmt.Sprintf("\"%s\"", nt.Time.Format("01/02/2006 15:04:05"))
fmt.Println("Marshalling FMPDateTime", nt, val)
return []byte(val), nil
}
Example log:
Marshalling DateTime &{2018-09-08 00:30:00 +0930 ACST true} "09/08/2018 00:30:00"
2018-09-08 00:30:00 +0930 ACST is 2018-09-07 15:00:00 UTC.
How do you JSON Marshall a pq.NullTime in UTC rather than the local timezone?
Libraries usually construct time.Time values using the local timezone, but the time instant is still the same, so you shouldn't worry about that.
If you want to display / output the time in UTC zone specifically, then "switch" your time to UTC timezone. For this, you may use the Time.UTC() method:
val := fmt.Sprintf("\"%s\"", nt.Time.UTC().Format("01/02/2006 15:04:05"))
That's all.
Also note that if your NullTime is not valid, I would rather output JSON null instead of an empty string.
I have the following field in all my documents. And the Timestamp below will always be in string and I have no control to change it into any other type.
{ "TIMESTAMP": "2017-09-07T16:43:08.707-04:00" }
Since it is -04:00 the timestamp is in EST. but it can be in any timezone like -05:00 or -6:00 or whatever
The goal is to get all the documents that match the following criteria
currentTime > TIMSETAMP + 4 hours
where currentTime is in UTC and it is something I generate when I query.
I tried something like the following and I am not sure if there is anything wrong with this approach.
(new Date()- ISODate("2017-09-07T16:43:08.707-04:00"))/(60*60*1000) > 4
As per MongoDB official docs, it states that:
ObjectId values consists of 12-bytes, where the first four bytes are a
timestamp that reflect the ObjectId’s creation, specifically:
a 4-byte value representing the seconds since the Unix epoch,
a 3-byte machine identifier,
a 2-byte process id, and
a 3-byte counter, starting with a random value.
I'm just wondering what's gonna happen on Tue, 19 Jan 2038 03:14:08 GMT when the unix time will be equal to 2147483648 which doesn't fit the 4-byte timestamp in ObjectId *philosoraptor meme*
Unsigned 2,147,483,648 perfectly fits into 4 bytes. 4 bytes is enough to hold values up to 4,294,967,295, which is a unix epoch for Sunday, 7 February 2106 06:28:16 GMT.
If ObjectID's survive without changes till then, the timestamp part will start from 0, if you care:
> new Date();
ISODate("2106-02-08T12:41:20.450Z")
> db.t.insert({welcome:"from the future"});
WriteResult({ "nInserted" : 1 })
> db.t.find().pretty();
{
"_id" : ObjectId("0001a7b306c389186a3a9323"),
"welcome" : "from the future"
}
> db.t.find()[0]._id.getTimestamp();
ISODate("1970-01-02T06:07:47Z")