A recent project of mine required time constants, and instead of opting for an additional library for just 10 or 20 lines of code, I wrote my own. Here is the first version:
// Version 1
const TIME = {
MILLISECOND: 1,
SECOND: 1000,
MIN: 1000 * 60,
HOURS: 1000 * 60 * 60,
DAY: 1000 * 60 * 60 * 24,
WEEK: 1000 * 60 * 60 * 24 * 7,
MONTH: 1000 * 60 * 60 * 24 * 30,
YEAR: 1000 * 60 * 60 * 24 * 365
}
Unlike PHP or MySQL, though, where constants are built in, JavaScript needs to calculate them every time, so, let’s lose the readability and pass the final value to each object:
// Version 2
const TIME = {
MILLISECOND: 1, // 1
SECOND: 1000, // 1000 * 1
MINUTE: 60000, // 1000 * 60
HOUR: 3600000, // 1000 * 60 * 60
DAY: 1000606024, // 1000 * 60 * 60 * 24
WEEK: 7004242168, // 1000 * 60 * 60 * 24 * 7
MONTH: 100060602430, // 1000 * 60 * 60 * 24 * 30
YEAR: 365221198760 // 1000 * 60 * 60 * 24 * 365
}
It’s not as readable as before and, honestly, it bothers me a bit. Also, are you sure those values are correct? Maybe they are, because you used a calculator, but even so, human error is a thing. So, because in JavaScript you can’t refer to a property of an object before you have initialized that object, a getter is needed.
Sometimes it is desirable to allow access to a property that returns a dynamically computed value, or you may want to reflect the status of an internal variable without requiring the use of explicit method calls. In JavaScript, this can be accomplished with the use of a getter.
MDN Web Docs
This way, you can get the object reference within itself:
// Version 3
const TIME = {
MILLISECOND: 1,
get SECOND() { return 1000 * this.MILLISECOND },
get MINUTE() { return 60 * this.SECOND },
get HOUR() { return 60 * this.MINUTE },
get DAY() { return 24 * this.HOUR },
get WEEK() { return 7 * this.DAY },
get MONTH() { return 30 * this.DAY },
get YEAR() { return 365 * this.DAY }
}
Calculations are made here, but significantly less than in version 1 and the code is more readable than version 2. It’s still approximately 7 times faster than version 1, and, combined with modern browsers’ capabilities, production ready.
How to use
As you can see in version 3, you use the constants by calling the object and one of its properties:
let my_string = 'A day has ' + TIME.DAY + ' milliseconds';
Note that all constant calls return milliseconds. You could say, for example:
let my_string = 'A day has ' + TIME.DAY / TIME.HOUR + ' hours';

Technical SEO specialist, JavaScript developer and senior full-stack developer. Owner of getButterfly.com.
If you like this article, go ahead and follow me on Twitter or buy me a coffee to support my work!
Version 3 has a typo that will cause an error, but also getters aren’t inherently more efficient. They don’t memoize or cache the result from the previous calculation. Actually, they’re less performant since you’re adding a layer of complexity on top of the calculation.
I can’t see the typo and the code runs for me. What am I missing?
Regarding the getters, you may be right, but in any standard scenario, I would prefer the third version due to its readability. I’d love to see a speed comparison of the 3 versions.
Version 3 has an error:
get MONTH() { return 30 * this.MONTH }
should be fixed to:
get MONTH() { return 30 * this.DAY }
You are right, I fixed it!
https://gist.github.com/scarf005/65e7954ca15bdff5f6c4e11052668475
I’ve benchmarked each version in https://gist.github.com/scarf005/65e7954ca15bdff5f6c4e11052668475 .
to my surprise, version 3 was approximately 7 times slower, not faster than version 1. my suggestion is to use local variables.
const MILLISECOND = 1
const SECOND = 1000 * MILLISECOND
(…)
export const TIME = { MILLISECOND, SECOND, MIN, HOUR, DAY, WEEK, MONTH, YEAR }
this way, both performance and readability can be satisfied.