github.com/go-chrono/chrono@v0.0.0-20240102183611-532f0d0d7c34/offset.go (about) 1 package chrono 2 3 import "fmt" 4 5 // UTC represents Universal Coordinated Time (UTC). 6 const UTC = Offset(0) 7 8 // Offset represents a time zone offset from UTC with precision to the minute. 9 type Offset Extent 10 11 // OffsetOf returns the Offset represented by a number of hours and minutes. 12 // If hours is non-zero, the sign of minutes is ignored, e.g.: 13 // - OffsetOf(-2, 30) = -02h:30m 14 // - OffsetOf(2, -30) = 02h:30m 15 // - OffsetOf(0, 30) = 00h:30m 16 // - OffsetOf(0, -30) = -00h:30m 17 func OffsetOf(hours, mins int) Offset { 18 return Offset(makeOffset(hours, mins)) 19 } 20 21 func makeOffset(hours, mins int) int64 { 22 if hours == 0 { 23 return int64(mins) * oneMinute 24 } 25 26 if mins < 0 { 27 mins = -mins 28 } 29 30 if hours < 0 { 31 return (int64(hours) * oneHour) - (int64(mins) * oneMinute) 32 } 33 return (int64(hours) * oneHour) + (int64(mins) * oneMinute) 34 } 35 36 // String returns the time zone designator according to ISO 8601, truncating first to the minute. 37 // If o == 0, String returns "Z" for the UTC offset. 38 // In all other cases, a string in the format of ±hh:mm is returned. 39 // Note that the sign and number of minutes is always included, even if 0. 40 func (o Offset) String() string { 41 return offsetString(int64(o), ":") 42 } 43 44 func offsetString(o int64, sep string) string { 45 e := truncateExtent(o, oneMinute) 46 if e == 0 { 47 return "Z" 48 } 49 50 sign := "+" 51 if e < 0 { 52 sign = "-" 53 } 54 55 hours, mins, _, _ := extentUnits(extentAbs(e)) 56 return fmt.Sprintf("%s%02d%s%02d", sign, hours, sep, mins) 57 }