// Code generated by astool. DO NOT EDIT. package duration import ( "fmt" "math" "regexp" "strconv" "time" ) // SerializeDuration converts a duration value to an interface representation // suitable for marshalling into a text or binary format. func SerializeDuration(this time.Duration) (interface{}, error) { // Seriously questioning my life choices. s := "P" if this < 0 { s = "-P" this = -1 * this } var tally time.Duration // Assume 8760 Hours per 365 days, cannot account for leap years in xsd:duration. :( if years := this.Hours() / 8760.0; years >= 1 { nYears := int64(math.Floor(years)) tally += time.Duration(nYears) * 8760 * time.Hour s = fmt.Sprintf("%s%dY", s, nYears) } // Assume 30 days per month, cannot account for months lasting 31, 30, 29, or 28 days in xsd:duration. :( if months := (this.Hours() - tally.Hours()) / 720.0; months >= 1 { nMonths := int64(math.Floor(months)) tally += time.Duration(nMonths) * 720 * time.Hour s = fmt.Sprintf("%s%dM", s, nMonths) } if days := (this.Hours() - tally.Hours()) / 24.0; days >= 1 { nDays := int64(math.Floor(days)) tally += time.Duration(nDays) * 24 * time.Hour s = fmt.Sprintf("%s%dD", s, nDays) } if tally < this { s = fmt.Sprintf("%sT", s) if hours := this.Hours() - tally.Hours(); hours >= 1 { nHours := int64(math.Floor(hours)) tally += time.Duration(nHours) * time.Hour s = fmt.Sprintf("%s%dH", s, nHours) } if minutes := this.Minutes() - tally.Minutes(); minutes >= 1 { nMinutes := int64(math.Floor(minutes)) tally += time.Duration(nMinutes) * time.Minute s = fmt.Sprintf("%s%dM", s, nMinutes) } if seconds := this.Seconds() - tally.Seconds(); seconds >= 1 { nSeconds := int64(math.Floor(seconds)) tally += time.Duration(nSeconds) * time.Second s = fmt.Sprintf("%s%dS", s, nSeconds) } } return s, nil } // DeserializeDuration creates duration value from an interface representation // that has been unmarshalled from a text or binary format. func DeserializeDuration(this interface{}) (time.Duration, error) { // Maybe this time it will be easier. if s, ok := this.(string); ok { isNeg := false if s[0] == '-' { isNeg = true s = s[1:] } if s[0] != 'P' { return 0, fmt.Errorf("%s malformed: missing 'P' for xsd:duration", s) } re := regexp.MustCompile(`P(\d*Y)?(\d*M)?(\d*D)?(T(\d*H)?(\d*M)?(\d*S)?)?`) res := re.FindStringSubmatch(s) var dur time.Duration nYear := res[1] if len(nYear) > 0 { nYear = nYear[:len(nYear)-1] vYear, err := strconv.ParseInt(nYear, 10, 64) if err != nil { return 0, err } // Assume 8760 Hours per 365 days, cannot account for leap years in xsd:duration. :( dur += time.Duration(vYear) * time.Hour * 8760 } nMonth := res[2] if len(nMonth) > 0 { nMonth = nMonth[:len(nMonth)-1] vMonth, err := strconv.ParseInt(nMonth, 10, 64) if err != nil { return 0, err } // Assume 30 days per month, cannot account for months lasting 31, 30, 29, or 28 days in xsd:duration. :( dur += time.Duration(vMonth) * time.Hour * 720 } nDay := res[3] if len(nDay) > 0 { nDay = nDay[:len(nDay)-1] vDay, err := strconv.ParseInt(nDay, 10, 64) if err != nil { return 0, err } dur += time.Duration(vDay) * time.Hour * 24 } nHour := res[5] if len(nHour) > 0 { nHour = nHour[:len(nHour)-1] vHour, err := strconv.ParseInt(nHour, 10, 64) if err != nil { return 0, err } dur += time.Duration(vHour) * time.Hour } nMinute := res[6] if len(nMinute) > 0 { nMinute = nMinute[:len(nMinute)-1] vMinute, err := strconv.ParseInt(nMinute, 10, 64) if err != nil { return 0, err } dur += time.Duration(vMinute) * time.Minute } nSecond := res[7] if len(nSecond) > 0 { nSecond = nSecond[:len(nSecond)-1] vSecond, err := strconv.ParseInt(nSecond, 10, 64) if err != nil { return 0, err } dur += time.Duration(vSecond) * time.Second } if isNeg { dur *= -1 } return dur, nil } else { return 0, fmt.Errorf("%v cannot be interpreted as a string for xsd:duration", this) } } // LessDuration returns true if the left duration value is less than the right // value. func LessDuration(lhs, rhs time.Duration) bool { return lhs < rhs }