← Back

miniblog

Thoughts, notes, and things I find interesting.


TIL: .NET caches the local time zone

After spending some time trying to figure out why one of our apps wasn't working, I stumbled upon the fact that .NET caches the time zone (avoiding reading from /etc/localtime on Linux every time a conversion is needed). This is easy to verify with this short snippet:

using static System.Console;

while(true) {
        WriteLine($"Current time: {DateTime.Now}");
        WriteLine($"TimeZone: {TimeZoneInfo.Local.Id}");
        WriteLine($"UtcNow: {DateTime.UtcNow}");
        WriteLine(new string('-', 15));
        await Task.Delay(5_000);
}

After changing the time zone of the system, DateTime.Now and TimeZoneInfo.Local.Id keep returning the same values as before.
Solution? Well, the recommendation is to always work in UTC, but if for some reason your code depends on the time zone, and restarting the app is not possible, just call TimeZoneInfo.ClearCachedData(). It could be combined with FileSystemWatcher (if you are using Linux and the environment variable TZ is not set) to only clear when a change is detected.


Screensavers

Back when I was a child, I was fascinated by screensavers, now a relic from the past. Imagine my surprise when I discovered (just recently, I must admit) that behind the scenes, a .scr file is just a Windows executable!

file description of src file

Well, that means that I could create my own screensaver, right? I just need to create a GUI app that renders fullscreen. Technically yes, but it needs to support some arguments so it can play nicely with the Control Panel configuration utility, namely /s for fullscreen mode, /c for configuration, and /p for the preview mode.
We can ignore the /s if we make the app render on fullscreen by default. To keep things simple, we only show a message dialog for /c indicating that we don't support configuration. /p is a little more complicated, as it involves getting a window handle and doing some wiring to make it work (that is, showing a preview of the screensaver on the Control Panel utility).
The next step is to decide what to render. We can try to replicate the now-missing Starfield screensaver.

Starfield GIF

This effect is based on projecting the 3D coordinates of each star onto a 2D plane using the following equations, while decreasing the Z value (the star's depth) on each iteration:

star_x = star.X / star.Z + SCREEN_WIDTH / 2;
star_y = star.Y / star.Z + SCREEN_HEIGHT / 2;
And that is pretty much the gist of it. Full code can be found on the GitHub repository.


Quine

A quine is a program that outputs its own source code. There is something magical (or perhaps unsettling) about a program creating itself. Here is one in C#:

var s = """
var s = ""{1}
{0}
""{1};
System.Console.WriteLine(string.Format(s, s, (char)34));
""";
System.Console.WriteLine(string.Format(s, s, (char)34));


On naming

Naming is the eternal struggle of every software developer. Naming is hard, really hard, and not only for variables, methods, or classes, but also for processes and methodologies. This week, I spent more time in meetings than needed just to explain an internal process to our teams, simply because a poor choice of name was causing an uproar among departments. It turns out that knowing the true name of a thing is rarer than we think. Next time, think twice before sticking a name on something.


TIL: Quirkiness of C|C++

Digraphs! A legacy of C, inherited by C++, that, back in the day, was useful for writing some correct, although pretty obscure code due to some constraints on characters like '# { } [ ]'. Let's take a look at the following hello, world! program:

%:include<iostream>

using namespace std;

int main()
<%
    cout << "hello, world!" << std::endl;
    return 0;
%>

Pretty cool, right? Trigraphs also exist but they are disabled on most compilers by default. Please don't use them in production code.