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 common 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