Parse Date from Array - JS - javascript

I have an array with a date. When I parse it, the month increases by 1. How can I fix it?
var data = [{
name: 'Arun',
date: [2019, 4, 9, 14, 55, 28, 897778]
}, {
name: 'Manohar',
date: [2019, 4, 3, 22, 43, 54, 894553]
}]
data.forEach((item) => {
item.date.pop()
item.date = new Date(...item.date).toLocaleString('en-US')
});
console.log(data)
I want the month as April and not May. Please advice.

As per the documentation suggests, the monthIndex would start at 0, rather than 1. So you need to manually subtract 1.
data.forEach((item) => {
item.date.pop()
item.date[1]--
item.date = new Date(...item.date).toLocaleString('en-US')
});

The month is represented by a value from 0 to 11, 4 is the fifth month, it corresponds to May, you just need to decrease it by 1.

Related

How can I convert my date and time into an acceptable format for React Big Calendar

I am taking date, start time and end time of an event from the database, all of which are stored as strings in these format: eventDate: "2022-02-21", startTime: "20:30", endTime: "22:30" respectively. I need to pass 2022-02-21 8:30 PM as the start time and 2022-02-21 10:30 PM as the end time. From the docs that I read, I believe I have to have them in the array list of event objects as:
new Date(2022, 2, 21, 20, 30, 0) and new Date(2022, 2, 21, 22, 30, 0). These values are dynamic, so I won't manually be able to change them. What are some ways I can manipulate the values of date, startTime and endTime to be able to pass it to the calendar?
const s = new Date(2022, 2, 21, 20, 30, 0), e = new Date(2022, 2, 21, 22, 30, 0)
const eventDate = `${s.getFullYear()}-${s.getMonth().toString().padStart(2, `0`)}-${s.getDate().toString().padStart(2, `0`)}`
const startTime = `${s.getHours().toString().padStart(2, `0`)}:${s.getMinutes().toString().padStart(2, `0`)}`
const endTime = `${e.getHours().toString().padStart(2, `0`)}:${e.getMinutes().toString().padStart(2, `0`)}`
console.log(`eventDate:`, eventDate, `startTime:`, startTime, `endTime:`, endTime)

Is there a easy way to get week number array by month and year?

