<3 some CO love
Lean-to in the hills above Crested Butte, CO.
Photograph by Jace Cooke.
A very circuitous discussion on our relationship with time zones from the perspective of a programmer.
Recently, I was dealing with a software bug. Well, it was kind of a time zone issue? Nope. Definitely a server/deployment problem. As you can tell, it was a confusing one to define. It first manifested when, even though tests were passing, expected behavior was absent in production: our once daily notifications triggered by
cron weren’t sending. So, I checked out the logs, found a SQL syntax error due to a SQL incompatibility between SQLite3 (dev) and MySQL (production), and fixed it. Expecting that since I deployed the fix before noon and the scheduled job that would execute the fix should run at 1730, I thought that we’d see the working notifications later that day. No such luck — the same error happened again! Based on what I understood about the problem, the new code should disallow the possibility of that error occurring at all. Well, digging in a little more, it seemed like the errors were happening at the wrong time. The job was set to run at 1730, the server time was set to MST as seen by using the
date program, but the jobs were running at odd times. My first theory, which turned out to be correct, was that a running
cron service does not dynamically pick up changes made to a system’s time zone. Thus, if the server had only been booted once, and
cron was started prior to the time zone being changed to MST, then
cron would still be running on UTC. I plopped a dummy job into the
crontab that appended the
date output to file and played around with the times it was supposed to run and saw that jobs were running 7 hours earlier than they should. I left the dummy job in place while
cron restarted and the
date entries stopped appearing. Once the dummy job’s time was set back 7 hours, the
date entries started showing up again! Easy fix for an issue that took some digging to figure out.
One dead end approach that turned up something interesting was trying to look at the environment of a running process. As I was researching
cron, it seemed like inspecting the
TZ environment variable for the process could show the discrepancy. It ended up that that variable was not set at the time the process was spawned, but learning how to look at the environment a process was spawned with was interesting:
psto determine the
PIDof the process to look at
cat /proc/<pid>/environ(basic approach)
There are a few more suggestions here.
Ok, so technically it’d be UTC, but GMT just sounds better. What is a time zone anyway? This is totally not researched, but my guess is that time zones are useful for making the same parts of the day happen at approximately the same. Noon is around when the middle of the daylight hours are, or something like that.
Anymore I feel like maintaining such a system is inefficient and will continue to become more so. As programmers write more and more software to automate our global lives, how much will be lost because of time zones and daylight savings time? It seems silly that, in an always-on world, we’d be needing to waste cycles on determining what time it is in another place. Instead, if we could standardize on a 24 hour clock where the current UTC noon is the current UTC noon, we could start abandon any mental or computational thought on the subject.
Obviously, I’m not putting enough thought into how many existing systems this change would break. It is wonderful to think about how simple we could make it if we wanted though…
What’s the deal with all these awkwardly spaced time parts?!
Alright. Well, we humans have ways of dealing with this. It’s called the metric system. Kind of. The metric system, or more generally, the International System of Units (SI), has to do with measuring things. In the case of time, it provides a measurement called the second, which is used to measure time duration. Originally, it was defined as 1/86400th of a “mean solar day”, but is now based on something something cesium something. Pish posh.
Well, the SI second doesn’t help us too much in terms of making our different time segments related in terms of powers of 10. There’s a different system for that called Decimal Time which splits a day into 10 hours, each with 100 minutes, each with 100 seconds. The odd part about this system is that, even though the name of each segment (hour, minute, second) is the same, their lengths are each different from what we’re used to. That would feel a bit odd at first…
A random bit of trivia for you. The Swatch company, in the 90s, created an alternate time system based on Decimal Time (see above) called Swatch Internet Time. Each
.beat was equivalent to the duration of one decimal minute, meaning that there were 1000
.beats in a day. No time zones were recognized and the goal was to create a time system that citizens of the internet could use. Pretty ahead of their game, no?
All this writing was a lot. I know. But, it’s been on my mind a lot lately, what with all the space talk, programming issues, and Hacker News discussions. Maybe you learned something? Or, maybe you’re just mad for reading this far.
So, I’m releasing a new Ruby gem and would like to explain some of the backstory.
Recently, I worked on a small Rails contract and part of the work was to fix a bug where a person’s age was being displayed wrong. The format desired was “X years X months X weeks X days” but the calculation seemed to be inconsistently off by a few days. The project had been using the time_diff gem, but after examination, it was clear what the problem was: it was using standard lengths for the months. Although, 316 days is technically ten months, two weeks, and two days if every month has 30 days, every month does not have 30 days. So, I started looking at other options:
end_date, which doesn’t seem to be how humans think about this type of calculation
time_diffwith some very minor changes.
Based on my findings, I decided to create a new gem with the following goals:
spancan and should get better.
I’m really looking forward to feedback on
span. Check it out, read the code, and send issues and pull requests with feedback.