time_context.go RawHistoryFolder
1package core
2
3import (
4 "fmt"
5 "strconv"
6 "strings"
7 "time"
8)
9
10type agentTimeContext struct {
11 started time.Time
12 location *time.Location
13 zone string
14 offset string
15}
16
17func newAgentTimeContext(now time.Time) agentTimeContext {
18 zoneName, offset := localTimeMetadata(now)
19 return agentTimeContext{
20 started: now,
21 location: now.Location(),
22 zone: zoneName,
23 offset: offset,
24 }
25}
26
27func localTimeMetadata(now time.Time) (string, string) {
28 zone, seconds := now.Zone()
29 zoneName := now.Location().String()
30 if zoneName == "" || zoneName == "Local" {
31 zoneName = zone
32 }
33 return zoneName, formatUTCOffset(seconds)
34}
35
36func (a *Agent) SetSessionTimeContext(started time.Time, timezone, offset string) {
37 if started.IsZero() {
38 return
39 }
40 location := time.Local
41 loadedTimezone := false
42 if timezone != "" && timezone != "Local" {
43 if loaded, err := time.LoadLocation(timezone); err == nil {
44 location = loaded
45 loadedTimezone = true
46 }
47 }
48 if !loadedTimezone && offset != "" {
49 if fixed := parseUTCOffset(offset); fixed != nil {
50 location = fixed
51 }
52 }
53 if timezone == "" {
54 timezone = location.String()
55 }
56 if offset == "" {
57 _, seconds := started.In(location).Zone()
58 offset = formatUTCOffset(seconds)
59 }
60
61 a.mu.Lock()
62 a.timeContext = agentTimeContext{
63 started: started,
64 location: location,
65 zone: timezone,
66 offset: offset,
67 }
68 a.mu.Unlock()
69}
70
71func (a *Agent) providerTimeContext() agentTimeContext {
72 a.mu.Lock()
73 defer a.mu.Unlock()
74 return a.timeContext
75}
76
77func (c agentTimeContext) systemText() string {
78 if c.started.IsZero() {
79 return ""
80 }
81 location := c.location
82 if location == nil {
83 location = time.UTC
84 }
85 zone := c.zone
86 if zone == "" {
87 zone = location.String()
88 }
89 offset := c.offset
90 if offset == "" {
91 _, seconds := c.started.In(location).Zone()
92 offset = formatUTCOffset(seconds)
93 }
94 return fmt.Sprintf("[Session time context]\nsession_started: %s\nlocal_timezone: %s (UTC%s)", c.started.In(location).Format(time.RFC3339), zone, offset)
95}
96
97func formatUTCOffset(seconds int) string {
98 sign := "+"
99 if seconds < 0 {
100 sign = "-"
101 seconds = -seconds
102 }
103 return fmt.Sprintf("%s%02d:%02d", sign, seconds/3600, (seconds%3600)/60)
104}
105
106func parseUTCOffset(value string) *time.Location {
107 if len(value) != len("+00:00") || (value[0] != '+' && value[0] != '-') || value[3] != ':' {
108 return nil
109 }
110 hours, errHours := strconv.Atoi(value[1:3])
111 minutes, errMinutes := strconv.Atoi(value[4:6])
112 if errHours != nil || errMinutes != nil || hours > 23 || minutes > 59 {
113 return nil
114 }
115 seconds := hours*3600 + minutes*60
116 if strings.HasPrefix(value, "-") {
117 seconds = -seconds
118 }
119 return time.FixedZone(value, seconds)
120}