summaryrefslogtreecommitdiff
path: root/notes2.go
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))
}
*/