@@ -2,14 +2,15 @@ package plugin
2
2
3
3
import (
4
4
"fmt"
5
+ "github.com/grafana/grafana-plugin-sdk-go/backend"
5
6
"regexp"
6
7
"strconv"
7
8
"strings"
8
9
"time"
9
10
)
10
11
11
- // 判断不区分大小写的键是否存在于 map[string] 中,并获取对应的值
12
- func getValueIgnoreCase (data map [string ]interface {}, keys []string ) (interface {}, bool ) {
12
+ // GetValueIgnoreCase 判断不区分大小写的键是否存在于 map[string] 中,并获取对应的值
13
+ func GetValueIgnoreCase (data map [string ]interface {}, keys []string ) (interface {}, bool ) {
13
14
for _ , key := range keys {
14
15
for k , v := range data {
15
16
if strings .EqualFold (k , key ) {
@@ -20,30 +21,79 @@ func getValueIgnoreCase(data map[string]interface{}, keys []string) (interface{}
20
21
return "" , false
21
22
}
22
23
23
- // 时间正则匹配
24
- // formatDateTime 根据给定的格式字符串(如 "${__from:date:iso}"、"${__from:date:iso+n}"、"${__from:date:iso-n}" 或 "${__from:date}")和时间戳,
25
- // 解析时区信息(如果存在)并应用到日期时间的格式化输出。
26
- func formatDateTime (formatStr string , timestamp time.Time ) (string , error ) {
27
- switch formatStr {
28
- case "${__from}" :
29
- t := timestamp .String ()
30
- return t , nil
31
- case "${__from:date:seconds}" :
32
- t := timestamp .Unix ()
33
- return strconv .FormatInt (t , 10 ), nil
34
- case "${__from:date:iso}" :
35
- // 默认使用 UTC 时间
36
- t := timestamp .UTC ()
37
- return t .Format (time .RFC3339 ), nil
24
+ var datePatternRegex = regexp .MustCompile ("(LT|LL?L?L?|l{1,4}|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|Q)" )
25
+
26
+ var datePatternReplacements = map [string ]string {
27
+ "M" : "1" , // stdNumMonth 1 2 ... 11 12
28
+ "MM" : "01" , // stdZeroMonth 01 02 ... 11 12
29
+ "MMM" : "Jan" , // stdMonth Jan Feb ... Nov Dec
30
+ "MMMM" : "January" , // stdLongMonth January February ... November December
31
+ "D" : "2" , // stdDay 1 2 ... 30 30
32
+ "DD" : "02" , // stdZeroDay 01 02 ... 30 31
33
+ "DDD" : "<stdDayOfYear>" , // Day of the year 1 2 ... 364 365
34
+ "DDDD" : "<stdDayOfYearZero>" , // Day of the year 001 002 ... 364 365 @todo****
35
+ "d" : "<stdDayOfWeek>" , // Numeric representation of day of the week 0 1 ... 5 6
36
+ "dd" : "Mon" , // ***Su Mo ... Fr Sa @todo
37
+ "ddd" : "Mon" , // Sun Mon ... Fri Sat
38
+ "dddd" : "Monday" , // stdLongWeekDay Sunday Monday ... Friday Saturday
39
+ "e" : "<stdDayOfWeek>" , // Numeric representation of day of the week 0 1 ... 5 6 @todo
40
+ "E" : "<stdDayOfWeekISO>" , // ISO-8601 numeric representation of the day of the week (added in PHP 5.1.0) 1 2 ... 6 7 @todo
41
+ "w" : "<stdWeekOfYear>" , // 1 2 ... 52 53
42
+ "ww" : "<stdWeekOfYear>" , // ***01 02 ... 52 53 @todo
43
+ "W" : "<stdWeekOfYear>" , // 1 2 ... 52 53
44
+ "WW" : "<stdWeekOfYear>" , // ***01 02 ... 52 53 @todo
45
+ "YY" : "06" , // stdYear 70 71 ... 29 30
46
+ "YYYY" : "2006" , // stdLongYear 1970 1971 ... 2029 2030
47
+ "gg" : "<stdIsoYearShort>" , // ISO-8601 year number 70 71 ... 29 30
48
+ "gggg" : "<stdIsoYear>" , // ***1970 1971 ... 2029 2030
49
+ "GG" : "<stdIsoYearShort>" , // 70 71 ... 29 30
50
+ "GGGG" : "<stdIsoYear>" , // ***1970 1971 ... 2029 2030
51
+ "Q" : "<stdQuarter>" , // 1, 2, 3, 4
52
+ "A" : "PM" , // stdPM AM PM
53
+ "a" : "pm" , // stdpm am pm
54
+ "H" : "<stdHourNoZero>" , // stdHour 0 1 ... 22 23
55
+ "HH" : "15" , // 00 01 ... 22 23
56
+ "h" : "3" , // stdHour12 1 2 ... 11 12
57
+ "hh" : "03" , // stdZeroHour12 01 02 ... 11 12
58
+ "m" : "4" , // stdZeroMinute 0 1 ... 58 59
59
+ "mm" : "04" , // stdZeroMinute 00 01 ... 58 59
60
+ "s" : "5" , // stdSecond 0 1 ... 58 59
61
+ "ss" : "05" , // stdZeroSecond ***00 01 ... 58 59
62
+ "z" : "MST" , // EST CST ... MST PST
63
+ "zz" : "MST" , // EST CST ... MST PST
64
+ "Z" : "Z07:00" , // stdNumColonTZ -07:00 -06:00 ... +06:00 +07:00
65
+ "ZZ" : "-0700" , // stdNumTZ -0700 -0600 ... +0600 +0700
66
+ "X" : "<stdUnix>" , // Seconds since unix epoch 1360013296
67
+ "LT" : "3:04 PM" , // 8:30 PM
68
+ "L" : "01/02/2006" , // 09/04/1986
69
+ "l" : "1/2/2006" , // 9/4/1986
70
+ "ll" : "Jan 2 2006" , // Sep 4 1986
71
+ "lll" : "Jan 2 2006 3:04 PM" , // Sep 4 1986 8:30 PM
72
+ "llll" : "Mon, Jan 2 2006 3:04 PM" , // Thu, Sep 4 1986 8:30 PM
73
+ }
74
+
75
+ func patternToLayout (pattern string ) string {
76
+ var match [][]string
77
+ if match = datePatternRegex .FindAllStringSubmatch (pattern , - 1 ); match == nil {
78
+ return pattern
79
+ }
38
80
39
- case "${__from:date}" :
40
- // 使用本地时间
41
- t := timestamp .Local ()
42
- return t .Format ("2006-01-02 15:04:05" ), nil
81
+ for i := range match {
82
+ if replace , ok := datePatternReplacements [match [i ][0 ]]; ok {
83
+ pattern = strings .Replace (pattern , match [i ][0 ], replace , 1 )
84
+ }
85
+ }
86
+
87
+ return pattern
88
+ }
43
89
44
- default :
45
- // 检查是否存在时区偏移量
46
- re := regexp .MustCompile (`\$\{__from:date:iso([+-])(-?\d+)\}` )
90
+ // FormatDateTime 时间正则匹配: 根据给定的格式字符串和时间戳,
91
+ // 解析时区信息(如果存在)并应用到日期时间的格式化输出。
92
+ func FormatDateTime (formatStr string , timestamp time.Time ) (string , error ) {
93
+ hasTimeOffset := strings .Contains (strings .ToLower (formatStr ), "utc" )
94
+ loc := time .FixedZone ("" , 0 )
95
+ if hasTimeOffset {
96
+ re := regexp .MustCompile (`.*?utc([+-])(\d+).*?` )
47
97
matches := re .FindStringSubmatch (formatStr )
48
98
fmt .Println ("matches:" , matches )
49
99
if len (matches ) == 3 {
@@ -64,34 +114,29 @@ func formatDateTime(formatStr string, timestamp time.Time) (string, error) {
64
114
}
65
115
66
116
// 创建对应时区
67
- loc := time .FixedZone ("" , int (offsetDuration .Seconds ()))
68
-
69
- // 使用给定的时间戳和时区进行格式化
70
- t := timestamp .In (loc )
71
- return t .Format ("2006-01-02 15:04:05" ), nil
117
+ loc = time .FixedZone ("" , int (offsetDuration .Seconds ()))
72
118
}
119
+ }
73
120
74
- return "" , fmt .Errorf ("unsupported format string: %s" , formatStr )
121
+ pattern := time .RFC3339
122
+ re := regexp .MustCompile (`"(.+?)"` )
123
+ matches := re .FindStringSubmatch (formatStr )
124
+ if len (matches ) > 1 {
125
+ format := matches [1 ]
126
+ pattern = patternToLayout (format )
75
127
}
128
+
129
+ return timestamp .In (loc ).Format (pattern ), nil
76
130
}
77
131
78
- // formatDateTimeForQuery 根据给定的格式字符串、查询时间范围对象(queryTimeRange)和时间类型(fromOrTo),
132
+ // FormatDateTimeForQuery 根据给定的格式字符串、查询时间范围对象(queryTimeRange)和时间类型(fromOrTo),
79
133
// 格式化相应的时间(起始时间或结束时间)。
80
- func formatDateTimeForQuery (formatStr string , queryTimeRange QueryTimeRange , fromOrTo string ) (string , error ) {
134
+ func FormatDateTimeForQuery (formatStr string , queryTimeRange backend. TimeRange ) (string , error ) {
81
135
timestamp := queryTimeRange .From
82
- if fromOrTo == "to" {
136
+ // 如果formatStr包含"__to",则使用结束时间,否则使用起始时间
137
+ // 并全部替换为__from
138
+ if strings .Contains (formatStr , "__time_to" ) {
83
139
timestamp = queryTimeRange .To
84
140
}
85
-
86
- // 替换格式字符串中的 "__from" 为 "__to"
87
- if fromOrTo == "to" {
88
- formatStr = strings .ReplaceAll (formatStr , "${__from}" , "${__to}" )
89
- }
90
-
91
- return formatDateTime (formatStr , timestamp )
92
- }
93
-
94
- type QueryTimeRange struct {
95
- From time.Time
96
- To time.Time
141
+ return FormatDateTime (formatStr , timestamp )
97
142
}
0 commit comments