August 23rd, 2024 08:18 UTC · 1 month ago

Golang

Relearning Go: Day 10

Time & Epoch to SHA256 Hashes & Base64 Encoding

Time & Epoch

gobyexample.com/time
gobyexample.com/epoch

Fine at first glance, but on further inspection there are several weirdnesses in plain sight:

Location?

Every time/date API I have used refers to time zones. These are often loaded from a time zone database. In Go the same concept has the name Location, but time zones are not really locations, even though they may coincide with a location. Indeed, the example uses the time.UTC “location”, but there’s no such place.

Go has this penchant for choosing different names for things. Another example is “rune”. It’s usually less helpful than using the more common name.

Overflow

time.Duration can only represent ~290 years (positive or, ahem, negative). Call (t Time) Sub(u Time) Duration where t and u are more than ~290 years apart and you’ll get a Duration of ~290 years. No error value. No panic. There’s no constant like time.DurationMax that you can use to check if there might have been an overflow.

As I’m looking into this, I see something else:

Mangled Duration maths

In the constants section of the documentation:

To convert an integer number of units to a Duration, multiply:

seconds := 10
fmt.Print(time.Duration(seconds)*time.Second) // prints 10s

The Duration documentation says:

A Duration represents the elapsed time between two instants as an int64 nanosecond count.

Meaning that the example above means: 10 nanoseconds times 1 second equals 10 seconds.

Let that sink in.

I would be skeptical of anything that uses the time package.

Time Formatting / Parsing

gobyexample.com/time-formatting-parsing

I kind of love the idea of using a reference date as the way to express both a print and parse format. This is an idea that should be copied! Sadly, here it’s part of the time package, and so best to avoid in this instance.

Random Numbers

gobyexample.com/random-numbers

Fine. Nothing to add.

Number Parsing

gobyexample.com/number-parsing

The following:

i, err := strconv.ParseInt("128", 0, 8)
fmt.Println("Value:", i)
fmt.Println("Error:", err)

prints:

Value: 127
Error: strconv.ParseInt: parsing "128": value out of range

Here’s where Go’s error idiom shines like a dessicated turd on an overcast winter’s day: return a misleading/useless value and an error.

URL Parsing

gobyexample.com/url-parsing

Yeah, fine. Weird that a URL’s Host field can be a host or a host:port, and that extra methods are required to extract those. That said, I’ve never used a URL parser that I’ve wholly agreed with.

SHA256 Hashes & Base64 Encoding

gobyexample.com/sha256-hashes
gobyexample.com/base64-encoding

Yep, fine; nothing to add.


Okay, taking a break. Next will be: reading files.