Javascript es with the Date object, providing several utilities for working with specific points in time.
However, what if I want to represent a time of day, such as 15:00
which simply denotes a point during any day, rather than being tied to a specific date?
I know I could use a string, but is there a representation which is more standardised for this kind of data?
Javascript es with the Date object, providing several utilities for working with specific points in time.
However, what if I want to represent a time of day, such as 15:00
which simply denotes a point during any day, rather than being tied to a specific date?
I know I could use a string, but is there a representation which is more standardised for this kind of data?
Share Improve this question asked Jan 26, 2015 at 1:07 csvancsvan 9,47412 gold badges55 silver badges94 bronze badges 03 Answers
Reset to default 10Depending on how granular you wanted to be, you could use seconds or milliseconds. So:
var time = 900; // 900 seconds = 15:00
Then in your JavaScript you could instantiate that time in todays date like so:
// get the current date and time
var date = new Date();
// reset the hours, mins, seconds, ms
date.setHours(0, 0, 0, 0);
// set according to the stored time
date.setSeconds(time);
In answer to a more standardised approach: most puters use the Unix Timestamp, which counts the number of milliseconds from 1 January 1970 UTC. But, as you've already stated, the date is not important to you.
Regardless of the importance of the day/month/year - using seconds or milliseconds is a good way of rehabilitating your data back into the mon JavaScript Date object, which is a very useful thing at the application level.
For a mammoth amount of over-consideration and syntactic sugar, you may or may not find Moment useful.
var time = 900;
// get the current date and time
var date = new Date();
// reset the hours, mins, seconds, ms
date.setHours(0, 0, 0, 0);
// set according to the stored time
date.setSeconds(time);
document.body.innerHTML = date;
I don't think there is a standard way of doing what you need but I would do something like the following example. The idea is that we're using a date object for the time parts and ignoring everything else.
function time(str) {
var date = '1970-01-01 {hr:min}:00';
var _time = new Date(date.replace('{hr:min}', str));
return {
getHours: function() {
return _time.getHours();
},
getMinutes: function() {
return _time.getMinutes();
},
getSeconds: function() {
return _time.getSeconds();
},
toString: function() {
return _time.toLocaleTimeString(); // or use `toTimeString()`
}
};
}
Usage:
var t = time('15:30');
var t2 = time('11:45');
t.getHours(); //=> 15
t.getMinutes(); //=> 30
t.getSeconds(); //=> 0
// We're getting AM and PM for free
t.toString(); //=> "3:30:00 PM"
t2.toString(); //=> "11:45:00 AM"
Update:
The example above doesn't make use of prototypes so every object gets a copy of those methods. If you're going to have a lot of objects, then you might want to use the following version, which uses prototypes. The downside of this version is that it exposes the this._time
property.
var time = (function() {
var date = '1970-01-01 {hr:min}:00';
var methods = {
getHours: function() {
return this._time.getHours();
},
getMinutes: function() {
return this._time.getMinutes();
},
getSeconds: function() {
return this._time.getSeconds();
},
toString: function() {
return this._time.toLocaleTimeString(); // or use `toTimeString()`
}
};
return function(str) {
var _instance = Object.create(methods);
_instance._time = new Date(date.replace('{hr:min}', str));
return _instance;
};
}());
var t = time('15:30');
var t2 = time('11:45');
I was looking into this recently as well, since I also wanted to represent time independent of date in JS.
I searched for a standard solution and quickly found there is none. The only thing that came close was to use Date
and only set time properties on it, as suggested by @shennan. But that felt wrong, since it's exposing methods that have nothing to do with daytime, like getFullYear()
, which will confuse people if it gets passed around in a program.
Other option was to use some datetime library, but introducing it to just represent a simple time also felt wrong, since those are often heavy in terms of size and their API.
I think the approach @istos went for - exposing only time related methods and using date as the core - is the best. However, it has one little issue that will give you incorrect results if you do calculations with dates and are outside of the UTC+0 timezone, and that is the usage of getHours()
. This method gives you localized hour count, which skews the result when you subtract eg. 2:00
from 4:00
, so you want to use getUTCHours()
instead, which returns hour count relative to UTC+0.
So here is a modern, memory efficient solution (by using class
, every instance refers for methods to one mon prototype) which allows for calculations since it both exposes and allows to create itself by using milliseconds (using TypeScript):
class Time {
private date: Date
constructor(...args: [number] | [number, number]) {
if (args.length === 1) {
this.date = new Date(args[0])
} else {
const hours = args[0]
const minutes = args[1]
this.date = new Date(Date.UTC(1970, 0, 1, hours, minutes))
}
}
getHours() {
return this.date.getUTCHours()
}
getMinutes() {
return this.date.getUTCMinutes()
}
getTime() {
return this.date.getTime()
}
toString() {
return `${padWithZero(this.getHours())}:${padWithZero(this.getMinutes())}`
}
}
const t1 = new Time(4, 30)
const t2 = new Time(1, 15)
const t3 = new Time(t1.getTime() - t2.getTime())
t3.getHours() // 3
t3.getMinutes() // 15