My entries in MongoDB have a publishedDate field as follows:
publishedDate:"{'$date': '1999-08-01T00:00:00.000-0700'}"
How do I retrieve the entries via collection.find with $regex, using user's input for year?
From MongoDB version >= 4.4 we can write custom filters using $function operator so try this:
let yearRegex = /^1999/;
db.testCollection.find({
$expr: {
$function: {
body: function(publishedDate, yearRegex) {
return yearRegex.test(publishedDate);
},
args: [{ $toString: "$publishedDate" }, yearRegex],
lang: "js"
}
}
});
Note: Instead of $toString we can also use $dateToString with timezone to cover edge cases.
"{'$date': '1999-08-01T00:00:00.000-0700'}" looks like MongoDB extended JSON notation for a Datetime object.
If the data in the collection is actually a date, note that the timezone in the database will be UTC, so the start/end would be off by a few hours if you intended to use any other timezone.
You can build a date object for the beginning of the year, and another for the beginning of the following year, and query for dates between:
let queryYear = 1999
db.collection.find({
publishedDate:{
$gte: new Date( queryYear + "-01-01T00:00:00-0700" ),
$lt: new Date( (queryYear+1) + "-01-01T00:00:00-0700")
}})
This allows to you build a date object with the desired timezone, and this query could also make use of an index on the publishedDate field.
Related
I currently have a JSON schema that required date time validation.
"type": "array",
"items": {
"type": "object",
"properties": {
"activeFrom": {"type": "string", "format": "datetime", "pattern": ********},
}
...
Validation should exist so that
Dates are in the format YYYY-MM-DDTHH:MM:SS.00-00:00
Represents (Year-Month-Day"T"Hour:Minute:Second.Milisecond-TimeZoneHour:TimeZoneMinute)
GMT Time Zone = 00:00
Example: 2022-11-12T16:32:21.00-00:00
Incorrect dates are not acceptable (i.e. 31 days in February, or incorporate leap year)
I have tried many different patterns (******) but can't seem to find one that works.
Appreciate any help and apologies if this questions structure is incorrect, new to SO :)
I think this will check dates in the way you're looking for.
First though pip install python-dateutil
EDIT: Have changed following comments.
from dateutil.parser import parse, ParserError
from datetime import timedelta
def check_date_is_legit(input_date):
"""
Checks if an input_date is legitimate
:param input_date: string, date to check.
:return result: False if the date isn't legit and True if it is.
"""
try:
parsed = parse(input_date)
if parsed.tzname() == 'UTC':
result = True
else:
result = False
except ParserError:
result = False
return result
I just started using mongoDB (Version 3.6.8) today, and I like it.
I was reading that it should be possible to have a date object directly in the database, but I can't get it to work.
Also I was wondering if it is the best solution or if I should just store my dates as "Epoch millis" instead?
I am trying to use use the $dateFromString keyword which should work but i receive this error:
bson.errors.InvalidDocument: key '$dateFromString' must not start with '$'
My code looks like this:
from datetime import date
import pymongo
dbcli = pymongo.MongoClient('mongodb://192.168.1.8:27017')
db = dbcli['washbase']
col = db['machine']
def conv(dato):
return {
'$dateFromString': {
'dateString': dato,
'format': '%Y-%m-%d',
'timezone':'Europe/Copenhagen',
}
}
today = date.today().isoformat()
data = {
'day': conv(today),
'time':12,
'room':'2B',
}
col.insert_one(data)
The reason why I need something like a date-object in the database is because I want to do a conditional query on the data, so that the database only sends the data i require. So i expect to do something like this.
result = col.find(
{
'day' : {
'$gt' : {
'$date' : '2020-01-01'
}
}
}
)
for x in results:
print(x)
But when I do this the app prints nothing.
The $dateFromString is an operator for MongoDB aggregations. An aggregation is a powerful way to create complex queries in MongoDB. Hence, this might not be what you need.
I would recommend storing the dates in the normal format. So your code should look something like this:
from datetime import date
import pymongo
dbcli = pymongo.MongoClient('mongodb://192.168.1.8:27017')
db = dbcli['washbase']
col = db['machine']
today = date.today().isoformat()
data = {
'day': today,
'time':12,
'room':'2B',
}
col.insert_one(data)
If you are concerned about timezones, MongoDB stores each date in UTC by default, converting whatever timezone is specified in your date to UTC. When reading the dates, you can then convert them to whatever timezone you need.
EDIT:
When writing your query, try using an actual date object. This converts the query date to an actual ISO date that the DB can understand.
col.find({'day': {'$gte': ISODate(date.today) }})
If you're trying to find entries that fall within a date range, you can do something like:
col.find({'day': {'$gte': ISODate(date.today), '$lte': ISODate(date.today + 24 hours) }})
Record_collection as in database :
{
"_id": 792ydihd2989002,
"mydate":ISODate("2020-06-08T09:05:12.191Z"),
"_id": 7676wwhdhwte77,
"mydate":ISODate("2020-07-08T09:05:12.191Z"),
"_id": 7676wwhdeete77,
"mydate": ,
}
Expected Output:
I need a query to get all he records where the 'mydate' is older than 20 minutes or the mydate value is empty. Either the mydate must be 20 minutes older or null.
I have tried in pymongo also with mongodb but it matches with date and not with the time.
I have two objects in the db with diferent dates:
{
"_id" : ObjectId("5addeaf92602ff20497e9406"),
"success" : true,
"timestamp" : 1524477784,
"base" : "EUR",
"date" : "2018-04-22",
"rates" : {
"AED" : 4.492662,
"ALL" : 128.39508,
"AMD" : 586.837094}
and the second one:
{
"_id" : ObjectId("5addb57d0043582d48ba898a"),
"success" : true,
"timestamp" : 1524477784,
"base" : "EUR",
"date" : "2018-04-23",
"rates" : {
"AED" : 4.492662,
"ALL" : 128.39508,
"AMD" : 586.837094}
My python code:
import pymongo
uri = "mongodb://127.0.0.1:27017"
client = pymongo.MongoClient(uri)
database = client['db']
collection = database['currency']
d=(*something I guess*)(input('Insert date: '))
item = collection.find_one({})
data= item['date']['d']
print(data)
What I want is to insert a day or a specific date, and then the program would print that specific day info.
In the db the date is in String and I think that I have to convert it.
Thanks in advance.
Well, first of all data= item['date']['d'] this will not gona work because the 2nd [] is used for indexing. And in your case its up to you either you take input same as your string date or convert it into date the take input then put a check on it
For converting string into date do this:
from datetime import date
year, month, day = map(int, (d['date']).split("-"))
required_date = date(year, month, day)
print required_date
Note: assuming that i have your mongo object/dictionary in d
and for second case:
take input from user in the same format in string for e.g:
userinput = str(raw_input('Enter Date: in Format(year, month, day) with seprator "-" e.g: 2018-04-23 \n'))
if userinput == d['date']:
print 'Correct'
again assuming that d is your mongo object.
Note:
Its for exmaple what ever case you are using use then put a if check on it.
Hope it helps you! :)
I'm using two dates to form a "period" in openErp:
_columns = {
'date_from': fields.date('From', required = True),
'date_to': fields.date ('To', required = True),
}
These two fields are inputs for the user, after they choose both dates I create a string called "period"
'period': str(date_from)+ ' // ' + str(date_to),
thing is, that the dates are in format "y-m-d" and i need them to be "d-m-y", even if i select my language in openERP it wont changue that string.
Is there any way that i can change that format ?
Thanks in advance.
As I found out when you try to get objects date/datetime field value it's returned as string, so this is ugly but for now (as I haven't seen better method) I do something like:
from dateutil import parser
...
my_date = parser.parse(my_object.date)
proper_date_string = my_date.strftime('%d-%m-%Y')
You also can use python datetime module and parse date string via strptime. But dateutil is required for openerp so you can use it.