How to map array of numbers to timing values - javascript

Hi I have an array of numbers
let timearray = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23];
But the problem is I am displaying the array value in DOM, but I want it such a way that the values been mapped accordingly. Ex: If 0 -> 12:00am, if its 18 -> 6:00pm. How can I do that? Any idea guys? I can only think of map using if else. But that seems pretty ugly. Any idea guys?

You need to define your array like this:
const timearray = [
'12:00am',
'01:00am',
'02:00am',
'03:00am',
...
'10:00pm',
'11:00pm',
]
console.log(timearray[3])
// 03:00am

Here's an example map function you can use (and improve based on your needs):
const timeArray = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23];
const result = timeArray.map(t => {
const ampm = t % 12;
return `${ampm === 0 ? 12 : ampm}:00${t >= 12 ? 'pm' : 'am'}`;
});
console.log(result)

This is exactly what Array.map is for:
let timearray = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23]
let mapped = timearray.map(function(value) {
switch (value) {
case 0: return "12:00am"
// ..
case 18: return "6:00pm"
}
})
Or you can use an object
let timearray = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23]
let map = {
0: "12:00am",
18: "6:00pm"
}
let mapped = timearray.map(function(value) {
return map[value]
})
If you simply want to convert 24 hour time to 12 hour time AND NOT MAP THE VALUES then google for "24 hour time to 12 hour time" and you'll find an answer.

To convert integers to hours in 12-hour format with am/pm format you can use:
let timearray = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23];
timearray.forEach(x => {
var suffix = x >= 12 ? "pm":"am";
hours = ((x + 11) % 12 + 1) + suffix;
console.log(hours);
}
);
Based on code from this answer: Converting 24 hour time to 12 hour time w/ AM & PM using Javascript

