Understanding Epoch Time

Understanding Epoch Time

By Joe Gilmore On January 10, 2015 In Web Design and Geeky stuff

Understanding Epoch Time

Understanding Epoch time is a useful thing to know when it comes to Web Development. If you are to develop a system where your users are spread around the world and you wish for them to see times that are relevant to them, then this article looks to explain how you can use it with MySQL and use JavaScript to display them in a human readable format.

Imagine this scenario: I have my own social media website and I update my status - when I add this post I would record in the MySQL table like this: INSERT INTO status_update (status,date_added) VALUES ('Joe is out walking the dog',NOW()); - the time that is recorded in my server is the exact time down to the second but it's set to whatever timezone my server is in.

The problem is that when I retreive back the time that the post was made then it'll only be relevant if I'm in the same time-zone as my server... this is where Epoch time comes in handy.

Our Servers Time:

Lets check what time the MySQL is reporting back using SELECT NOW(); which is: 2015-11-03 07:30:38 - which is correct for me as I'm currently based in London, UK which is the timezone my server is configured to. But if someone from America, New Zealand or Japan is reading this page then it's clearly wrong for them.

Using Unix Timestamp:

The Unix Timestamp is simply an amount of seconds passed since the following date: Jan 01 1970. (UTC) - UTC is an abbreviation for Coordinated Universal Time so it doesn't matter what timezone you are in it should always be the same (as long as your computers clock is working correctly)

Now if I do the following SQL call: SELECT UNIX_TIMESTAMP( NOW() ); it returns back: 1446535838 which is the amount of seconds since Jan 01 1970. (UTC) and is true for everyone no matter where they are based in the world!

Making it more readable..

Now that we are returning back a more useful time we now need to make it a bit easier for our users to understand, this can be done using JavaScript as the users browser can easily read these Unix Timestamps and convert them to an better format: var myDate = new Date( yourEpochDate *1000);document.write(myDate.toGMTString()+"-"+myDate.toLocaleString()); - which displays as Tue, 03 Nov 2015 07:30:38 GMT-03/11/2015 07:30:38 - which is what we want as this is then correct for any of our users around the world

Making it a lot more readable...

Ok so the output above is correct and we can start to see the time no problem, but if we really want to make our status updates look better, we should go that extra mile. Let's make it so that if the status was updated within the last 30 seconds it says "Updated: Just Now", if was updated between 30 seconds and 1 minute it'll say "Updated: Less than a minute ago" - then we'll show how many minutes ago it was updated: "Updated: 5 minutes ago", then after 60 minutes we'll just show the hours: "Updated: 3 hours ago" then after 24 hours we say "Updated: Yesterday at 20.07" then if it's within the same year we'll say "Updated: 2nd January at 14.47", and if it was the previous year we'll say: "Updated: 30th December 2014 at 12.02"

The JavaScript Function:

function formatTimestamp(ts){
    var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
    var now = new Date();
    var ts = new Date(ts*1000);
    var diff = (now.getTime() - ts.getTime())/1000; 
    var year_now = now.getFullYear();
    function s(x){return x>1?'s':'';}//Append an s function i.e. 3 days ago
    function lz(x){return x<10?'0'+x:x;}//Leading Zeros Function
    var out,m,h,d;
    var ts_m = ts.getMinutes();
    var ts_h = ts.getHours();
    var ts_d = ts.getDate();
    var ts_y = ts.getFullYear();
    if(diff<=30){out='Just now'}
    else if(diff<=60){out='Less than a minute ago'}
    else if(diff>=60 && diff<=3599){
	m = Math.floor(diff/60);
	out=m+' minute'+s(m)+' ago'
    }else if(diff>=3560 && diff<=86399){
	h = Math.floor(diff/3600);
	out=h+' hour'+s(h)+' ago'
    }else if(diff>=86400 && diff<=(86400*2)){
	out='Yesterday at '+lz(ts_h)+':'+lz(ts_m)
    }else if(diff>=(86400*2)){
	out=ts_d+' '+months[ts.getMonth()]+' '+(year_now>ts_y?ts_y:'')+' at '+lz(ts_h)+':'+lz(ts_m)
    }
    return out;
}