Mgo SetBSON to mongo golang driver

I’m migration our app from mgo to the official mongo go driver, but I’m stuck with the mgo SetBSON migration, this is my old code and I don’t know how to do this using the new driver:

type MyStruct struct {
	ID            primitive.ObjectID `bson:"_id"`
	Ends          time.Time          `bson:"ends"`
func (st *MyStruct) SetBSON(raw bson.Raw) error {
	decoded := new(struct {
		ID            primitive.ObjectID `bson:"_id"`
		Ends          string             `bson:"ends"`

	bsonErr := raw.Unmarshal(decoded)
	if bsonErr != nil {
		return bsonErr

	const dateFormat = "2006-01-02"
	end, endErr := time.ParseInLocation(dateFormat, decoded.Ends, constants.NYCLoc)
	if endErr != nil {
		return endErr

	st.ID = decoded.ID
	st.Ends = time.Date(ey, em, ed, 23, 59, 0, 0, constants.NYCLoc)
	return nil

The core is, we have a struct that in mongo stores the “end” field as a string that looks like “20200402”. When the driver reads the bson from mongo, I need to decode the struct and convert the string value from the field “end” into a time.Time Go type.

I hope I can avoid having to create a new custom “field” type for the end mongo field, because the app assumes a time.Time all over.


Hi @Diego_Medina,

You can do this using the UnmarshalBSON hook for the driver. This is similar to the UnmarshalJSON hook in the encoding/json library. I wrote up an example of this in It’s worth noting that version 1.3.0 of the driver introduced a custom BSON registry to mimic parts of mgo BSON behavior to mitigate BSON issues for users when migrating to the official driver. This registry supports GetBSON/SetBSON. You can see documentation for that at


Thanks you! your example was just what I needed.