You may also consider leveraging a library such as, moment.js (https://momentjs.com/) in this situation.
Here is an example of usage in your case:
var time = moment(2,"h:hh A");
console.log(time);
// 02:00am
The benefit from this approach is that you would be able to easily format the output, if required to.

Related

How to format MM/YYYY to YYYY-MM in js

I have this string:
var date = "3/2020";
I need the date in this format and adding a 0 if the month is less than 10:
var result = "2020-03";
I already did this:
var date = "3/2020";
var result = date.replace('/', '-');
console.log(result);
I just need a little help to know how could I add a 0 if the month is less than 10, and to change the order. Any Suggestion ?
I would suggest looking into moment.js
Then you can create a new date and set format and also set the wanted output format
const date = moment("3/2020", "MM/YYYY").format("YYYY-MM")
const date2 = moment("11/2020", "MM/YYYY").format("YYYY-MM")
console.log(date)
console.log(date2)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
Regex would help.
const input = "3/2020";
const [_, month, year] = /(\d+)\/(\d*)/.exec(input);
const output =`${year}-${month.toString().padStart(2, "0")}`;
console.log(output);
It can be done with a one-liner (which I have broken down into multiple lines to explain them) :
const date = "3/2020";
const dateFormatted = date
.split("/") // [ "3" , "2020" ]
.reverse() // [ "2020" , "3" ]
.map(d => /^\d$/.test(d) ? "0"+ d : d) // transforms "3" into "03" but leaves "2020" intact
.join("-"); // "2020-03"
console.log(dateFormatted)
Please use Array.map(), Array.split() and Array.reverse() functions.
Like this.
const date = "3/2020";
const result = date.split('/').map(val => val.length === 1 ? '0' + val : val).reverse().join('-');
console.log(result);
var date = "3/2020";
dateandmonth = date.split("/");
var event1 = new Date();
event1.setMonth(dateandmonth[0]-1);
event1.setYear(dateandmonth[1]);
MyDateString = (event1.getFullYear() + "-" + ('0' + (event1.getMonth()+1)).slice(-2));
I would never claim this is a clever way of doing it but, just for fun, you could manage everything using just String.prototype.slice() in a template string:
const input1 = '3/2020';
const output1 = `${(input1).slice(-4)}-${('0' + input1).slice(-7, -5)}`;
//-----------------------------------------^ prepend a '0' in case months < 10
const input2 = '11/2020';
const output2 = `${(input2).slice(-4)}-${('0' + input2).slice(-7, -5)}`;
// test
console.log(output1);
console.log(output2);
Obviously this works exclusively on the premises that you know for sure the input string format is consistent and predictable: 1 or 2 digits for the month, 1 separator character, 4 digits for the year.
I do not recommend using it in a real product, especially if the input string comes from an API and its format may change over time.
You can use date-fns library.
import { parse, format } from 'date-fns';
const convertDateFormat = (dateStr, oldFormat, newFormat) => {
let date = parse(dateStr, oldFormat, new Date());
return format(date, newFormat);
};
const date = new Date();
const formattedWithSlash = format(date, 'MM/yyyy');
console.log(formattedWithSlash); //'10/2021'
const changedFormat = convertDateFormat(formattedWithSlash, 'MM/yyyy', 'yyyy-MM');
console.log(changedFormat); //'2021-10'

How to replace time stamp in the string and round hours?

I have function that returns array or values that represent working hours. Array can return one or two elements. In case where only one element is returned this is pretty simple but when I have two that is the problem to find the way how to replace the existing values in the string. Here is example of the original string: 0600-2200 MAY 15-SEP 30; 0600-2100 OCT 1-MAY 14. I have function that finds the time stamp in the string and returns the hours. Example of the returning array is here: [16,15]. That array has two values and I need to replace 0600-2200 with first element in the array 16 and append the word hours to that. So final output should look like this: 16 hours MAY 15-SEP 30; 15 hours OCT 1-MAY 14. Here is example of the function that converts time stamp to string:
var timeSt = "0600-2200 MAY 15-SEP 30; 0600-2100 OCT 1-MAY 14";
const calcDifference = range => {
const time = range.split`-`.map(e => (+e.substr(0, 2) * 60 + (+e.substr(2))) / 60);
return time[1] - time[0];
};
const diffs = timeSt.match(/\d{4}\-\d{4}/g).map(e => calcDifference(e));
console.log(diffs);
The solution I have tried looks like this:
var hours = "";
for(var i=0; i < diffs.length; i++){
hours += timeSt.replace(regex,diffs[i] + " hours ");
}
Here is the output that above example produced:
16 hours MAY 15-SEP 30; 16 hours OCT 1-MAY 1415 hours MAY 15-SEP 30; 15 hours OCT 1-MAY 14
Seems that entire string was appended twice. I understand why that is happening but still can't get a good way how to fix this problem. The other thing that I noticed is that some time stamp values look like this: 0000 - 2359
In that case function that converts hours will return this: [23.983333333333334]. I would like to round up that value to 24 and that is the only case where the value should be rounded up to 24 the higer int his case. I time stamp looks like this: 0500-2330 function returns [18.5] and that value should not round. It should stay as it is. If anyone knows good way on how to fix these two problems please let me know.
For the problem of replacing you can provide a callback to .replace function in string.
const roundMinutes = 15;
const timeSt = "0600-0000 MAY 15-SEP 30; 0600-2145 OCT 1-MAY 14";
const calcDifference = range => {
const time = range.split`-`.map(e => +e.substr(0, 2) * 60 + (+e.substr(2)));
let [start, end] = time;
if (end < start) {
end += 24 * 60;
}
return end - start;
};
const formatted = timeSt.replace(/\d{4}\-\d{4}/g, (range) => {
const diff = calcDifference(range);
const full = Math.round(diff / roundMinutes) * roundMinutes;
const hours = Math.floor(full / 60);
const minutes = full - hours * 60;
const time = minutes === 0 ? `${hours}` : `${hours}.${minutes}`
return `${time} hours`;
})
console.log(formatted)
To change precision you can tweak roundMinutes constant.

How To Get The Sum of Two Times Using Moment.js?

I want to add two times like time1 = '00:05' and time2 = '10:00'. I want the result like the following after sum: result='10:05'. I used moment for that, this is what I used:
let x = moment.duration(moment(this.time1, "hh:mm A").add(moment(this.time2, "hh:mm A")));
let result = moment.utc(x.asMilliseconds()).format('HH:mm:ss');
but I got nothing, how can I do it?
You can't add time this way with moment because you are asking it to add two times, not a time plus a duration. If you want to add ten minutes, use the add() function with a duration.
moment(this.time2, "hh:mm A").add(10, 'minutes')
More here: https://momentjs.com/docs/#/manipulating/add/
It's not really clear in your question what 00:05 PM means. That doesn't look like a valid time. Moment will interpret it as 12:05pm, but it looks like you want to interpret it as 5 minutes. (That's the only way you get 10:05 as an answer). You can do this with moment if you don't include the PM part of the string.
moment.duration('00:05')
Is a duration of five minutes. You can add this to your time with:
moment('10:00 PM', '"hh:mm A"').add(moment.duration('00:05'))
// 22:05:00
Adding two periods works but it is currently not obvious in moment, how to format it like you want. Until they add format() to durations this will have to do:
var d = moment.duration('03:10:10').add(moment.duration('01:20:30'))
moment.utc(d.as('milliseconds')).format("HH:mm:ss")
// '04:30:40'
See Example For Add & Diff using moment.js .. cheers😀
// addTimes(["01:00", "00:30", "00:50"]) ---- 02:20
addTimes(times) {
let duration = 0;
times.forEach(time => {
duration = duration + moment.duration(time).as('milliseconds')
});
return moment.utc(duration).format("HH:mm")
}
// subtractTimes(["05:00", "00:30", "00:20"]) --- 04:10
subtractTimes(times) {
let totalDiff = 0
for (let i = 0; i < times.length; i++) {
let duration = moment.duration(times[i]).as('milliseconds')
if (i == 0) {
totalDiff = duration
}
if (i > 0) {
totalDiff = totalDiff - duration
}
}
return moment.utc(totalDiff).format("HH:mm")
}
function addTwoHours(firstTime = "20:40", secondTime = "18:40") {
firstTime = firstTime.split(':');
secondTime = secondTime.split(':');
const now = moment();
const expiration = moment().add({ hour: firstTime[0], minute: firstTime[1] }).add({ hour: secondTime[0], minute: secondTime[1] });
const diff = expiration.diff(now);
const diffDuration = moment.duration(diff);
return {
"years": diffDuration.years(),
"months": diffDuration.months(),
"days": diffDuration.days(),
"hours": diffDuration.hours(),
"minutes": diffDuration.minutes(),
"yourAnswer" : `${expiration.diff(now, 'hours')}:${diffDuration.minutes()}`
}
}
console.log(addTwoHours());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>

MomentJs get "time until" with two variables

I am trying to get moment.js to show me time until a specific date. I have that done doing this:
let date = 2017-03-27T12:00:00;
moment().to(date);
This shows: "in 10 days".
I'd really like this to show "in 10 days and 2 hours" or the two highest values. For example, 1 year and 5 months, 4 minutes and 30 seconds.
Is there a simple way to do this? I am currently working on a complicated method to handle this...
let years = moment(date).local().diff(moment(), 'years');
let months = (moment(date).local().diff(moment(), 'months'));
let days = (moment(date).local().diff(moment(), 'days'));
let hours = (moment(date).local().diff(moment(), 'hours'));
let minutes = (moment(date).local().diff(moment(), 'minutes'));
let seconds = (moment(date).local().diff(moment(), 'seconds'));
//The above values return total number each,
//For example, this could show 1 year, 14 months, 435 days, etc.
//The math below is supposed to make this say
//1 year, 2 months, 14 days, etc.
let yearsRemain = years;
let monthsRemain = months - (years *12);
let daysRemain = days - (Math.floor(months * 30));
let hoursRemain = hours - (days * 24);
let minutesRemain = minutes - (hours * 60);
let secondsRemain = seconds - (minutes * 60);
var dateArray = [
yearsRemain,
monthsRemain,
daysRemain,
hoursRemain,
minutesRemain,
secondsRemain
]
console.log(dateArray);
/*
returns [1, 1, 3, 23, 16, 46] for example
*/
the problem with this is when it comes to days. Since days in a year and days in a month vary, I was hoping moment.js would help me out. Is there a better way of doing this?
Eventually, I will be able to iterate through the array and find the two largest values to display how I'd like.
You can use moment.duration to calculate the dateArray value. Duration has years(), months(), days(), hours(), minutes(), seconds() getters.
Here a live example:
let date = '2017-03-27T12:00:00';
var dur = moment.duration( moment(date).diff(moment()) );
let yearsRemain = dur.years();
let monthsRemain = dur.months();
let daysRemain = dur.days();
let hoursRemain = dur.hours();
let minutesRemain = dur.minutes();
let secondsRemain = dur.seconds();
var dateArray = [
yearsRemain,
monthsRemain,
daysRemain,
hoursRemain,
minutesRemain,
secondsRemain
]
console.log(dateArray);
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
You can use moment-duration-format plug-in to show duration in a custom format. The plugin has a template option that lets you customize the format.
let date = '2017-03-27T12:00:00';
let dur = moment.duration( moment(date).diff(moment()) );
console.log( dur.format() );
console.log( dur.format('M [months and] d [days]') );
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/1.3.0/moment-duration-format.min.js"></script>
Note that moments has relativeTime, relativeTimeRounding and relativeTimeThreshold that lets you customize how moment shows relative time (so you can change to output).

How to convert 7:30 AM time to javascript Date type?

How can I convert time taken from form in html in the format of Hours:Minutes AM/PM to Date class object in javascript.
You could use regex to parse the time and set it to a date object.
var d = new Date(),
s ='7:30 AM',
parts = s.match(/(\d+)\:(\d+) (\w+)/),
hours = /am/i.test(parts[3]) ? parseInt(parts[1], 10) : parseInt(parts[1], 10) + 12,
minutes = parseInt(parts[2], 10);
d.setHours(hours, minutes,0,0); // As suggested by #RobG
// d.setHours(hours);
// d.setMinutes(minutes);
console.log(d);
Let's assume you have your input in the form var time = "7:30 AM".
The first thing we want to do is get the AM/PM out of the way.
time.split(' ') gives us ["7:30", "AM"], so we do:
var timePeriod = time.split(' ')[1];
time = time.split(' ')[0];
See MDN's article on .split if you have any questions
We now have timePeriod === 'AM' and time === '7:30'.
We can use the same trick to get hour and minute.
var hour = time.split(':')[0];
var minute = time.split(':')[1];
It would be easier to just use numbers, so we'll normalize our data a bit here.
if (timePeriod === 'AM') {
// Do not use `hour += 12` here as that will not convert the result to a number
hour = 12 + hour
}
And now we just have numbers to work with. Let's start with the current date:
var currentDate = new Date();
and modify the hour and minute to match the data we just parsed:
currentDate.setHours(hour);
currentDate.setMinutes(minute);
Now we should have a date that we can work with!
*See MDN's article on the Date object if you have any questions******

Categories