How to filter JSON data from API by date range in JavaScript - javascript

I want to filter the below JSON data by start date and end date, it should return the data between start date and end date, I tried to achieve using below code, but I'm doing wrong something to filter. I'm new to front end technologies like JavaScript. It would be appreciated if someone can correct me what I'm doing wrong here:
The API data is like that seen below
{
"rec_id": 1,
"emp_id": 1,
"date": "Jan 22, 2020",
"time_in": "09:20",
"time_out": "19:56",
"total_hours": 10.6,
"weekday": 4,
"name": "Carlina Dahlberg",
"gender": "Female",
"designation": "Supervisor",
"department": "Production",
"calculate": "",
"basic_salary": 20000,
"per_day_salary": 1000
},
{
"rec_id": 2,
"emp_id": 2,
"date": "Jan 22, 2020",
"time_in": "08:33",
"time_out": "13:16",
"total_hours": 4.72,
"weekday": 4,
"name": "Brenden Greenacre",
"gender": "Male",
"designation": "Executive",
"department": "Marketing",
"calculate": "",
"basic_salary": 25000,
"per_day_salary": 1250
},
This is my code file
async function getData(){
let myData = await fetch("http://34.198.81.140/attendance.json")
.then((respose) => {
return respose.json()
})
.then((data) => {
return data;
});
let startDate ="Feb 1, 2020";
let endDate = "Feb 29, 2020";
let result = myData.filter((data) => {
return data.date >= startDate && data.date <=endDate;
})
console.log(result);
}
getData()
The data get filtered but not as per requirement, please see the screen shot of console output. In the screen shot the Data come from 1 feb to 29 Feb but, the Data from 2 Feb to 9 Feb whole data is skip by filter function.

You can use Urnary (+) operator, with new Date() to create a timestamp, and then you can compare the timestamps to get desired result.
async function getData() {
/*
let myData = await fetch("http://34.198.81.140/attendance.json")
.then((respose) => {
return respose.json()
})
.then((data) => {
return data;
});*/
// For Testing Purposes only (data modified)
let myData = [{
"rec_id": 1,
"emp_id": 1,
"date": "Jan 22, 2020",
"time_in": "09:20",
"time_out": "19:56",
"total_hours": 10.6,
"weekday": 4,
"name": "Carlina Dahlberg",
"gender": "Female",
"designation": "Supervisor",
"department": "Production",
"calculate": "",
"basic_salary": 20000,
"per_day_salary": 1000
},
{
"rec_id": 2,
"emp_id": 2,
"date": "Feb 5, 2020",
"time_in": "08:33",
"time_out": "13:16",
"total_hours": 4.72,
"weekday": 4,
"name": "Brenden Greenacre",
"gender": "Male",
"designation": "Executive",
"department": "Marketing",
"calculate": "",
"basic_salary": 25000,
"per_day_salary": 1250
}
]
let startDate = +new Date("Feb 1, 2020");
let endDate = +new Date("Feb 29, 2020");
let result = myData.filter((data) => {
return +new Date(data.date) >= startDate && +new Date(data.date) <= endDate;
})
console.log(result);
}
getData()

You need to parse the date into something you can compare dates with.
There are a few options in front of you for that.
Rely on Date.Parse(), a bad idea ref. (mdn)
Use an alternative date library. A simple google search should reveal some.
After parsing the date, you can use the same logic that you are currently using.

you can do it through converting the strings of number into numbers. afterwards try comparing them with each other.
You can use JS libraries such as Moment.js or Dayjs as well to get around it.look through their APIs to dispel the snag you got stuck.

You can use the code below, if you decide to use async/await:
async function getData() {
const response = await fetch('http://34.198.81.140/attendance.json')
const myData = await response.json()
let startDate = 'Feb 1, 2020'
let endDate = 'Feb 29, 2020'
let result = myData.filter(data => {
return (
// Convert all date values to javascript dates using new Date(value)
// Get the number of milliseconds using getTime()
// Compare the milliseconds values
new Date(data.date).getTime() >= new Date(startDate).getTime() &&
new Date(data.date).getTime() <= new Date(endDate).getTime()
)
})
console.log(result)
}
getData()

Related

Remove " " from keys when PHP associative array in parsed through json_encode

