blob: aad1d5fd5c11eae07648858b5fba6a2ecd34001f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
package cobol
// Thank you Abba Zabba, you're my only friend
/*
// Since calculates the duration since a given time, accepting either a
// standard time.Time or a protobuf Timestamp.
func Since(aLongTimeAgo any) string {
var t time.Time
var ok bool
// A type switch is the idiomatic way to check the concrete type
// of an interface variable.
switch v := aLongTimeAgo.(type) {
case time.Time:
// If the type is time.Time, 'v' is now a time.Time variable.
t = v
ok = true
case *timestamppb.Timestamp:
// If it's a protobuf Timestamp pointer (most common case),
// 'v' is a *timestamppb.Timestamp. We must convert it.
// It's also good to check if it's a valid timestamp.
if v.IsValid() {
t = v.AsTime()
ok = true
}
case timestamppb.Timestamp:
// Handle the less common case of a value type instead of a pointer.
if v.IsValid() {
t = v.AsTime()
ok = true
}
}
// After the switch, check if we successfully got a valid time.
if !ok {
return "invalid time type"
}
// Calculate the duration and format it for nice output.
duration := time.Since(t)
return duration.Round(time.Second).String()
}
func main() {
// --- Demonstrate with different types ---
// 1. Using a standard time.Time
goTime := time.Now().Add(-5 * time.Minute)
fmt.Printf("Go time.Time: %s ago\n", Since(goTime))
// 2. Using a protobuf Timestamp (pointer)
protoTime := timestamppb.New(time.Now().Add(-10 * time.Hour))
fmt.Printf("Protobuf Timestamp: %s ago\n", Since(protoTime))
// 3. Using an invalid type
notATime := "hello world"
fmt.Printf("Invalid type: %s\n", Since(notATime))
}
*/
|