Get items for today and yesterday based off timestamp - javascript

I have a json object which is generated using lowdb. Each json entry has a timestamp. I wan't to get all the entry for yesterday, and today based on the timestamp.
The items variable here is just a json object. Here is a sample
{
"items": [
{
"date": 1596131220030,
"item": {
"price": "160,00",
"title": "Cotton Quarter-Zip Sweater"
}
},
{
"date": 1596232321030,
"item": {
"price": "160,00",
"title": "Cotton Quarter-Zip Sweater"
}
}
]
}
I want to get the items from yesterday, and today in this functuin
export async function report(){
try {
const items = db.get('items').value();
return items;
} catch (error) {
console.log(error);
}
}

You can compare with time values for the start of "today" and "yesterday", e.g.
// Return time value for the start of given date, default is today
function getToday(d = new Date()) {
return new Date(+d).setHours(0,0,0,0);
}
// Return time value for the start of day prior to given day, default is today
function getYesterday(d = new Date()) {
let e = new Date(getToday(d));
return e.setDate(e.getDate() - 1);
}
let data = {
"items": [
{"date": 1596085802005, // 30 Jul 2020
"item": "1"
},
{"date": 1596131220030, // 31 Jul 2020
"item": "2"
},
{"date": 1596232321030, // 1 Aug 2020
"item": "3"
}
]
}
// Run as for 1 Aug 2020
let yesterday = getYesterday(new Date(2020,7,1));
let result = data.items.filter(item => item.date >= yesterday);
console.log(result);
Results may vary based on the host timezone offset as the above uses local date values.

You need to parse the date, and compare the difference as follows:
let obj = {
"items": [
{
"date": 1596131220030,
"item": {
"price": "160,00",
"title": "Cotton Quarter-Zip Sweater"
}
},
{
"date": 1596232321030,
"item": {
"price": "160,00",
"title": "Cotton Quarter-Zip Sweater"
}
}
]
};
let list = [];
let items = obj.items;
let today = new Date();
for(let i = 0; i < items.length; i++){
var d = new Date(items[i].date);
var diff = Math.floor((d - today) / (1000 * 60 * 60 * 24));
if(diff == 0 || diff == -1)
list.push(items[i].item);
}
console.log(list);

Related

momentjs iterate over dates in a two week period and map the date to existing array

I have an array that has a object with two properties, 'location' and 'needs'. The needs property has an array of objects with a date and count {date: "2021-06-15", count: 10} so an array would look like this:
{
"location": "NYC",
"needs": [
{
"date": "2021-04-06",
"count": 56
},
{
"date": "2021-04-13",
"count": 10
}
]
}
What I need to do is to use Momentjs to use today's date, figure out the two week period starting from today, and then map the needs-count to the date in the moment loop. If there is a date missing (like in the example below), it should put a 0 as the count
A final array would look like...
{
"location": "NYC",
"needs": [
{
"date": "2021-04-06",
"count": 56 // this had a count in the initial object
},
{
"date": "2021-04-07",
"count": 0
},
{
"date": "2021-04-08",
"count": 0
},
{
"date": "2021-04-09",
"count": 0
},
{
"date": "2021-04-10",
"count": 0
},
{
"date": "2021-04-11",
"count": 0
},
{
"date": "2021-04-12",
"count": 0
},
{
"date": "2021-04-13",
"count": 10 // this had a count in the initial object
},
...
...
...
]
}
In terms of a function, the closest I have got is
let startDay = moment().format('YYYY-MM-DD');
let endDay = moment().add(14, 'days').format('YYYY-MM-DD');
let startDate = moment(startDay);
let endDate = moment(endDay);
let datesBetween = [];
let startingMoment = startDate;
while(startingMoment <= endDate) {
for (let count = 0; count < 15; count ++) {
// at this point im trying to take 'week' which has the location property and needs property and trying to merge them together... but failed miserably.
if (week.needs[count].date === startingMoment) {
datesBetween.push([startingMoment.clone(), week.needs[count].count]);// clone to add new object
startingMoment.add(1, 'days');
} else {
datesBetween.push([startingMoment.clone(), 0]);// clone to add new object
}
}
}
Can someone see where I went so wrong?
const week = {
"location": "NYC",
"needs": [
{
"date": "2021-04-06",
"count": 56
},
{
"date": "2021-04-13",
"count": 10
}
]
}
let current = moment();
const allDates = [];
const FORMAT = 'YYYY-MM-DD';
for (let count = 0; count < 14; count++) {
const found = week.needs.find(i => i.date === current.format(FORMAT));
if (found) {
allDates.push(found);
} else {
allDates.push({
date: current.format(FORMAT),
count: 0,
});
}
current.add(1, 'day');
}
week.needs = allDates;
console.log(week);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ==" crossorigin="anonymous"></script>
You could do something like this :
let dates = {
"location": "NYC",
"needs": [
{
"date": "2021-04-06",
"count": 56
},
{
"date": "2021-04-13",
"count": 10
}
]
};
let day = moment();
for( let i=0; i< 15; i++){
let date = day.add(1, "days").format("YYYY-MM-DD");
console.log(`Looking if ${date} is in array...`)
if(dates.needs.find(obj => obj.date === date)) continue;
console.log(`Adding ${date}`)
dates.needs.push({ date, count : 0 })
}
dates.needs.sort( (a,b) => a.date > b.date ? 1: -1 );
console.log(dates)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>