I try to get week numbers of year in specific month and year with javascript.
function getWeekNumbers(month, year) {
var first, last, weeks = [];
if (month < 10)
month = "0" + month;
var date = "01." + month + "." + year;
first = moment(date, 'dd.MM.yyyy').startOf('month').week();
last = moment(date, 'dd.MM.yyyy').endOf('month').week();
for (i = first; i < last; i++) {
weeks.push(i);
}
return weeks;
}
var result = getWeekNumbers(3, 2021);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ==" crossorigin="anonymous"></script>
I need the result like; [9,10,11,12,13]
But the code is not work properly.
It will also cause problems in the 12th month.
Your solution is very close, I made some small tweaks to my own liking but you can change that back if you want.
First of all, I recommend using isoWeek instead of week, isoWeek conforms to week numbering according to ISO 8601 (https://momentjs.com/docs/#/get-set/iso-week/).
Your other error lies in not including last as part of the for loop, in this case you want to include it unlike normally where you just loop to the end of a list. Thus <= is what you need in the for-loop.
function getWeekNumbers(month,year) {
var first, last, weeks=[];
first = moment().month(month - 1).year(year).startOf('month').isoWeek();
last = moment().month(month - 1).year(year).endOf('month').isoWeek();
for(var i = first; i <= last; i++){
weeks.push(i);
}
return weeks;
}
Would this satisfy what you're looking for? I used some array chunking and date functions to break the dates of any given month into their respective weeks:
const getWeeks = (month, year) => Array(new Date(year, month, 0).getDate()).fill(0).map((_,i) => new Date(year, month-1, i+1)).map((d,i,a) => !i && d.getDay() ? [Array(d.getDay()).fill(null), d.getDate()] : d.getDate() === a.length && d.getDay() < 6 ? [d.getDate(), Array(6-d.getDay()).fill(null)] : d.getDate()).flat(2).map((d,i,a) => a.length ? a.splice(0,7) : null).filter(w => w);
// February 2021
getWeeks(2, 2021); // -> returns array below ↓↓↓
[
[null, 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12, 13],
[ 14, 15, 16, 17, 18, 19, 20],
[ 21, 22, 23, 24, 25, 26, 27],
[ 28, null, null, null, null, null, null]
]
If you'd prefer not have the null placeholders, but just have shorter arrays when a week has fewer days, we can achieve this using an additional filter. We can even include an optional parameter for this value, that when left empty (or set to undefined) will yield the trimmed arrays:
const getWeeks = (month, year, nullVal) => Array(new Date(year, month, 0).getDate()).fill(0).map((_,i) => new Date(year, month-1, i+1)).map((d,i,a) => !i && d.getDay() ? [Array(d.getDay()).fill(nullVal), d.getDate()] : d.getDate() === a.length && d.getDay() < 6 ? [d.getDate(), Array(6-d.getDay()).fill(nullVal)] : d.getDate()).flat(2).map((d,i,a) => a.length ? a.splice(0,7) : null).filter(w => w).map(w => nullVal !== undefined ? w : w.filter(d => d));
// December 2021
getWeeks(12, 2021); // -> bullish value blank :: trimming weeks, returns array below ↓↓↓
[
[ 1, 2, 3, 4],
[ 5, 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17, 18],
[19, 20, 21, 22, 23, 24, 25],
[26, 27, 28, 29, 30, 31 ]
]
getWeeks(12, 2021, 0); // -> using 0 as nullish value, returns array below ↓↓↓
[
[ 0, 0, 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17, 18],
[19, 20, 21, 22, 23, 24, 25],
[26, 27, 28, 29, 30, 31, 0]
]
You can also use this function to get the number of weeks in a month or the dates in a particular week by the week's index value:
// Get number of weeks in month
getWeeks(12, 2021).length // -> 5
// Get dates in a week by index value
getWeeks(5, 2021)[2] // -> [9, 10, 11, 12, 13, 14, 15]

Combine objects of an array with the same date into one - JavaScript

I receive an array of posts through an API and want to merge the ones with the same "month" and "year" (day is not important), into one object. I looked up for answers but there are just too many foo-bar examples that confuses more than helping. I want to know the cleanest, most elegant way of handling such problems, without getting into call-back hell and nested blocks...
Here is the API response:
0:
{
date: {day: 27, month: 1, year: 2020}
id: 3
}
1:
{
date: {day: 28, month: 1, year: 2020}
id: 4
}
2:
{
date: {day: 31, month: 1, year: 2020}
id: 5
}
3:
{
date: {day: 1, month: 2, year: 2020}
id: 6
}
4:
{
date: {day: 2, month: 2, year: 2020}
id: 7
}
The expected outcome:
0:
result: {month: 1, year: 2020, id:[3,4,5]}
1:
result: {month: 2, year: 2020, id:[6,7]}
One approach would be to use the Array#reduce() method to transform the input array into a dictionary, where each value contains the accumulation of id's for that month and year. Once this dictionary has been built, you could then extract the values of that dictionary to an array via Object#values() to obtain the required output:
let input=[{date:{day:27,month:1,year:2020},id:3},{date:{day:28,month:1,year:2020},id:4},{date:{day:31,month:1,year:2020},id:5},{date:{day:1,month:2,year:2020},id:6},{date:{day:2,month:2,year:2020},id:7}];
/* Convert the dictionary that will be created by reduce to a value array */
var output = Object.values(input.reduce((dict, item) => {
const { date, id } = item;
/* The distinct key for this item based on month/year of date field */
const key = `${date.month}-${date.year}`;
/* Check if dictionary already has an object value for key. This short hand
will only insert a new object value for key, if one does not already exist
in the dictionary */
const value = dict[key] || { month : date.month, year : date.year, id : [] };
/* Add the item id to the dictionary entries id array */
value.id.push(id);
/* Update value object for key */
return { ...dict, [key] : value };
}, {}))
console.log(output);
The idea here is that the dictionary is built using Compound Keys, where the keys are derived from the month and year of the current array item.
When no value exists for the current key, a new value object is inserted to the dictionary for that key:
{ month : date.month, year : date.year, id : [] }
The id of the current array item is then added (accumulated) to the id sub array of the object for that key:
dict[key].id.push(id);
Hope that helps
Here is an alternate approach, if you are not a big fan of Array.reduce and Array.values and also, if you like to consider performance when running the response for a larger data set.
This approach avoids cloning object (or rather non-mutating object) with spread operator i.e {...<anyObject>} while iterating. which should be fine for minimal set of data but but definitely not when you deal with huge volume.
const response = [{
date: { day: 27, month: 1, year: 2020 },
id: 3
}, {
date: { day: 28, month: 1, year: 2020 },
id: 4
}, {
date: { day: 31, month: 1, year: 2020 },
id: 5
},{
date: { day: 1, month: 2, year: 2020 },
id: 6
},{
date: { day: 2, month: 2, year: 2020 },
id: 7
}];
function groupByMonthYear(response) {
// output
const groupedData = []
// Using map for lookup to avoid iterating again on the grouped data
const referenceMap = new Map();
// destructing month, year and id from the response
for (const { date: { month, year }, id } of response) {
const groupKey = `${month}${year}`
// check if the month and year reference is already seen using the groupKey MMYYYY
if (referenceMap.has(groupKey)) {
referenceMap.get(groupKey).id.push(id);
// early return
continue;
}
// simply add a new entry if it doesn't exist
const data = {
month,
year,
id: [id]
};
groupedData.push(data);
referenceMap.set(groupKey, data)
}
return groupedData;
}
// Invoke and Print the result
console.log(groupByMonthYear(response));

How to show month max and min in D3

I am new to D3 and need to design a heatmap using D3. I had the data for 20 years and required to show the max and min for every month. The question is different month has different days and for February there is 28 days or 29 days. Can anybody help me?
Sorry for my unclear description.This is the part of the data.enter image description here I need to use the max and min value of each month to draw a heatmap. The data is from 1997-01-01 to 2007-12-31.
You can sort this out using underscorejs and d3.extent.
For Example your list is like,
data = [{
month: 1,
value: 10
}, {
month: 1,
value: 20
}, {
month: 2,
value: 30
}, {
month: 2,
value: 40
}];
You underscore groupBy method like,
result = _.groupBy(data, 'month');
Your result will be,
result = {
1: [{
month: 1,
value: 10
}, {
month: 1,
value: 20
}],
2: [{
month: 2,
value: 30
}, {
month: 2,
value: 40
}]
};
Then you can plot max and min values using d3.extent.

Find the average of each index in 2+ arrays to return a new array of averages

For this problem, what is the most ideal solution in JavaScript to take a bunch of arrays all with the same number of indexes which all have integer values and then return one array with the average of each index from each array.
Here is an example of what I mean:
var data = [[ 12, 14, 13, 10 ], [ 11, 13, 12, 2 ], [ 18, 12, 3, 4 ]];
to return one single array with all the averages calculated like so:
[13.6, 13, 9.3, 5.3 ];
data=data.map(arr=>arr.reduce((old,new)=>old+new,0)/arr.length);
I dont give an explanation, i give the OP the ability to find out alone + learn it that way...
You have to use map function in order to calculate average for every item from array.I'm using reduce function in order to calculate the sum for every item.
Here is solution:
var data = [[ 12, 14, 13, 10 ], [ 11, 13, 12, 2 ], [ 18, 12, 3, 4 ]];
console.log(data.map(function(item){
return item.reduce( ( prev, current ) => prev + current , 0 ) / item.length;
}));

Categories