I am trying to supply some data to a Javascript Function but right now i am unable to convert it to desired format.
The Correct Format that is Working is below.
const eventsArr = [
{
day: 1,
month: 1,
year: 2023,
events: [
{
title: "asdEvent 1 lorem ipsun dolar sit genfa tersd dsad ",
time: "10:00 AM",
}
],
},
{
day: 13,
month: 11,
year: 2022,
events: [
{
title: "Event 2",
time: "11:00 AM",
},
],
},
];
The format is am being able to produce is the following.
const eventsArr = [
{
"day": "18",
"month": "2",
"year": "2023",
"events": [
{
"title": "Feb 18th Event and Updated From Databae",
"time": "05:10"
}
]
}
The Only difference between two javascript objects/arrays is that my version has "" around the keys and the working format does not have "" around the keys.
My Server Side PHP Code where i am using json_encode
$events = [];
foreach($db_data['CalendarEvent'] as $event)
{
$single_event = array(
'day'=>$event->ce_day,
'month'=>$event->ce_month,
'year'=>$event->ce_year,
'events'=>array(
array(
'title'=> $event->ce_title,
'time'=> $event->ce_time_from,
)
)
);
$events[] = $single_event;
}
$db_data['all_events'] = json_encode($events , JSON_PRETTY_PRINT);
Can somebody help me in this? How can i produce the required format (without "" around the keys in javascript). What i am doing wrong?
Thanks in Advance

Change Year-month to Month(letter)-year format in JavaScript

I have a dataset with date format as
var dataset = [{
"monthDate": "2018-05",
"count": 83
},
{
"monthDate": "2018-06",
"count": 23
},.....]
I wish to change this to 'May-18', 'June-18' and so on and pass this data to Highchart Categories. How do I do that?
You could parse the date into a Date object, and then format it with toLocaleDateString. One adjustment is needed at the end, to get the hyphen in the output:
var dataset = [{ "monthDate": "2018-05", "count": 83 }, { "monthDate": "2018-06", "count": 23 }];
var result = dataset.map(o => ({
monthDate: new Date(parseInt(o.monthDate), o.monthDate.slice(-2) - 1)
.toLocaleDateString("en", {month: "long", year: "2-digit"})
.replace(" ", "-"),
count: o.count
}));
console.log(result);

How to compare date in JSON data using jmespath?

I have one JSON data, which contains date like jan 23,2018.
How can I compare JSON data date with the current date?
[
{
"id": "user_1",
"date": "jan 23, 2019"
},
{
"id": "user_2",
"date": "mar 3, 2017"
},
{
"id": "user_3",
"date": "feb 23, 2019"
}
]
How can I get data which has the date is more than current date using jmespath?
const array = [
{
"id": "user_1",
"date": "jan 23, 2019"
},
{
"id": "user_2",
"date": "mar 3, 2017"
},
{
"id": "user_3",
"date": "feb 23, 2019"
}
];
const newArray = array.map((value) => {
value.date = new Date(value.date).getTime();
return value;
});
console.log(newArray);
console.log('current time in milliseconds ', new Date().getTime());
/* array.forEach((value) => {
const date = new Date(value.date);
console.log(date);
}); */
// console.log('current date', new Date());
Loop array and pass date string to new Date() to get date object and then you can compare it to current date.
EDIT: Now you can directly use milisecond to compare the dates.
You can use JMESPath Custom functions to achieve that. You'll need to convert your date to epoch in order to compare the dates because JMESPath doesn't understand date object.
You can refer an example here under Custom function section: https://pypi.org/project/jmespath/
I created my own custom function to check whether a past date has surpassed current time by atleast certain amount of seconds. Here's my code:
from jmespath import functions
import time
class CustomFunctions(functions.Functions):
# the function name should always have a prefix of _func_ for it to be considered
#functions.signature({'types': ['string']}, {'types': ['number']})
def _func_hasTimeThresholdCrossed(self, jobdate, difference):
jobdate = time.strptime(jobdate,'%Y-%m-%dT%H:%M:%S.%fZ')
return time.time() - time.mktime(jobdate) > difference
options = jmespath.Options(custom_functions=CustomFunctions())
jmespath.search("hasTimeThresholdCrossed(createdAt,`1000000`)",{"createdAt":"2019-03-22T10:49:17.342Z"},options=options)

Sorting array of object javascript / typescript on firestore timestamp

I have below array structure
[
{
"id": "8gFUT6neK2I91HIVkFfy",
"element": {
"id": "8gFUT6neK2I91HIVkFfy",
"archived": false,
"updatedOn": {
"seconds": 1538653447,
"nanoseconds": 836000000
}
},
"groupBy": "pr"
},
{
"id": "9jHfOD8ZIAOX4fE1KUQc",
"element": {
"id": "9jHfOD8ZIAOX4fE1KUQc",
"archiveDate": {
"seconds": 1539250407,
"nanoseconds": 62000000
},
"archived": false,
"updatedOn": {
"seconds": 1538655984,
"nanoseconds": 878000000
}
},
"groupBy": "pr"
},
{
"id": "CeNP27551idLysSJOd5H",
"element": {
"id": "CeNP27551idLysSJOd5H",
"archiveDate": {
"seconds": 1539248724,
"nanoseconds": 714000000
},
"archived": false,
"updatedOn": {
"seconds": 1538651075,
"nanoseconds": 235000000
}
},
"groupBy": "pr"
},
{
"id": "Epd2PVKyUeAmrzBT3ZHT",
"element": {
"id": "Epd2PVKyUeAmrzBT3ZHT",
"archiveDate": {
"seconds": 1539248726,
"nanoseconds": 226000000
},
"archived": false,
"updatedOn": {
"seconds": 1538740476,
"nanoseconds": 979000000
}
},
"groupBy": "pr"
}
]
and below code to sort
Sample JSfiddle
http://jsfiddle.net/68wvebpz/
let sortedData = this.arraydata.sort((a:any, b:any) => { return Number(new Date(b.element.date).getTime()) - Number(new Date(a.element.date).getTime()) })
This does not make any effect.
There are a few problems that we need to fix:
Your updatedOn object is not something that can be converted to a date. You need to do extra work.
JavaScript doesn't support nanoseconds, only milliseconds. You will therefore need to divide that number by a million.
By using getTime for the comparison, you're actually discarding the milliseconds - that function returns seconds.
To fix the first two, use this function:
function objToDate(obj) {
let result = new Date(0);
result.setSeconds(obj.seconds);
result.setMilliseconds(obj.nanoseconds/1000000);
console.log('With nano', result);
return result;
}
This creates a new date and then sets the seconds and milliseconds. This gives you dates in October 2018 when I use your test data.
Then, to compare them and fix the remaining problems, use this (much simpler) form:
let sortedData = data.sort((a:any, b:any) => {
let bd = objToDate(b.element.updatedOn);
let ad = objToDate(a.element.updatedOn);
return ad - bd
});
That should do it.
To reverse the sort order, just use the less-than operator:
return bd - ad
Turn your strings into dates, and then subtract them to get a value that is either negative, positive, or zero:
array.sort(function(a,b){
return new Date(b.date) - new Date(a.date);
});
Is it something like this:
var array = [
{id: 1, name:'name1', date: 'Mar 12 2012 10:00:00 AM'},
{id: 2, name:'name2', date: 'Mar 8 2012 08:00:00 AM'}
];
console.log(array.sort((a, b) => {
return new Date(a.date) - new Date(b.date)
}))

Replace JSON Object Programmatically

I'm looking for the most effective way to replace a JSON Object in a file.
20150628 - Update at the bottom of this post
Here's the scenario:
I have a bunch of JSON files (many) and in these files are large chunks of JSON (sometimes 20-30K lines of it). These are configurations for various testing routines we have. Recently, a change was required to change an object from this:
"createdAt": {
"year": 2014,
"month": 11,
"dayOfMonth": 24,
"hourOfDay": 2,
"minute": 22,
"second": 54
}
to a format like this:
"createdAt":"2015-05-12T21:14:51Z"
Let's even make this easier. I want to replace all of the createdAt and updatedAt fields in my JSON object (which there can be many) with:
"createdAt":"2015-05-12T21:14:51Z"
or
"updatedAt":"2015-05-12T21:14:51Z"
There are NUMEROUS (100's of these) objects in each file, with different values for the fields. I need to go through and replace every createdAt and updatedAt object with the new format. The date's do not matter. I can have them be anything.
I can do this by hand, but it will literally take me a day or two to do of full time work (I know, I tried to do one file and after 1/2 hour I gave up, it was taking way too long).
How can I do this programmatically?
Regex? Sed? Something else?
Final note: I only need to do this once. After that, I won't need to do it again.
Thanks for any tips!
Example JSON: (Just imagine the real one is 30,000 lines!) :)
{ "products": [
{
"displayOrder": 3,
"product": {
"foo": "bar",
"createdAt": {
"year": 2014,
"month": 11,
"dayOfMonth": 24,
"hourOfDay": 2,
"minute": 22,
"second": 54
},
"description": "Fizz Bin",
"id": "8765309",
"modelNumber": "call-it",
"name": "Boom",
"price": {
"amount": 100,
"currency": "USD"
},
"type": "Active",
"updatedAt": {
"year": 2015,
"month": 1,
"dayOfMonth": 27,
"hourOfDay": 19,
"minute": 33,
"second": 25
}
}
},
{
"displayOrder": 4,
"product": {
"foo": "barx",
"createdAt": {
"year": 2013,
"month": 1,
"dayOfMonth": 4,
"hourOfDay": 3,
"minute": 2,
"second": 5
},
"description": "Fizzy Stuff",
"id": "876511111",
"modelNumber": "zoom-zoom-1000",
"name": "Zoom Zoom 1000",
"price": {
"amount": 1000,
"currency": "USD"
},
"type": "Active",
"updatedAt": {
"year": 2011,
"month": 5,
"dayOfMonth": 25,
"hourOfDay": 15,
"minute": 35,
"second": 55
}
}
}
]
}
UPDATE 20150628
For those wondering, here's the gulpfile I wrote to accomplish exactly what I wanted. It is based off of the accepted answer. It will recursively search the tree for what I'm looking for an replace it when found. Its not the prettiest thing in the world, but it did exactly what I needed and saved me a couple weeks of manual time. Total time to process all my files? Under 100ms. Amazing.
var gulp = require('gulp');
var change = require('gulp-change');
function searchTreeForDates(obj) {
if(typeof(obj) === 'object') {
for (var key in obj) {
if (typeof(obj[key]) === 'object' && (key === 'createdAt' || key === 'updatedAt')) {
obj[key] = "2015-06-29T00:53:00Z";
} else {
obj[key] = searchTreeForDates(obj[key])
}
}
}
return obj;
}
function updateDate(content) {
var obj = JSON.parse(content);
obj = searchTreeForDates(obj);
return JSON.stringify(obj);
}
gulp.task('change', function() {
return gulp.src('*.json')
.pipe(change(updateDate))
.pipe(gulp.dest('changed/'))
});
Here is an initial stab. You implement your own "date parsing logic." It requires you to install gulp. And save this in a gulpfile.js . You would need to possibly loop over all the properties that are "date" objects. But that logic isn't that hard.
var gulp = require('gulp');
var change = require('change');
function translateDate(dateField){
return dateField.A + dateField.b + ...;
}
function updateDate(content) {
var obj = JSON.parse(content);
//loop over the obj properties and call the below
// for the ones you want to change.
obj.dateField = translateDate(obj.dateField);
return JSON.stringify(obj);
}
gulp.task('change', function() {
return gulp.src('**/*.json')
.pipe(change(updateDate))
.pipe(gulp.dest('changed/'))
});
Why not manually?
function formatDate(dateObject){
var formattedDate =
dateObject['year']+'-'+
dateObject['month']+'-'+
dateObject['dayOfMonth']+'T'+
dateObject['hourOfDay']+':'+
dateObject['minute']+':'+
dateObject['second']+'Z';
}
var jsonArray = {...};
for(var key in jsonArray){
for(var i = 0; i < jsonArray[key].length; i++){
jsonArray[key][i]['createdAt'] = formatDate(jsonArray[key]['createdAt']);
jsonArray[key][i]['updatedAt'] = formatDate(jsonArray[key]['updatedAt']);
}
}
Open each file, change the property with a convert function and then save the new JSON:
function changeDate(obj) {
var newObject = obj.year + '-' + obj.month + '-' + obj.dayOfMonth + 'T' + obj.hourOfDay + ':' + obj.minute + ':' + obj.second;
return newObject;
}
// here you open the file and stores it's content in the products variable.
for (var i = 0; i < products.length; i++) {
var product = products[i];
product.product.createdAt = changeDate(product.product.createdAt);
product.product.updatedAt = changeDate(product.product.updatedAt);
}
// .. now you need to save the modified json

Categories