Some people get too cute about compacting their code, for it then becomes too difficult to understand.
There is an error with meridiem when the time is 12, for midday is not AM, it’s PM, all the way from 12:00 daytime.
Here is a converted version of the code, to help with understanding what it does.
function DateTime() {
var hour = objToday.getHours();
var minute = objToday.getMinutes();
var meridiem = hour > 12 ? "PM" : "AM";
if (hour > 12) {
hour = objToday.getHours() - 12;
} else {
if (objToday.getHours() < 10) {
hour = "0" + objToday.getHours();
}
}
if (minute < 10) {
minute = "0" + objToday.getMinutes();
}
today = + hour + ":" + minute + " "+ meridiem;
}
The proper rules for converting the time are found at What do AM and PM stand for.
Here’s how you correctly convert from 24-hour time to 12-hour time.
From 0:00 (midnight) to 0:59, add 12 hours and use am.
0:49 = 12:49 am (0:49 + 12)
From 1:00 to 11:59, just add am after the time.
11:49 = 11:49 am
From 12:00 to 12:59, just add pm after the time.
12:49 = 12:49 pm
From 13:00 to 0:00, subtract 12 hours and use pm.
13:49 = 1:49 pm (13:49 - 12)
Let’s not change what works, and use those rules in the code instead.
But first, to make sure that things keep working as they should, I’ll use some tests to help check that my changes work, and that the code continues to work throughout the changes.
No complex testing harness needs to be involved here, we can just use some console.log commands.
objToday = {
getHours: function () {return 1;},
getMinutes: function () {return 0;}
};
DateTime();
if (today !== "1:00 AM") {
console.log("Expected 1:00 AM but got ", today);
}
objToday = {
getHours: function () {return 10;},
getMinutes: function () {return 10;}
};
DateTime();
if (today !== "10:10 AM") {
console.log("Expected 10:10 AM but got ", today);
}
objToday = {
getHours: function () {return 12;},
getMinutes: function () {return 59;}
};
DateTime();
if (today !== "12:59 PM") {
console.log("Expected 12:59 PM but got ", today);
}
The last test fails, resulting in the logged output because it gets “12:59 AM” from the original code. We’ll fix that up shortly by following the instructions.
Deleting the original code, we start with:
var hour = objToday.getHours();
var minute = objToday.getMinutes();
var meridiem = "";
Following the instructions, we get the following code:
// Details on converting from 24 hour to 12 hour from:
// https://www.timeanddate.com/time/am-and-pm.html
if (hour === 0) {
hour += 12;
meridiem = "AM";
}
if (hour > 0 && hour <= 11) {
meridiem = "AM";
}
if (hour === 12) {
meridiem = "PM";
}
if (hour >= 13) {
hour -= 12;
meridiem = "PM";
}
And we just need to pad a zero in front of the minutes:
if (minute < 10) {
minute = "0" + minute;
}
today = hour + ":" + minute + " " + meridiem;
And the tests all pass with flying colors.
It’s normally not a good ideas to use global variables, so instead of using objToday, I’d have the function accept that as a function parameter, give it a more appropriate name, and return the time string from the function.
function format12Hour(date) {
var hour = date.getHours();
var minute = date.getMinutes();
...
return hour + ":" + minute + " " + meridiem;
}
var today = format12Hour(objToday);
Here’s the full function code that it’s ended up becoming.
It’s now much more usable and stable code that you can use in every project, and it’s easy to understand it too.
function format12Hour(date) {
var hour = date.getHours();
var minute = date.getMinutes();
var meridiem = "";
// Details on converting from 24 hour to 12 hour from:
// https://www.timeanddate.com/time/am-and-pm.html
if (hour === 0) {
hour += 12;
meridiem = "AM";
}
if (hour > 0 && hour <= 11) {
meridiem = "AM";
}
if (hour === 12) {
meridiem = "PM";
}
if (hour >= 13) {
hour -= 12;
meridiem = "PM";
}
if (minute < 10) {
minute = "0" + minute;
}
return hour + ":" + minute + " " + meridiem;
}