About Time

you : Hey, what's the time?

me : This is your lucky day because I am a programmer and I ❤ talking about time. See, the preferred way of dealing with time is to always work in UTC, converting to localtime only when generating output to be read by humans.

you : No, I just mean the time by your watch.

me : Yeah, that's the localtime but you should avoid dealing with it because you don't understand time.

you : What's there to understand, 365 days in a year, 24 hours in a day, 60 minutes in an hour and 60 seconds in a minute, now would you just tell me the goddamn time.

me : 365 days in a year except leap years which have 366 days, 24 hours in a day except some days could have 23 hours and some could have 25 hours or some other amount of hours, whole or not because of daylight saving time (DST), 60 seconds in a minute except when leap seconds are inserted, a minute will be 61 seconds long. You really should make more time for understanding time.

you : Yeah, great, I think it's time for me to leave.

me : No, there's no time for that, it's story time, this is a story as old as time, the story of time itself. Long ago, before the advent of universally synchronized times and timezones, local time was synchronized to movements of the sun, noon was when the sun was high in the sky, a purely local event. The local clock keeper of the town would ensure the clock matched the sun each day and everyone took their time from the official local clock. With the advent of faster travel, in particular the railroads, a need for a standard, predictable, time arose. Many long rail lines only had a single-track and with electronic communications yet to be invented running trains strictly on schedule was vital to avoiding collisions.

To cater to this need for a standard, predictable time, in 1884 an international convention divided the world into twenty-four time zones centered on the "prime meridian", which was originally defined as longitude zero, a line that bisected a critical part of the main telescope at the Royal Observatory at Greenwich in south-east London. All countries defined their time as some offset, positive or negative, away from "Greenwich Mean Time" (GMT). GMT is based on mean local time at the agreed upon zero longitude.

In the 1970s the world standards switched from "GMT" time to Atomic Time, or "UTC" time (Coordinated Universal Time). GMT follows all movements of the earth and is slightly different each day. UTC is atomic and exactly the same each day. As the years go by GMT drifts from UTC. When this difference approaches 0.9 second the Bureau International des Poids et Mesures (International Bureau of Weights and Measures, a.k.a., BIPM) in France declares a day in the future that will have a "leap second" added (or subtracted) to prevent the drift between the two times from reaching a full second. These are effectively random intervals that can not be predicted very far in the future. Leap seconds are typically implemented on the last day of June or December, but may occur at the end of any quarter.

Leap seconds may be positive or negative, adding or subtracting a second on the last minute of a day. On a "leap second" day the day ends at the completion of 23:59:58 for negative leap seconds and after the completion of 23:59:60 for positive leap seconds. The next second is "00:00:00" of the next day, which is also known as 24:00:00. Leap Seconds are added (or subtracted) at the same time around the globe at 23:59:59 UTC, whatever the local time may be, regardless of any local time zones.

you : Cool story bro, but I am getting late for a meeting, gotta go.

me : Whether you are getting late or not would depend on the timedelta between two localtime timestamps which is a surprisingly complex operation because of daylight saving time. "Saving time" is a concept that allows nations away from the equator to adjust their clocks by a nationally agreed upon time period to allow for the change of dawn and dusk that occurs with the change of seasons. "Spring forward and fall back" is often used to refer to this process of setting clocks forward in spring and backwards in fall. There are no international standards for DST but fortunately GMT and UTC are not subject to daylight-saving rules. UTC is thus our beacon of constancy in a sea of turmoil.

Let me give you some examples of the problems caused by DST in dealing with localtime, in the US/Eastern timezone on the last Sunday morning in October, the following sequence happens -- 01:00 EDT occurs, 1 hour later, instead of 2:00 AM the clock is turned back 1 hour and 01:00 happens again (this time 01:00 EST). In fact, every instant between 01:00 and 02:00 occurs twice and given a localtime timestamp in this period, there is no way to know whether the timestamp refers to a time before or after the end-of-daylight-saving-time transition and yeah the day has 25 hours. Similarly, 2:30 AM on the first Sunday of April never happens in the US/Eastern timezone, as the clocks are made to jump forward at 2:00 AM skipping the entire hour, leaving the day with 23 hours.

you : Enough of crazy talk, stop it.

me : Don't believe me? Time to walk the talk then, let me quickly drop into a python 3.5 REPL:

import time

# Time in seconds since the epoch
time.time()
# Out : 1474645365.8843284

# What is epoch?
# The epoch is the point where the time starts i.e.
time.asctime(time.gmtime(0))
# Out : 'Thu Jan  1 00:00:00 1970'

utc_time = time.gmtime()
time.asctime(utc_time)
# Out : 'Fri Sep 23 15:50:16 2016'

# The default argument of time.gmtime() is time.time()
time.gmtime() == time.gmtime(time.time())
# Out : True

time.daylight
# Out : 0
# Nonzero if a DST timezone is defined

time.tzname
# Out : ('India Standard Time', 'India Daylight Time')
# A tuple of two strings: the first is the name of the local non-DST timezone
# The second is the name of the local DST timezone 
# If no DST timezone is defined, the second string should not be used

time.timezone
# Out : -19800
# The offset of the local (non-DST) timezone, in seconds west of UTC
# time.altzone which gives the offset of the local DST timezone should be used if time.daylight is nonzero

# -19800 in hrs
-19800/(60*60)
# Out : -5.5
# Indian Standard Time is UTC + 5:30

local_time = time.localtime()
time.asctime(local_time)
# Out : 'Fri Sep 23 21:47:11 2016' 
time.asctime(time.gmtime(time.time() - time.timezone))
# Out : 'Fri Sep 23 21:47:11 2016' 

# Relation between localtime and UTC time:
time.gmtime(time.time() - time.timezone) == time.localtime()
# Out : True

    

me : Woah, time flies, it's 9:47 PM already.

you : Go to hell.