func New(p string, options ...Option) (*Strftime, error) {
	ds, err := getSpecificationSetFor(options...)
	if err != nil {
		return nil, errors.Wrap(err, `failed to get specification set`)
	}
	var h appenderListBuilder
	h.list = &combiningAppend{}
	if err := compile(&h, p, ds); err != nil {
		return nil, errors.Wrap(err, `failed to compile format`)
	}
	return &Strftime{
		pattern:  p,
		compiled: h.list.list,
	}, nil
}
New creates a new Strftime object. If the compilation fails, then
an error is returned in the second argument.
package strftime
import (
	"io"
	"strings"
	"sync"
	"time"
	"github.com/pkg/errors"
)
type compileHandler interface {
	handle(Appender)
}
type appenderListBuilder struct {
	list *combiningAppend
}
func (alb *appenderListBuilder) handle(a Appender) {
	alb.list.Append(a)
}
type appenderExecutor struct {
	t   time.Time
	dst []byte
}
func (ae *appenderExecutor) handle(a Appender) {
	ae.dst = a.Append(ae.dst, ae.t)
}
func compile(handler compileHandler, p string, ds SpecificationSet) error {
	for l := len(p); l > 0; l = len(p) {
		var verbatim verbatimw
		i := strings.IndexByte(p, '%')
		if i < 0 {
			verbatim.s = p
			handler.handle(&verbatim)
			p = p[l:]
			continue
		}
		if i == l-1 {
			return errors.New(`stray % at the end of pattern`)
		}
		if i > 0 {
			verbatim.s = p[:i]
			handler.handle(&verbatim)
			p = p[i:]
		}
		specification, err := ds.Lookup(p[1])
		if err != nil {
			return errors.Wrap(err, `pattern compilation failed`)
		}
		handler.handle(specification)
		p = p[2:]
	}
	return nil
}
func getSpecificationSetFor(options ...Option) (SpecificationSet, error) {
	var ds SpecificationSet = defaultSpecificationSet
	var extraSpecifications []*optSpecificationPair
	for _, option := range options {
		switch option.Name() {
		case optSpecificationSet:
			ds = option.Value().(SpecificationSet)
		case optSpecification:
			extraSpecifications = append(extraSpecifications, option.Value().(*optSpecificationPair))
		}
	}
	if len(extraSpecifications) > 0 {
		if raw, ok := ds.(*specificationSet); ok && !raw.mutable {
			ds = NewSpecificationSet()
		}
		for _, v := range extraSpecifications {
			if err := ds.Set(v.name, v.appender); err != nil {
				return nil, err
			}
		}
	}
	return ds, nil
}
var fmtAppendExecutorPool = sync.Pool{
	New: func() interface{} {
		var h appenderExecutor
		h.dst = make([]byte, 0, 32)
		return &h
	},
}
func getFmtAppendExecutor() *appenderExecutor {
	return fmtAppendExecutorPool.Get().(*appenderExecutor)
}
func releasdeFmtAppendExecutor(v *appenderExecutor) {
	v.dst = v.dst[:0]
	fmtAppendExecutorPool.Put(v)
}
func Format(p string, t time.Time, options ...Option) (string, error) {
	ds, err := getSpecificationSetFor(options...)
	if err != nil {
		return "", errors.Wrap(err, `failed to get specification set`)
	}
	h := getFmtAppendExecutor()
	defer releasdeFmtAppendExecutor(h)
	h.t = t
	if err := compile(h, p, ds); err != nil {
		return "", errors.Wrap(err, `failed to compile format`)
	}
	return string(h.dst), nil
}
type Strftime struct {
	pattern  string
	compiled appenderList
}