Untuk versi bahasa Indonesia dari entri ini, klik di sini.
Hello! This time, I want to discuss about ways to present relative time.
To present time data, e.g. time of delivery and last modified time, usually we use relative time alongside absolute time. What are the differences?
Absolute time is a time which is based on a specific fixed event (epoch). For example, the 1 CE is based on Isa's/Jesus' birth PBUH. The 1 Hijri is based on the migration of Muhammad PBUH from Mecca to Medina.
Relative time is a time distance or time difference between two events, usually from an event to current time. For example, this post was published a few minutes ago. The October month is coming in 4 days.
One of the advantages of relative time is that there is no need to take time zone into account when understanding the meaning of the displayed date/time. For example, in contents targeting international readers, sometimes on different time zones are displayed to make it easier for readers. If there are supports for updating content dynamically, many will choose to show countdowns alongside its absolute time, one of the ways to present relative time.
Ways to Present Relative Time
There are many ways to present relative times. For example, the ones on websites or applications usually use minute unit as their smallest unit. The next ones are hours, days, weeks or months, and so on. The next unit is used after it reaches 1 unit, i.e. the hour unit after 60 minutes, the day unit after 24 hours, and so on.
It does not have to be that way. For relative time, I prefer if the next unit is used after it reaches 1.5 or 2 of the unit. For example, the hour unit after 90 or 120 minutes, the day unit after 36 or 48 hours, and so on.
Another thing is that there are those who round downward (floor), round upward (ceil), or round to the nearest (round). I choose to round downward.
The problem is that most libraries (1) use one unit as the limit for the next unit, (2) use weird limits in my opinion, or (3) round upward.
Because of that, this time, I want to make my own version as I want. What I want is a version which uses second as its smallest unit, uses the next unit after reaching 2 of the unit, and rounds downward.
Relative Time Conversion Function
I am going to use JavaScript language. One of the reasons is that this code can be tested in this very page.
Below is a basic definition of relativeTime function which accepts two parameters which are time of the event and epoch for calculating the relative time. The epoch parameter is optional and it defaults to current time at call.
function relativeTime(time, epoch) {
if (epoch == undefined) {
epoch = new Date();
}
// The diff value is in milliseconds.
let diff = time.getTime() - epoch.getTime();
// ...
}
The diff variable is for determining which text to be shown.
The first case is when the absolute value of diff is smaller than 1 the smallest unit being used.
// If diff is below 1 second,
if (Math.abs(diff) < 1000) {
return "now";
}
For the next step, we get the sign of diff. After that, we make diff be always positive by using absolute function to make determining which unit to be used easier.
// A negative diff value means that the event is in the past.
const past = diff < 0;
diff = Math.abs(diff); // Absolute value
The next parts are repeated based on units used. There are three main steps: (1) converting diff to the next unit, (2) checking whether is below or equal to 2 of the unit, and (3) presenting based on past vs. non-past.
diff /= 1000; // Milliseconds to seconds
if (diff <= 2 * 60) {
return past ? // "ago" vs. "in"
Math.floor(diff) + " seconds ago" :
"in " + Math.floor(diff) + " seconds";
}
// The above code is repeated for minutes, hours, and days.
Below is the complete code.
// Relative time in English
function relativeTime(time, epoch) {
if (epoch == undefined) {
epoch = new Date();
}
// The diff value is in milliseconds.
let diff = time.getTime() - epoch.getTime();
// If diff is below 1 second,
if (Math.abs(diff) < 1000) {
return "now";
}
// A negative diff value means that the event is in the past.
const past = diff < 0;
diff = Math.abs(diff); // Absolute value
// Seconds //
diff /= 1000; // Milliseconds to seconds
if (diff <= 2 * 60) {
return past ?
Math.floor(diff) + " seconds ago" :
"in " + Math.floor(diff) + " seconds";
}
// Minutes //
diff /= 60; // Seconds to minutes
if (diff <= 2 * 60) {
return past ?
Math.floor(diff) + " minutes ago" :
"in " + Math.floor(diff) + " minutes";
}
// Hours //
diff /= 60; // Minutes to hours
if (diff <= 2 * 24) {
return past ?
Math.floor(diff) + " hours ago" :
"in " + Math.floor(diff) + " hours";
}
// Days //
diff /= 24; // Hours to days
return past ?
Math.floor(diff) + " days ago" :
"in " + Math.floor(diff) + " days";
}
Example result: The publication of this post is when?
Final Words
Even though we can create our own relative function ourselves, we may not be able to apply it for applications created by other parties. Because of that, I hope that every application has a way to see absolute time alongside relative time.
Basically, I prefer to be able to see exact values instead of approximation if possible. Even this blog also chooses to show publication time using absolute time. Relative times usually shown usually lose their precisions. For example, absolute time is usually precise until seconds, meanwhile relative time usually loses its precision over time (minutes ago, hours ago, and so on).
That's all I write this time. Hope this helps!
