Google’s civil
package is simple – it’s aim is to represent a single day of the year without respect to time or location. This is useful for things like birthdays where it’s the same all over the world – even though time is different all over the world.
The main struct is:
type Date struct {
Year int // Year (e.g., 2014).
Month time.Month // Month of the year (January = 1, ...).
Day int // Day of the month, starting at 1.
}
And it gets represented in MongoDB as an object with 3 integer values:
# golang definition
occurredOn civil.Date `bson:"occurredOn"`
...
# mongodb definition
occurredOn Object
year 2022
month 4
day 2
This leads to weirdness if you want to query. For instance I don’t think standard $gt
/ $lt
queries will work as 2022-4-2
is lexicographically greater than 2022-10-20
but is an earlier date and I believe mongoDB can do a best-case scenario for comparing objects against each other but that also adds internal complexity to the query. Essentially it’s far more complicated than comparing two instances of time.Time
against each other. So what’s the easiest way to do it?
2
Answers
As far as I can tell there are four edge cases to cover:
Here's the function I came up with to return a mongoDB query to check for a
civil.Date
strictly greater than anothercivil.Date
. Apologies for the weird formatting but this is what thego fmt
spit out:I think there’s no implementation to serialize type of civil.Date in mongo bson pacakge. (There’s no function MarshalBinary)
Maybe, it has to be changed to time.Time package for better solution because it has the implementation in any serialization such as bson, json or xml and even in google datastore.
However if the type of civil.Date is the desired one then you should query and compare the field one by one ranging from year, month and day. And you have to consider to update or modified the indexes of the collection.