React compare or match two dates

I am facing an issue in React JS. I want to do compare or match the start_date with header date
Rest API
[
{
"id": "1",
"staff_name": "Jill",
"custom_service_name": "Jone",
"start_date": "2020-05-06 11:30:00",
"end_date": "2020-05-06 11:45:00",
},
{
"id": "2",
"staff_name": "james",
"custom_service_name": "smith",
"start_date": "2020-05-06 11:00:00",
"end_date": "2020-05-06 11:15:00",
}
]
console.log data:
1:00 AM //start_date
["9:43:36 AM", "9:13:36 AM", "10:13:36 AM"] //header_date
12:00 PM
["9:43:36 AM", "9:13:36 AM", "10:13:36 AM"] //header_date
2:15 AM
["9:43:36 AM", "9:13:36 AM", "10:13:36 AM"] //header_date
My Code:
var currentdate = new Date(); //header_date logic
var prevdate = new Date();
var firstdate = new Date();
prevdate.setTime(currentdate.getTime() - (30 * 60 * 1000));
firstdate.setTime(currentdate.getTime() + (30 * 60 * 1000));
var current = currentdate.toLocaleTimeString();
var previous = prevdate.toLocaleTimeString();
var first = firstdate.toLocaleTimeString();
var headerdate = [previous ,current, first];
this.state = {
headerdate:headerdate,
appointmentdata:[]
}
componentDidMount() { //get start_date
axios.get(`http://localhost/route/v1/appointment`)
.then(res => {
const appointmentdata = res.data;
console.log(appointmentdata);
this.setState({ appointmentdata });
})
}
I try , but this logic is not working
render() { return (
<div>
{this.state.appointmentdata.map(data =>
{ const dateTime = moment(data.start_date.toString());
if (dateTime.format("h:mm A") === this.state.headerdate)
{
return <p>{dateTime.format("h:mm A")}</p>; } //return the match date
else { return null; } })}
Demo:
https://codesandbox.io/s/quizzical-browser-9e3g4
What should i do?
Can anyone help me
I see you're using Moment. So you can use isSame built-in helper from them to achieve this.
Docs: https://momentjs.com/docs/#/query/is-same/
Example code:
const isSameDate = (start_date, header_date) => {
const startDate = moment(start_date);
const headerDate = moment(header_date);
return startDate.isSame(headerDate, 'day');
}
One small tip, you should move the date checking outside the render method, that would makes your code easier to read and maintainable

How to calculate the current streak (consecutive days in a row starting at the current date)?

const arr = [
{
"date": "2019-09-18"
},
{
"date": "2019-09-19"
},
{
"date": "2019-09-21"
},
{
"date": "2019-09-22"
},
{
"date": "2019-09-23"
}
]
function currentStreak(arr) {
let count = 0
arr.reverse().forEach((el, i) => {
if (new Date() - new Date(el.date) === i * 86400000) count++
})
return count
}
I'm having a hard time getting this to work. Assuming the current date is "2019-09-23", why is the above code returning 0 when it should return 3?
You are passing the current Date i.e today's date - 5th Nov Tue so the calculation done is on the basis of today's date, you must pass the value of date object
For example :-
const arr = [
{
"date": "2019-09-18"
},
{
"date": "2019-09-19"
},
{
"date": "2019-09-21"
},
{
"date": "2019-09-22"
},
{
"date": "2019-09-23"
}
]
function currentStreak(arr) {
let count = 0
arr.reverse().forEach((el, i) => {
if (new Date('2019-09-23') - new Date(el.date) === i * 86400000) count++
})
return count;
}
console.log(currentStreak(arr))
Since, new Date() gives you date + current time, hence it cannot compare correctly with the New Date(YYYY-MM-DD) which gives time at midnight hours.
If you modify your date to midnight hours, then it will compare correctly. So your code will look like.
function currentStreak(arr) {
let count = 0
arr.reverse().forEach((el, i) => {
if ((new Date().setUTCHours(0,0,0,0) - new Date(el.date).setUTCHours(0,0,0,0)) === i * 86400000) count++
})
return count
}
new Date() returns this - Tue Nov 05 2019 15:16:22 GMT+0800 (Singapore Standard Time)
So in your if condition it will not increment. Change the format of the new Date() and compare it to your array.
const arr = [
{
"date": "2019-09-18"
},
{
"date": "2019-09-19"
},
{
"date": "2019-09-21"
},
{
"date": "2019-09-22"
},
{
"date": "2019-09-23"
}
]
function currentStreak(arr) {
let count = 0
arr.reverse().forEach((el, i) => {
if ((new Date() - new Date(el.date) >= i * 86400000) && (new Date() - new Date(el.date) < (i+1) * 86400000)) count++
})
return count
}
console.log(currentStreak(arr));
It doesn't work because you didn't include minutes, hours, seconds and milliseconds.

Blank data for certain hours - hence missing in my array. Is there a way to fill in the missing hours?

I have some data by the hour and summarise/consolidate the array.
However, there are some hours which are blank in data.Items hence my array would skip the data point completely.
Is there a way where I can through my data/array and fill in the gaps and assign a '0' next to it?
for(i=0; i<dataLength; i++){
var date = new Date(data[i].ctimestamp);
date.setMinutes(0);
date.setSeconds(0);
date.setMilliseconds(0);
var date = moment(date).tz("Pacific/Auckland").format("DD/MM/YY HH:mm");
dateArray.push({"date" : date});
}
Here is an example - "11/12/18 05:00" and "11/12/18 06:00" are missing so it's skipped completely.
[{
"date": "11/12/18 08:00",
"count": 5
},
{
"date": "11/12/18 07:00",
"count": 4
},
{
"date": "11/12/18 04:00",
"count": 6
}]
Ideally, I would like it to show:
[
{
"date": "11/12/18 08:00",
"count": 5
},
{
"date": "11/12/18 07:00",
"count": 4
},
{
"date": "11/12/18 06:00",
"count": 0
},
{
"date": "11/12/18 05:00",
"count": 0
},
{
"date": "11/12/18 04:00",
"count": 6
}]
I think this simplifies the logic and produces the result you want:
const data = [
{
"date": "11/12/18 08:00",
"count": 5
},
{
"date": "11/12/18 07:00",
"count": 4
},
{
"date": "11/12/18 04:00",
"count": 6
}
];
let min = Number.MAX_VALUE;
let max = 0;
const dates = data.reduce((memo, {date, count}) => {
const time = new Date(date).getTime();
min = Math.min(min, time);
max = Math.max(max, time);
memo[time] = count;
return memo;
}, {});
const ONE_HOUR = 60 * 60 * 1000;
const dataOutput = [];
for (let i = min;i <= max;i += ONE_HOUR) {
dataOutput.push({
date: new Date(i).toLocaleString(),
count: dates[i] || 0
});
}
console.log(dataOutput)
I'll assume the array you posted as sample data, is called dataItems. Also, I'll use moment to handle time, but you can convert it to vanilla JS if you want.
So, what I would do is go through dataItems, and check if prev value is 1 hour prev to this value, if its not, add a new input.
dataItems.reduce((acc, val) => {
if(!acc) {
return [moment(val)];
}
let momentVal = moment(val)
if (momentVal.diff(acc[acc.length - 1], 'hours') !== 1){
acc.push(momentVal)
return acc;
} else {
while(momentVal.diff(acc[acc.length - 1], 'hours') !== 1){
acc.push(moment(acc[acc.length - 1]).add(1, 'hours')) //clone and add 1 hour
}
}
}])
I didn't take in consideration your object isn't just date, but that should be simple to adapt. The general logic is: go through your array, if the previous one is 1 hour less than right now, keep it going. Else, add a new input until the actual one is 1 hour after the last one on the array

Number of features by day javascript

I have a json document that looks like this:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"time": 1438342780,
"title": "Iran's foreign minister calls for world's nuclear weapons states to disarm",
"author": "Julian Borger",
"web_id": "world/2015/jul/31/iran-nuclear-weapons-states-disarm-israel"
},
"geometry": {
"type": "Point",
"coordinates": [
-77.26526,
38.90122
]
}
},
{
"type": "Feature",
"properties": {
"time": 1438300867,
"title": "Big bangs over the white cliffs of Dover as unique 1915 artillery gun is fired again",
"author": "Maev Kennedy",
"web_id": "world/2015/jul/31/big-bangs-over-white-cliffs-dover-unique-1915-artillery-gun-fired-again"
},
"geometry": {
"type": "Point",
"coordinates": [
1.3,
51.13333
]
}
}
]
}
I would like to fetch the 'feature' array inside json and return the number of features for a given day. For example, for the data above I would expect something like:
{
"date": 7/31/2015,
"number": 2
}
Currently I have something that looks like this:
d3.json('path/to/json', function(json) {
data = json;
});
Fairly new to js and d3 so a bit stumped. Let me know if you need any more details. Thanks in advance!
This will work for you, it returns an array of object. each object is the object you asked.
var a = yourJSONObject, var map = {}, output = [];
for (var i = 0; i < a.features.length; i++) {
var ref = new Date(a.features[i].properties.time*1000).toDateString();
if (map[ref] == undefined) {
map[ref] = output.push({
date: ref,
number: 1
}) - 1;
} else
output[map[ref]].number++
}
console.log(output) //[ { date: 'Sat Jan 17 1970', number: 2 } ]
The critical piece here is that your time values are in Epoch time, which means you'll have to convert them to preset dates using this technique.
Then you can traverse the features array, and track the count for each date.
var features = yourJSONObject.features;
var featuresByDate = {};
for (var i = 0, len = features.length; i < len; i++) {
// find the current feature's date
var epochTime = features[0].properties.time;
var date = new Date(0);
date.setUTCSeconds(epochTime);
// find the date in 7/31/2015 format
var dateStr = (date.getMonth() + 1) + '/' + date.getDate() + '/' + date.getFullYear();
// count the date for the first time if it has not been counted yet
if ( ! featuresByDate.hasOwnProperty(dateStr) ) {
featuresByDate[dateStr] = 1;
}
// otherwise, increment its counter
else {
featuresByDate[dateStr]++;
}
}
Two functions - one to get the correct date based on the epoch time, the other to iterate through the features building a temporary object, then iterating through the object to give you an array of date/number objects.
function getDate(time) {
var d = new Date(0);
d.setUTCSeconds(time);
return [d.getMonth() + 1, d.getDate(), d.getFullYear()].join('/');
}
function getData(data) {
var obj = data.features.reduce(function(p, c) {
var date = getDate(c.properties.time);
p[date] = (p[date] + 1) || 1;
return p;
}, {});
return Object.keys(obj).map(function (el) {
return { date: el, number: obj[el] };
});
}
getData(data);
OUTPUT
[
{
"date": "7/31/2015",
"number": 2
}
]
DEMO
I don't know D3, but you can do this with straight JS:
var json = {
"features": [{
"type": "Feature",
"properties": {
"time": 1438342780,
"title": "Iran's foreign minister calls for world's nuclear weapons states to disarm"
}
}, {
"type": "Feature",
"properties": {
"time": 1438300867,
"title": "Big bangs over the white cliffs of Dover as unique 1915 artillery gun is fired again"
}
}, {
"type": "Feature same date",
"properties": {
"time": 1448300867,
"title": "Big bangs over the white cliffs of Dover as unique 1915 artillery gun is fired again"
}
}]
}
var counts = {}
function secondsToDate(seconds) {
var date = new Date(1970,0,1);
date.setSeconds(seconds);
return date.toDateString();
}
json.features.reduce((counts, feature) => {
var date = secondsToDate(feature.properties.time)
if (counts[date]) {
counts[date]++
} else {
counts[date] = 1
}
return counts
}, counts)
console.log(counts) // {'Fri Jul 31 2015': 2, 'Mon Nov 23 2015': 1}
The missing bit is parsing your timestamp into a date.
Now grouping on dates. Maybe now the downvoter can undo that!
I added an object with a replicated timestamp to highlight the count going up.

Categories