Don’t fret, programs involving time are no harder to develop or test than any other programs. Time carries some inherent complexity (“business rules”) that you need to learn. I guess the main problem is appreciating complexity of time, since it’s something we are all familiar with and tend to think about as “simple”. But since you ask a question here, it seems you already overcame this particular issue.
The fundamental thing is that there are at least two “times”. Local time, or wall-clock time, is the time that you see at the clock face at some instant. This is generally subject to timezone, various laws, rules etc. A single wall-clock time might map to multiple instants - in time zones that observe Daylight Saving Time, clock “moves back” an hour in fall. In many European countries clocks showed 02:13 AM twice on October 27, 2024. Wall-clock time is what most of everyday conversations refer to.
The second type of time does not have unique name, as far as I can tell. I’m going to call it monotonic time. This is how we biologically perceive time - as something that always moves forward. You can’t go back in time and every monotonic time uniquely expresses a single instant. UTC is often considered as a shortcut of monotonic time, but it’s still affected by things like leap seconds. Unix timestamp is a bit better in that regard, but then you need to keep track of leap seconds somewhere else.
As a data normalization step, programmers tend to display all times in user interface in wall-clock time, but store it in database as monotonic time (usually UTC). This is not completely wrong, but leaves open the question what should happen if timezone definition changes between a moment when data was stored and a moment when data is displayed. This blog post goes into more detail:
So as a base rule, learn how time is displayed to users, how it is stored and think what may go wrong when you translate between these two.
In particular, be wary of heuristics that are often used to obtain the user time:
- Current user local time. User may be traveling when using the system. User may be interacting with event in different time zone. User might want local time or event time, depending on nature of event (if I sign up to conference in LA, I don’t care it’s going to be 3 AM my local time if I intend to attend in person, but I do care if I intend to attend through video chat).
- User language. Many languages are spoken in one country only, and that country might have single time zone. But just because I set my language to German does not mean I want whatever time is right now in Germany.
- User location. Again, user may be traveling. Some places are subject to border dispute between countries that use different time zones.
Some of these heuristics might be right in context of specific project. It’s worth making them explicit.
If user has the ability to set their timezone, look out which displayed times it does affect. You would expect it to affect most of times in application, except explicitly noted. But what about email notifications? What about mobile app? What about push notifications?
You can learn more about time calculations in following three articles:
https://unix4lyfe.org/time/
Finally, this article has great collection of in-depth reading near the end: