Calculating weekdays and dates with Go
Terminal with Mouse Input
The MouseLeft
event comes up if the user clicks and releases the left mouse button. The payload enclosed with the event indicates the coordinates at which the mouse pointer was located at the time of the click. Line 47 needs to dynamically convert the event received as a generic interface{}
type to a ui.Mouse
type; it then uses Y
to access the (vertical) y-value of the click position.
The wdayPick()
function in line 86 determines the clicked weekday. It can do that because the program knows from the UI layout that Sunday is at the click position with a y-value of 4
, Monday at 5
, and so on through Saturday at position 10
. The function discards any other position, returning an error, so that the main program simply ignores the click.
If the user has done their mental arithmetic correctly and selected the right weekday, the condition in line 53 is true, and the BorderStyle.Fg
attribute sets the weekday widget's frame to green. The following call to randDate()
in line 56 fetches a new date task, and the success counter wins
is incremented by one. However, if the user guesses wrong, line 59 colors the widget's frame red and sets wins
back to zero. Life can be hard!
To refresh the success counter graphically, the call to displayTask()
in line 63 changes the widget's contents, and the call ui.Render()
with both widgets as parameters updates the current status in the terminal. To make sure that the red or green border that provides user feedback only appears briefly and then disappears again, line 65 starts a Go routine that runs in parallel; it first sleeps for 200ms thanks to time.After()
, then resets the window's frame to the original White
(which actually looks gray), and displays the whole thing with ui.Render()
. That's how dynamics come into play, thanks simply to the standard parallelism features built into Go.
Text in Color
The text displayed in the widgets can also be colored using termui if so desired – not with an attribute like the widget borders, but using special tags in the text string on display. The date to be calculated appears in black thanks to this, and the number of successfully completed tasks in green; lines 80 to 81 include corresponding color commands in the text to be displayed with (fg:black)
and (fg:green)
.
Tricky Date Arithmetic
Selecting a random day of the year is more difficult than you might think. Sure, most years have 365 days, but in a leap year with 366 days, even February 29 should occur every now and then. Thanks to the Duration
type from the time package, Go offers a method to calculate the time span between January 1 of the year investigated and the same date of the following year. Unfortunately, it refuses to express this in days, but uses hours instead.
The reason for this is the mess that occurs when a leap second [5] or the summer/winter time changeover occurs between two dates. Does that count as a fraction of a day or not? Go forces the programmer to multiply the hour difference by 24 to get the day number – as an indication that this may not be entirely true.
It is easier to use the Unix epoch time on Linux; this gives you the number of seconds that elapsed since January 1, 1970. It does not include leap seconds that have occurred, but gives the same timestamp to the times before and during a leap second. The randDate()
function from line 93 in Listing 1 determines the Unix time for January 1st of the investigated year as well as the time stamp for January 1 of the following year and determines the time difference in seconds.
The rand.Intn()
function then selects a random number between
(inclusive) and the timestamp of January 1 of the following year (exclusive) from the math/rand package and adds the value to the start date. The result is a second timestamp sometime in the current year, which the time.Unix()
function converts into a time.Time
object from the Go standard library, whose month and day are output by Month()
and Day()
. Since Unix seconds are available as int64
and the random functions from math/rand expect and return normal ints, line 102 needs to mediate between the two and convert the types accordingly.
The random number generator provided by Go still has the unpleasant feature of supplying the same random values whenever you call the program; this is unlikely to offer users any lasting training benefits in the long run. For this reason, line 98 taps into a new entropy source, initializes it with the current time in nanoseconds as the seed, and thus creates the new random number generator in the r1
variable. Its Intn()
method therefore comes up with new random sequences each time the dateday
binary is called.
« Previous 1 2 3 Next »
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Canonical Bumps LTS Support to 12 years
If you're worried that your Ubuntu LTS release won't be supported long enough to last, Canonical has a surprise for you in the form of 12 years of security coverage.
-
Fedora 40 Beta Released Soon
With the official release of Fedora 40 coming in April, it's almost time to download the beta and see what's new.
-
New Pentesting Distribution to Compete with Kali Linux
SnoopGod is now available for your testing needs
-
Juno Computers Launches Another Linux Laptop
If you're looking for a powerhouse laptop that runs Ubuntu, the Juno Computers Neptune 17 v6 should be on your radar.
-
ZorinOS 17.1 Released, Includes Improved Windows App Support
If you need or desire to run Windows applications on Linux, there's one distribution intent on making that easier for you and its new release further improves that feature.
-
Linux Market Share Surpasses 4% for the First Time
Look out Windows and macOS, Linux is on the rise and has even topped ChromeOS to become the fourth most widely used OS around the globe.
-
KDE’s Plasma 6 Officially Available
KDE’s Plasma 6.0 "Megarelease" has happened, and it's brimming with new features, polish, and performance.
-
Latest Version of Tails Unleashed
Tails 6.0 is based on Debian 12 and includes GNOME 43.
-
KDE Announces New Slimbook V with Plenty of Power and KDE’s Plasma 6
If you're a fan of KDE Plasma, you'll be thrilled to hear they've announced a new Slimbook with an AMD CPU and the latest version of KDE Plasma desktop.
-
Monthly Sponsorship Includes Early Access to elementary OS 8
If you want to get a glimpse of what's in the pipeline for elementary OS 8, just set up a monthly sponsorship to help fund its continued existence.