D3: Format date type - javascript

I want to format a date in D3. Here is my code:
var format = d3.time.format("%Y/%m");
var dates = data.map(function(d){ return new Date("2016/01/03"); });
var formDate = format.parse(dates);
console.log(formDate);
My formDate seems to be null, don't know why.
In my chart the values are not displayed at all. How should I format it to get something like "2016/01" ?

Based on your comments, you need to use format as a function itself.
format.parse() is for parsing string representations of a date into a javascript Date (the opposite operation from what you are looking for).
For instance, given a date, 'd', you would use the following code to get what you would like:
var format = d3.time.format("%Y/%m");
var formattedDate = format(d);
Further adding to the confusion, it looks like you attempted to use parse() on a collection of dates. both parse() and format() only support individual strings/Dates respectively, so keep that in mind.
You haven't given enough information to suggest what structure your data is in, but the above should be enough to help you formulate a transform function for your x axis labels.

Related

Find closest date in list to date of interest with google earth engine

I have created a list of Sentinel 2 images. I have also extracted the date value from the DATATAKE_IDENTIFIER field and pasted it back as a property named "DATE" of ee.Date type for every image of my list. Now i am trying to retrieve the image which is chronologically closest to a date of interest specified by the user.For example if i have dates for: 5-May, 10-May, 15-May, 20-May and the user chooses 14th-May i want to return 15-May. Can someone please help?
Here is my code:
var startDate = ee.Date('2017-07-01');
var finishDate = ee.Date('2017-07-31');
//Create imageCollection with the sentinel2 data and the date filters
var interestImageCollection = ee.ImageCollection(sentinel2_1C_ImageCollection)
.filterBounds(interestRectangle) //changed here your geometrical shape
.filterDate(startDate, finishDate)
.sort('CLOUDY_PIXEL_PERCENTAGE', false);
//function which will extract the date from the 'DATATAKE_IDENTIFIER' field and add it as a new one to every image
var add_date = function(interestImageCollection){
//iterate over the image Collection
//.map must always return something
return interestImageCollection.map(function(image){
//take the image property containing the date
var identifier = ee.String(image.get('DATATAKE_IDENTIFIER'));
//regex
var splitOn = "_|T";
//split
var splitted = identifier.split(splitOn,"");
var date = ee.String(splitted.get(1));
//DATE OPTION
var year = ee.Number.parse(date.slice(0,4));
var month = ee.Number.parse(date.slice(4,6));
var day = ee.Number.parse(date.slice(6,8));
var dateTaken = ee.Date.fromYMD(year, month, day);
return image.set('DATE',dateTaken);
});
};
//list conversion
var subList = interestImageCollection.toList(interestImageCollection.size());
//get the image with the chronologically closest date to my date of interest
var dateOfInterest = ee.Date('2017-07-10');
//failed attempt to use sort for difference in dates calculation and get the closest date
var c = subList.sort(function(a, b){
var distancea = dateOfInterest.difference(a.get['DATE'],'day').round().abs();
var distanceb = dateOfInterest.difference(b.get['DATE'],'day').round().abs();
return distancea - distanceb; // sort a before b when the distance is smaller
}).first();
For programming languages i would use a loop which at every iteration would check if the difference between my desired date and the retrieved date is lower than any previous value and update some temporal variables. But i think that earth engine has a more automated way to do that.
I also tried to use the sort function with a custom comparator but that did not work as well.
Also some regular javascript (like closestTo) functions seem to not be working in earth engine.
I think there is a much shorter and easier solution to this. Each image should have a property named system:time_start that we can use can use to our advantage. Since we know our date, we can add a new property to our images that signify distance to our required date in terms of milliseconds as we can just treat it as numeric operation that going through all the day month considerations that come with YMD format.
ic = ic.map(function(image){
return image.set(
'dateDist',
ee.Number(image.get('system:time_start')).subtract(dateOfInterest.millis()).abs()
);
});
This new field 'dateDist' can now be used to sort the image collection.
ic = ic.sort('dateDist');
The default way of sorting is ascending so this should be good. And you can get the closest scene by taking the first image. One thing to consider is that if your ROI rectangle covers enough area to look at multiple row/path then there might be multiple scenes with closest dates. In such case it might be good idea to inspect how many scenes fall within same date range.

Attempt to sort firebase database is not working

I am trying to sort firebase date by date but it is not working.
I have firebase data structure in this format
I use this function to call the node
var awardsref = CatalogueDB.ref("cageawards/" + mycagecode).orderByChild('Awarddate');
awardsref.on('value', Awardstable, errData);
this is the output
is there a work around to sort the data based on this date format?
As #GerardoHerrera pointed out, Firebase don't support sorting by Date. However, if you parse the dates and convert them to milliseconds based on the UNIX epoch, you should be able to sort them lexicographically according to that.
const date1 = new Date("04-07-2018").getTime();
date1; // 1523084400000
const date2 = new Date("06-02-2018").getTime();
date2; // 1527922800000
Since date1 is less than date2, it will sort as being before date2 in ascending order. Store those converted millisecond time values in your Firebase and you should be able to sort your dataset by them.
e.g.
"7MFD4" {
...
"SPE7L018P1428" {
"Awarddate": "04-07-2018",
"AwarddateMS": 1523084400000
...
}
...
}
Then do orderByChild('AwarddateMS').
According to the following page, How query data is ordered, a date is not considered in any sorting way. It first orders null values, then false values, then true, numbers, strings and finally objects.
And all sorting is made following a Lexicographical Order.
So you may need to do the sorting on the client side by your own methods.
ThereĀ“s another post where you can find an explanation on how to sort by date here

Meteor.js / MongoDB between dates query not returning data

