There is an object array like this:
[
{
timestamp: 1318781876
any: 'other fields'
}
]
Of course there are multiple objects in that array. I am using momentJS - if it matters here...
Now I need to split that array into months. That means I need to get all objects for 'july' to display them in a table.
Is this possible at all or should I change the datastructure? I thought using timestamp is the best option, as I could calculate everything from this.
But now I'm thinking if I have to add month and year field to the object...
You could iterate the array and build up a tree, may also write year and month to the objects:
var map={};
array.forEach(function(obj){
var d = new Date(obj.timestamp*1000);
var m = obj.month = d.getMonth() +1;
var y = obj.year = d.getFullYear();
if(!map[y]) map[y]={};
if(!map[y][m]) map[y][m]=[];
map[y][m].push(obj);
});
So now weve got a map like this:
map: {
2017 : {
8 : [
{
timestamp:123456,
month:8,
year:2017,
any:"other value"
}
]
}
}
So you can now get all julys by:
map[2017][7]
It depends if you just do this once, then other answers will be easier, but if you need different timeranges the upper code just needs to iterate once, and you can get the filtered results easily. To get sorted results:
var sorted=Object.keys(map)/*the years*/ .sort().map(function(year){
return { year, months: Object.keys(map[year]).sort().map(function(month){
return {month,results:map[year][month]};
})
};
});
These arrays may already be built up while building the hash table, see ninas way of doing this
This can be done using array.filter
myArr = [
{
timestamp: 1318781876
any: 'other fields'
}
...
];
var filteredArray = myArr.filter(function(item) {
return (item.timestamp > minOfDateRange && item.timestamp < maxOfDateRange);
});
Your structure is quite useful. You can use Array.filter:
const startDate = new Date(2017, 6, 1); // 6 for July
const endDate = new Date(2017, 7, 1);
const selectedData = data.filter(entry => startDate <= entry.timestamp * 1000 && entry.timestamp * 1000 < endDate)
Convert the milisecond to a date using following code and get the month afterward
var date = new Date(milliseconds);
var month = date.getMonth();
then put the july object to another array and display them as you wish
You can use a hashmap approach.
var arr = [
...
{
timestamp: 1318781876
any: 'other fields'
}
...
];
var grouped = {};
var months = ['Jan', 'Feb' ...];
arr.forEach( function(item){
var dateObj = moment.unix(item.timestamp);
var month = months[dateObj.month()];
if(!grouped[month]){
grouped[month] = [];
}
grouped[month].push(item);
});
console.log(grouped);
Related
I'm trying to find week days between first date and second date (exclusive first and second). In the array that contains the weekday dates, the values get increment after line 1 in executed, which is unexpected.
private getListOfWeekDaysBetweenTwoDates(
startDate: Date,
endDate: Date
): Date[] {
const weekdaysList = [];
let tempDate = this.addDaystoGivenDate(startDate, 1);
while (tempDate < endDate) {
if (this.isWeekDay(tempDate)) {
weekdaysList.push(tempDate);
}
//line 1
tempDate = this.addDaystoGivenDate(tempDate, 1);
}
return weekdaysList;
}
private addDaystoGivenDate(date: Date, numberOfDays: number): Date {
return new Date(date.setUTCDate(date.getUTCDate() + numberOfDays));
}
private isWeekDay(day: Date): boolean {
if (day.getUTCDay() >= 1 && day.getUTCDay() <= 5) {
return true;
}
return false;
}
How do I stop array values changing?
Isolating the problem, you're changing the date after inserting it to the array, but what you're inserting is a reference to the date:
let d = new Date()
d.setUTCDate(1)
const arr = []
arr.push(d)
console.log(arr)
d.setUTCDate(10)
console.log(arr) //date in arr changes from 1 to 10
That's because you're calling date.setUTCDate() over tempDate.
There is more than one way to solve it, but for example you could store not the reference to tempDate but a completely new Date object:
weekdaysList.push(tempDate); => weekdaysList.push(new Date(tempDate));
In the simplified example:
let d = new Date()
const arr = []
d.setUTCDate(1)
arr.push(new Date(d))
console.log(arr)
d.setUTCDate(10)
console.log(arr) //date in arr keeps 1
I have an array of objects. Each object has a date property. I am trying to create a function where I append every item to a new array if the item's date is equal to today's date.
Also, I am not sure if the for loop is the most efficient approach for this, this list will never be more than a few hundred items though.
My function:
todayListItems() {
const todayItems = [];
const todayDate = moment(new Date()).format('dd-mm-YYYY');
for (let i = 0; i < myArray.length; i++) {
const itemDate = moment(myArray[i].date).format('dd-mm-YYYY');
if (itemDate === todayDate) {
todayItems.push(myArray[i]);
}
}
console.log(todayItems);
return todayItems;
}
This function runs but even if there is an item with today's date nothing will be pushed to the array.
You can use Array.filter() and moment#isSame with the second parameter to limit the granularity to a unit other than milliseconds:
function todayListItems(arr) {
return arr.filter(obj => moment().isSame(obj.date, 'day'));
}
todayListItems(myArray);
Demo:
function todayListItems(arr) {
return arr.filter(obj => moment().isSame(obj.date, 'day'));
}
const myArray = [
{ date: '2019-10-14T12:10:00Z'},
{ date: new Date() },
{ date: moment().minutes(120).format('YYYY-MM-DDTHH:mm:ss') },
{ date: new Date('2019-10-23T01:00:00') },
];
console.log(todayListItems(myArray));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
You're formatting wrongly. mm is minutes. The formatting should be DD-MM-YYYY, see https://momentjs.com/docs/#/displaying/format/
In my application I have a mysql table where I have maintained the history of price alteration. I mapped the dates out of the history table and it looks like this:
['09-16-2019','09-25-2019','10-10-2019',...n]
Using this history, I want to create an array of date ranges so that I can easily figure out which client in my application registered between what date range. The format I want looks like :
let ranges = [
{start:'09-16-2019',end:'09-24-2019'},
{start:'09-25-2019',end:'10-09-2019'}
.,
.,
..n
]
You can use a simple Array.prototype.reduce() to create an object from the given dates array, like so:
let dates = ['09-16-2019', '09-25-2019', '10-10-2019', '18-10-2019'];
let ranges = dates.reduce((acc, val, i, arr) => {
if (i !== 0) acc.push({
start: arr[i - 1],
end: val
});
return acc;
}, []);
console.log(ranges);
Assuming from your example, what you have is list of start dates, you can iterate and figure out end date.
let x = ['09-16-2019','09-25-2019','10-10-2019']
let res = [];
for(let i = 0; i < x.length - 1; i++) {
let start = x[i];
let end = new Date(Date.parse(x[i+1]) - 86400000).toLocaleDateString("en",{year:"numeric",month:"numeric",day:"numeric"});
res.push({start, end})
}
console.log(res);
// [ { start: '09-16-2019', end: '9/24/2019' },
// { start: '09-25-2019', end: '10/9/2019' } ]
I have array with this timestamps,
var labels = ["2018-12-01T00:00:00.000Z",
"2018-12-02T00:00:00.000Z",
"2018-12-09T00:00:00.000Z",
"2018-12-09T00:00:00.000Z",
"2018-12-18T00:00:00.000Z"
]
what is the best way to have array in format 2018-12-01. I need to have date for graph
You should use Array.prototype.map(), and create a new array with the characters you don't want sliced off the end:
var labels = ["2018-12-01T00:00:00.000Z",
"2018-12-02T00:00:00.000Z",
"2018-12-09T00:00:00.000Z",
"2018-12-09T00:00:00.000Z",
"2018-12-18T00:00:00.000Z"
];
var truncated = labels.map(str => str.slice(0, -14));
console.log(truncated);
Have you considered using moment?
function updateTimeFormat(arr) {
return arr.map(x => {
return moment(x).format('YYYY-MM-DD');
});
}
You can use the built-in Date, as so:
labels.map(label => {
const date = new Date(label);
return `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;
}
you can achieve what you want by using Array.prototype.map
var labels = ["2018-12-01T00:00:00.000Z",
"2018-12-02T00:00:00.000Z",
"2018-12-09T00:00:00.000Z",
"2018-12-09T00:00:00.000Z",
"2018-12-18T00:00:00.000Z"
];
const newDates = labels.map( label => {
const newd = new Date(label);
const fullYear = newd.getFullYear();
const month = (newd.getMonth() + 1 ).toString();
const date = (newd.getDate()).toString();
return `${fullYear}-${month.length > 1 ? month : month.replace(/^/,0)}-${date.length > 1 ? date : date.replace(/^/,0)}`;
});
console.log(newDates);
I have array with a few hundred events where every has date entry (in Date().getTime format in DB) and I have 10 days displayed in simple table. To every day-row I need to display number of events in that particular day. What would be the best way to do that?
Okay here is an update:
I've Firebase db with this structure:
{
events: {
event1: {
date: 144335265211,
title: "sometext",
text: "longer text"
},
event2: {
date: 1444482619766,
title: "sometext",
text: "longer text"
}
}
}
I am pulling it into local Redux store so I have an JS array with the same structure.
This way I am creating the table for particular days:
for (let dc = 0; dc < 10; dc++) {
const date = new Date();
date.setDate(date.getDate() + dc);
const m = date.getMonth();
const d = date.getDay();
const y = date.getUTCFullYear();
rows.push(
<td>"On the " + m + "/" + d + "/" + y + " is SOMENUMBER events"</td>
);
return rows;
}
Thanks a lot!
First you need to convert it to an array:
var events = Object.keys(obj).map((key) => {
return Object.assign({}, obj[key], {eventName: key});
});
Then you need to group them by date. We can do this with lodash.
var groupBy = require('lodash/collection/groupBy');
var eventsWithDay = events.map((event) => {
return Object.assign({}, event, {day: new Date(event.date).setHours(0, 0, 0, 0))
});
var byDay = groupBy(eventsWithDay, 'day');
And byDay will be an object with a key for each date with a value of an array of events for that day.