How to compare date in JSON data using jmespath? - javascript

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)

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 filter JSON data from API by date range in 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()

Filtering unix timestamps

So, I am working on a time registration management tool. I have a date picker component where I choose the date I want to see the registrations from. It gives me the Unix timestamp of that day and I store that value, fx. 1606856503.
Now, I am retrieving all registrations from the API, which is an array of objects where each object is a registration. Each registration has a date property, which is basically a Unix timestamp from the date it was created.
[{
"id": "1",
"userId": "userId 1",
"customerId": "customerId 1",
"case": "case 1",
"description": "description 1",
"hours": 72,
"date": 1606826246,
"customer": "customer 1",
"project": "project 1"
}]
Now, that I have a date picker Unix timestamp, I would like to filter the registrations in order to filter and display only registrations which were made on the day of the Unix timestamp from the picker, but can't figure out how would I compare them and filter based on the day.
Here's a quick snippet illustrating using either Date.prototype.toISOString() or Date.prototype.toDateString() to filter against a specified timestamp.
Since your timestamps are stored in seconds and javascript dates use milliseconds, you need to multiply by 1000 when creating your dates
const filterTimestamp = 1606859476; // Tuesday, December 1, 2020 9:51:16 PM
const filterDate = new Date(filterTimestamp*1000);
You can then filter by comparing the first 10 characters of the date strings returned by toISOString() which will always keep the timezone as zero UTC offset
const filterDateString = new Date(filterTimestamp*1000).toISOString().slice(0, 10);
// "2020-12-01" sliced from "2020-12-01T21:51:16.000Z"
const regsOnDate = regs.filter(o => (
new Date(o.date*1000).toISOString().slice(0, 10) === filterDateString));
or by the date strings returned by toDateString() which will use the local timezone
const filterDateString = new Date(filterTimestamp*1000).toDateString();
const regsOnDate = regs.filter(o => (
new Date(o.date*1000).toDateString() === filterDateString));
// eg: compares "Mon Nov 02 2020" to "Tue Dec 01 2020"
Using toISOString()
const regs = [
{
"id": "1",
"date": 1606826246, // Tuesday, December 1, 2020 12:37:26 PM
"customer": "customer 1",
},
{
"id": "2",
"date": 1604353553, // Monday, November 2, 2020 9:45:53 PM
"customer": "customer 2",
},
{
"id": "3",
"date": 1606860022, // Tuesday, December 1, 2020 10:00:22 PM
"customer": "customer 3",
}
]
const filterTimestamp = 1606859476; // Tuesday, December 1, 2020 9:51:16 PM
const filterDateString = new Date(filterTimestamp*1000).toISOString().slice(0, 10);
// "2020-12-01" sliced from "2020-12-01T21:51:16.000Z"
const regsOnDate = regs.filter(o => (
new Date(o.date*1000).toISOString().slice(0, 10) === filterDateString));
console.log( regsOnDate );
Using toDateString()
const regs = [
{
"id": "1",
"date": 1606826246, // Tuesday, December 1, 2020 12:37:26 PM
"customer": "customer 1",
},
{
"id": "2",
"date": 1604353553, // Monday, November 2, 2020 9:45:53 PM
"customer": "customer 2",
},
{
"id": "3",
"date": 1606860022, // Tuesday, December 1, 2020 10:00:22 PM
"customer": "customer 3",
}
]
const filterTimestamp = 1606859476; // Tuesday, December 1, 2020 9:51:16 PM
const filterDateString = new Date(filterTimestamp*1000).toDateString();
const regsOnDate = regs.filter(o => (
new Date(o.date*1000).toDateString() === filterDateString));
console.log( regsOnDate );
UNIX timestamps are seconds since 1 Jan 1970 UTC, ECMAScript time values are milliseconds since the same epoch, see Convert a Unix timestamp to time in JavaScript.
If you just want to compare values for the same date UTC, you can just compare whole days since the epoch. That means a simple arithmetic operation on the value rather than using Date objects. e.g.
let data = [{"id": "1","date": 1606826246}, // 1 Dec 2020 UTC
{"id": "2","date": 1606867200}, // 2 Dec 2020 UTC
{"id": "3","date": 1606953600} // 3 Dec 2020 UTC
];
// Start with date sometime on 2 Dec 2020 UTC
let d = new Date(Date.UTC(2020,11,2,8,32,21)); // 2 Dec 2020 08:32:21 Z
console.log('Test date: ' + d.toISOString());
// Get whole days since epoch
let daysSinceEpoch = d.getTime() / 8.64e7 | 0;
console.log('daysSinceEpoch: ' + daysSinceEpoch);
// Find matching records in data
let result = data.filter(obj => (obj.date / 8.64e4 | 0) == daysSinceEpoch);
console.log('Matching records: ' + JSON.stringify(result));
// Matching date values
console.log('Matching dates:');
result.forEach(obj => console.log('id: ' + obj.id + ' on ' + new Date(obj.date * 1000).toISOString().substr(0,10)));
You can do the same thing with local dates, you just need to be a bit more careful of getting the days, see How do I get the number of days between two dates in JavaScript?

How to ignore time-zone on new Date()?

I have JavaScript function called updateLatestDate that receive as parameter array of objects.
One of the properties of the object in array is the MeasureDate property of date type.
The function updateLatestDate returns the latest date existing in array.
Here is the function:
function updateLatestDate(sensorsData) {
return new Date(Math.max.apply(null, sensorsData.map(function (e) {
return new Date(e.MeasureDate);
})));
}
And here is the example of parameter that function receive:
[{
"Address": 54,
"AlertType": 1,
"Area": "North",
"MeasureDate": "2009-11-27T18:10:00",
"MeasureValue": -1
},
{
"Address": 26,
"AlertType": 1,
"Area": "West",
"MeasureDate": "2010-15-27T15:15:00",
"MeasureValue": -1
},
{
"Address": 25,
"AlertType": 1,
"Area": "North",
"MeasureDate": "2012-10-27T18:10:00",
"MeasureValue": -1
}]
The function updateLatestDate will return MeasureDate value of last object in the array.
And it will look like that:
var latestDate = Sat Oct 27 2012 21:10:00 GMT+0300 (Jerusalem Daylight Time)
As you can see the time of the returned result is different from the time of the input object.The time changed according to GMT.
But I don't want the time to be changed according to GMT.
The desired result is:
var latestDate = Sat Oct 27 2012 18:10:00
Any idea how can I ignore time zone when date returned from updateLatestDate function?
As Frz Khan pointed, you can use the .toISOString() function when returning the date from your function, but if you're seeking the UTC format, use the .toUTCString(), it would output something like Mon, 18 Apr 2016 18:09:32 GMT
function updateLatestDate(sensorsData) {
return new Date(Math.max.apply(null, sensorsData.map(function (e) {
return new Date(e.MeasureDate).toUTCString();
})));
}
The Date.toISOString() function is what you need
try this:
var d = new Date("2012-10-27T18:10:00");
d.toISOString();
result:
"2012-10-27T18:10:00.000Z"
If you use moment it will be
moment('Sat Oct 27 2012 21:10:00 GMT+0300', 'ddd MMM DD DDDD HH:mm:SS [GMT]ZZ').format('ddd MMM DD YYYY HH:mm:SS')

Categories