I have the following piece of code for getting results back from a Mongo Collection.
var currentDate = moment().toISOString();
// RETURNING: 2016-12-10T20:36:04.494Z
var futureDate = moment().add(10, "days").toISOString();
// RETURNING: 2016-12-20T20:36:04.495Z
return agenda = Agendas.find({
"agendaDate": { '$gte': currentDate, '$lte': futureDate }
});
And the date is stored in MongoDB Collection like below;
{
"_id" : ObjectId("584877e56466dd236cd95f15"),
"agendaDate" : ISODate("2016-12-12T17:28:25.000+0000"),
"agendaTime" : "20:59",
"agendaEvent" : "Test event"
}
However, I am not getting any results returning as all. I have set up 3 test documents, 2 in the range, 1 outside.
Can anyone explain what I'm doing wrong and help rectify the code?
You need to compare dates against actual date objects, not strings representing them.
That is, you need to get the date from your moment objects, using the toDate() method.
var futureDate = moment().add(10, "days").toDate();
Well actually moment.toISOString() returns a string, so you can't use it to compare with date object in your mongodb query.
You should consider creating a date object for that.
Regs,
Yann

Why doesn't flot work with a array of (x,y) values? Javascript object versus arrays?

I'm creating a flot graph using some php-script. The php generates the data and uses json_encodeto pass this data to some javascript-flot code where I parse using jQuery.parseJson.
I was using the data-array filled with (x,y) values. Plotting this doesn't seem to work. If I encapsulate the array within an object flot is plotting it without problems. Why doesn't the first method work? I've added a jsFiddle below.
var data = '[["201518","1"],["201519","3"],["201520","6"]]',
data2 = '{"data":[["201518","1"],["201519","3"],["201520","6"]]}';
var set = jQuery.parseJSON(data),
set2 = jQuery.parseJSON(data2);
var placeholder = $('#placeholder');
$.plot(placeholder, [set2.data]);
//$.plot(placeholder, set); <= not working? Why?
jsfiddle
You need to pass an array:
$.plot(placeholder, [set])
// instead of `$.plot(placeholder, set)`
Two problems. First you need numbers and not strings when passing as an array (see here where it says
Note that to simplify the internal logic in Flot both the x and y
values must be numbers (even if specifying time series, see below for
how to do this). This is a common problem because you might retrieve
data from the database and serialize them directly to JSON without
noticing the wrong type. If you're getting mysterious errors, double
check that you're inputting numbers and not strings.
Second (as pointed out in another answer), you need the [array] around set. The following works:
$(document).ready(function () {
var data = '[[201518,1], [201519,3], [201520,6]]',
data2 = '{"data":[["201518","1"],["201519","3"],["201520","6"]]}';
var set = jQuery.parseJSON(data),
set2 = jQuery.parseJSON(data2);
var placeholder = $('#placeholder');
//$.plot(placeholder, [set2.data]);
$.plot(placeholder, [set]);
});

Issues with Date() when using JSON.stringify() and JSON.parse()

I am trying to calculate the difference between two times using JavaScript. It's just basic math but I seem to have some issues with that while using JSON.stringify() and JSON.parse().
If you're wondering why am I applying the JSON.stringify() function to the date, it's because I using local storage to store some data on the client side and use it whenever the client lands on my website again ( it's faster that way rather than making more requests to the server ). That data usually updates once in a while ( I'm grabbing the data through API from another website ), so I set up a data_update variable and I'm storing it together with the other data.
That way I'm grabbing the stored data from the local storage and check if the difference between data_update ( which is a date / time ) and the time / date when the check it's made and see if it's greater than a week / day /etc .
So that is the reason why I'm using the JSON functions. My problem is that when I'm parsing the data from the local storage, the date seems to be different from a Date() object.
I'm trying to do the next operation per say :
var x = JSON.parse(JSON.stringify(new Date()));
var y = JSON.parse(this.get_local_storage_data(this.data_cache_key)); // the data object stored on local storage
var q = y.data_update; // this is the variable where the Date() was stored
console.log(Math.floor((x-q)/1000));
The above will return null. Also when I want to see the Math.floor(x) result, it returns null again.
So what can I do in this situation ? Is there a fix for this ?
If you look at the output of JSON.stringify for a Date, you'll see that:
JSON.stringify(new Date())
Results in a string. JSON does not have a primitive representation of Date objects that JSON.parse will turn back into a Date object automatically.
The Date object's constructor can take a date string, so you can turn those string values back into dates by doing:
var x = new Date(JSON.parse(JSON.stringify(new Date())));
Then the arithmetic will work.
x = new Date(JSON.parse(JSON.stringify(new Date())))
y = new Date(JSON.parse(JSON.stringify(new Date())))
y - x
=> 982
JSON.stringify(new Date())
returns
"2013-10-06T15:32:18.605Z"
Thank God is: Date.prototype.toISOString()
As the recommended answer suggests, the date is simply converted to a string when using JSON.stringify.
Another approach that would maybe fit this use case is to store the time in milliseconds using Date.now():
// Date.now() instead of new Date()
const millis = Date.now();
console.log(millis);
// same output as input
console.log(JSON.parse(JSON.stringify(millis)));
That way you can be sure that what goes into JSON.stringify comes out the same when using JSON.parse.
This also makes it easy to compare dates, if you have two millisecond values, using < and >.
Plus you can convert the milliseconds to a date at any time (usually before you render it to the user):
const millis = Date.now();
console.log(millis);
console.log(new Date(millis));
NOTE: using milliseconds as your date representation is usually not recommended, at least not in your database: https://stackoverflow.com/a/48974248/10551293.

Categories

Resources