func (ts *TS) Unmarshal(field []byte, c *Context) error {
	ts.IsHL7Null = isHL7Null(field)
	if ts.IsHL7Null {
		return nil
	}
	components := c.Delimiters.splitComponents(Token{Value: field}, c.Nesting)
	var tsWithoutTz []byte
	tzIndex := bytes.LastIndexAny(components[0].Value, "+-")
	if tzIndex > 0 {
		tsWithoutTz = components[0].Value[0:tzIndex]
	} else {
		tsWithoutTz = components[0].Value
	}
	var format string
	switch len(tsWithoutTz) {
	case 4:
		format = "2006"
		ts.Precision = YearPrecision
	case 6:
		format = "200601"
		ts.Precision = MonthPrecision
	case 8:
		format = "20060102"
		ts.Precision = DayPrecision
	case 10:
		format = "2006010215"
		ts.Precision = HourPrecision
	case 12:
		format = "200601021504"
		ts.Precision = MinutePrecision
	case 14:
		format = "20060102150405"
		ts.Precision = SecondPrecision
	case 16:
		format = "20060102150405.0"
		ts.Precision = TenthSecondPrecision
	case 17:
		format = "20060102150405.00"
		ts.Precision = HundredthSecondPrecision
	case 18:
		format = "20060102150405.000"
		ts.Precision = ThousandthSecondPrecision
	case 19:
		format = "20060102150405.0000"
		ts.Precision = TenThousandthSecondPrecision
	default:
		return errors.New("bad TS value: invalid length")
	}
	if len(components) > 1 {
		switch string(components[1].Value) {
		case "Y":
			ts.Precision = YearPrecision
		case "L":
			ts.Precision = MonthPrecision
		case "D":
			ts.Precision = DayPrecision
		case "H":
			ts.Precision = HourPrecision
		case "M":
			ts.Precision = MinutePrecision
		case "S":
			ts.Precision = SecondPrecision
		default:
			return errors.New("bad TS value: unknown precision")
		}
	}
	var err error
	if tzIndex < 0 && ts.Precision > DayPrecision {
		ts.Time, err = time.ParseInLocation(format, string(tsWithoutTz), c.TimezoneLoc)
		return err
	}
	if tzIndex < 0 && ts.Precision <= DayPrecision {
		ts.Time, err = time.Parse(format, string(tsWithoutTz))
		return err
	}
	ts.Time, err = time.Parse(format+"-0700", string(components[0].Value))
	return err
}
Unmarshal unmarshals a TS value, as described in 2.8.42 of the HL7 2.3
specification. Values have the following format:
YYYY[MM[DD[HHMM[SS[.S[S[S[S]]]]]]]][+/-ZZZZ]^<degree of precision>
Paraphrasing the comments on precision: In the current and future
versions of HL7, the precision is indicated by limiting the number
of digits used, unless the optional second component is present. In
prior versions of HL7, an optional second component indicates the
degree of precision of the time stamp. This optional second
component is retained only for purposes of backward compatibility.
package hl7
import (
	"bytes"
	"errors"
	"reflect"
	"strconv"
	"time"
	"golang.org/x/text/encoding/unicode"
)
type ST string
var _ Primitive = (*ST)(nil)
func NewST(st ST) *ST {
	return &st
}
func (st *ST) Marshal(_ *Context) ([]byte, error) {
	return []byte(string(*st)), nil
}
func (st *ST) Unmarshal(field []byte, c *Context) error {
	parsed, err := parseText(field, c)
	if err != nil {
		*st = ""
		return err
	}
	*st = ST(parsed)
	return nil
}
func SanitizeString(s string) string {
	if isHL7Null([]byte(s)) {
		return ""
	}
	return s
}
func (st *ST) SanitizedString() string {
	return SanitizeString(st.String())
}
func (st *ST) String() string {
	if st == nil {
		return ""
	}
	return string(*st)
}
func (st *ST) Empty() bool {
	return st == nil || *st == ""
}
type ID string
var _ Primitive = (*ID)(nil)
func NewID(id ID) *ID {
	return &id
}
func (id *ID) Marshal(_ *Context) ([]byte, error) {
	return []byte(string(*id)), nil
}
func (id *ID) Unmarshal(field []byte, _ *Context) error {
	*id = ID(field)
	return nil
}
func (id *ID) SanitizedString() string {
	return SanitizeString(id.String())
}
func (id *ID) String() string {
	if id == nil {
		return ""
	}
	return string(*id)
}
func (id *ID) Empty() bool {
	return id == nil || *id == ""
}
type SI struct {
	Value uint64
	Valid bool  
}
var _ Primitive = (*SI)(nil)
func NewSI(value uint64) *SI {
	return &SI{value, true}
}
func (si *SI) Marshal(_ *Context) ([]byte, error) {
	return []byte(strconv.FormatUint(si.Value, 10)), nil
}
func (si *SI) Unmarshal(field []byte, _ *Context) error {
	si.Valid = !isHL7Null(field)
	if !si.Valid {
		return nil
	}
	i, err := strconv.ParseInt(string(field), 10, 64)
	if err != nil {
		err = ErrBadValue
	} else if i < 0 {
		err = errors.New("SI must be non-negative")
	} else {
		si.Value = uint64(i)
	}
	return err
}
type NM struct {
	Value float64
	Valid bool  
}
var _ Primitive = (*NM)(nil)
func NewNM(value float64) *NM {
	return &NM{Value: value, Valid: true}
}
func (nm *NM) Marshal(_ *Context) ([]byte, error) {
	return []byte(strconv.FormatFloat(nm.Value, 'f', -1, 64)), nil
}
func (nm *NM) Unmarshal(field []byte, _ *Context) error {
	nm.Valid = !isHL7Null(field)
	if !nm.Valid {
		return nil
	}
	i, err := strconv.ParseFloat(string(field), 64)
	if err != nil {
		return ErrBadValue
	}
	nm.Value = i
	return nil
}
type IS string
var _ Primitive = (*IS)(nil)
func NewIS(is IS) *IS {
	return &is
}
func (is *IS) Marshal(_ *Context) ([]byte, error) {
	return []byte(string(*is)), nil
}
func (is *IS) Unmarshal(field []byte, _ *Context) error {
	*is = IS(field)
	return nil
}
func (is *IS) SanitizedString() string {
	return SanitizeString(is.String())
}
func (is *IS) String() string {
	if is == nil {
		return ""
	}
	return string(*is)
}
func (is *IS) Empty() bool {
	return is == nil || *is == ""
}
type DT string
var _ Primitive = (*DT)(nil)
func NewDT(dt DT) *DT {
	return &dt
}
func (dt *DT) Marshal(_ *Context) ([]byte, error) {
	return []byte(string(*dt)), nil
}
func (dt *DT) Unmarshal(field []byte, _ *Context) error {
	*dt = DT(field)
	return nil
}
type TM string
var _ Primitive = (*TM)(nil)
func NewTM(tm TM) *TM {
	return &tm
}
func (tm *TM) Marshal(_ *Context) ([]byte, error) {
	return []byte(string(*tm)), nil
}
func (tm *TM) Unmarshal(field []byte, _ *Context) error {
	*tm = TM(field)
	return nil
}
type TSPrecision int
const (
	YearPrecision TSPrecision = iota
	MonthPrecision
	DayPrecision
	HourPrecision
	MinutePrecision
	SecondPrecision
	TenthSecondPrecision
	HundredthSecondPrecision
	ThousandthSecondPrecision
	TenThousandthSecondPrecision
)
func (p TSPrecision) formatString() string {
	return [...]string{
		"2006",
		"200601",
		"20060102",
		"2006010215",
		"200601021504",
		"20060102150405",
		"20060102150405.0",
		"20060102150405.00",
		"20060102150405.000",
		"20060102150405.0000",
	}[p]
}
type TS struct {
	IsHL7Null     bool
	Time          time.Time
	Precision     TSPrecision
	ElideTimezone bool
}
var _ Primitive = (*TS)(nil)
func (ts *TS) Marshal(c *Context) ([]byte, error) {
	time := ts.Time.In(c.TimezoneLoc)
	format := ts.Precision.formatString()
	if c.IncludeTimezone && !ts.ElideTimezone {
		format += "-0700"
	}
	return []byte(time.Format(format)), nil
}