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