In Go time.Time
is a struct which cannot have a nil
value. It has a zero value (which is all struct fields having their zero values), but this zero value corresponds to MongoDB ISODate("0001-01-01T00:00:00Z")
and not to the MongoDB null
value.
If your field is of type time.Time
, you cannot set any value to it to end up MongoDB null
value.
The simplest solution is to use a field of type pointer to time.Time
instead, that is *time.Time
. If you leave or set this field to Go nil
, it will end up as null
in MongoDB.
If you can't or don't want to use *time.Time
, there is still a "workaround": declare 2 fields, one is of your "regular" time.Time
type, and use a struct tag to exclude this from MongoDB. And add another field of type *time.Time
, and make this mapped to MongoDB. And write a custom marshaling / unmarshaling logic, which when marshaling would update this extra field based on the original, or would set the original based on the extra when unmarshaling.
This is an example how it could look like:
type User struct {
CreatedAt time.Time `bson:"-"`
PCreatedAt *time.Time `bson:"created"`
}
func (u *User) GetBSON() (interface{}, error) {
if u.CreatedAt.IsZero() {
u.PCreatedAt = nil
} else {
u.PCreatedAt = &u.CreatedAt
}
return u, nil
}
func (u *User) SetBSON(raw bson.Raw) (err error) {
if err = raw.Unmarshal(u); err != nil {
return
}
if u.PCreatedAt == nil {
u.CreatedAt = time.Time{}
} else {
u.CreatedAt = *u.PCreatedAt
}
return
}
Explanation:
User.CreatedAt
holds the time.Time
value which you can work with (read / write). This field is excluded from MongoDB.
There is a pointer User.PCreatedAt
field which is mapped to the created
property in MongoDB.
When a User
is marshaled (saved to MongoDB), GetBSON()
is called. If CreatedAt
is the zero value, sets PCreatedAt
to nil
which will end up as null
in MongoDB. Else sets / uses the non-zero timestamp.
When a User
is unmarshaled (loaded from MongoDB), SetBSON()
is called. This checks if PCreatedAt
is nil
(which corresponds to MongoDB null
), and if so, sets CreatedAt
to its zero value. Else uses the timestamp retrieved from MongoDB.
Related / similar questions:
Set default date when inserting document with time.Time field
Accesing MongoDB from Go