d3.max return wrong date - javascript

I have a kind a weird problem. I'm loading data for a overview page. I need to show max date, so users know which time period they're dealing with. Now, I know which date this should be (today or yesterdays date, this is updated once a night) but I would like to do a max function anyway, in case something goes wrong during the update.
The problem I'm having is that both d3.max and a custom max-date function returns the wrong date. One month in the future, so today should show 7/9 2015 but instead it displays 7/10 2015. When I filter the data on 7/10 i get an empty array. In fiddle this works alright so there is something fishy going on. I do run an d3.tsv(tsv is right, even if the extension says .csv the file is in fact tab-separated), might be something there that's causing trouble? Any ideas where i might go wrong? The parsefunction alone returns the right results, the dates when read have the following format: dd.mm.yyyy
//Dateformatting
function parseDate (dateStr) {
var s1 = dateStr.split(" ");
var s1dat = s1[0].split(".");
return new Date(s1dat[2], s1dat[1], s1dat[0])
};
var dateArr = [];
//Occupation
d3.tsv("data.csv", function(error, data, tsv) {
datasetIn = data;
datasetIn.forEach(function(d) {
d.datum = parseDate(d.datum);
d.Patients = +d.Patients.replace(",", ".");
d.Beds= +d.Antal_vardplats.replace(",", ".");
});
for (index = 0; index < datasetIn.length; ++index) {
dateArr.push(datasetIn[index].datum);
}
var maxYear = d3.max(dateArr).getFullYear();
var maxDate = d3.max(dateArr);
})

In JavaScript month values are zero-based beginning with 0 for January to 11 for December. Passing in a human-readable 9 representing September to new Date() is supposed to create a Date object for October instead.
new Date("2015", "9", "7").toDateString(); // "Wed Oct 07 2015"
Adjusting for this should give you the correct result when parsing human-readable date values.

Related

Difficulty converting json string to date format in d3

I've tried to look at some code examples for this but I'm stuck here. I have a json which is reading dates as strings. For example:
1/1/1993 is 33970.
I have points on a map, each with associated dates. I have a time-slider based on dates. Once the time slider is updated, I would like the appearance of the points to change based on the date value of slider.
// build slider
var inputValue = null;
var year = ["1993","1994","1995","1996","1997","1998","1999","2000","2001","2002","2003","2004","2005","2006","2007","2008","2009", "2010","2011","2012","2013","2014","2015","2016","2017","2018","2019"];
Build function to update slider.
function update(value) {
document.getElementById("range").innerHTML=year[value];
inputValue = year[value];
d3.selectAll(".points")
.attr("fill", dateMatch);
}
d3.select("#timeslide").on("input", function() {
update(+this.value);
console.log(value)
});
And finally, build the function that matches the date in my data, to the date in the time slider!
function dateMatch(data, value) {
var d = new Date(data.properties.Sign_Date);
var y = [d.getFullYear()];
console.log(y)
console.log(d)
if (inputValue == y) {
this.parentElement.appendChild(this);
return "blue";
} else {
return "#999";
};
}
I think the template here should work but there is an issue reading in the dates in the dateMatch function. For some reason, it's just printing
Wed Dec 31 1969 16:00:41 GMT-0800 (Pacific Standard Time)
For every record in my data. Which doesn't make sense since my data doesnt even go back to 1969. Can anyone tell me what they think might breaking here, or better, an easier way to filter this temporal data?
You need to convert all your dates to real dates. Be aware, if you don't use UTC (universal time zone) or another defined timezone the date conversion will depend on the timezone set on the computer. For more about javascript dates I suggest reading MDN.
function createDateUTC(yourDateFormat) {
var parsed = yourDateFormat.split('/'),
day = +parsed[0],
monthIndex = +parsed[1]-1,
year = +parsed[2]
return new Date(Date.UTC(year, monthIndex, day))
}

Javascript date constructor on Cordova WP8

I have a date string in the format 28-Dec-2016 04:25 AM and need to convert it to a Date object. For this, I first split the string to get the date and time
cDateStringParts = cdate.split(' ');
Then I get the date and time components
cDateParts = cDateStringParts[0].split('-');
cTimeParts = cDateStringParts[1].split(':');
Then I initialize the Date object like
if(cDateStringParts[2]=='AM'){
cDateObject = new Date(cDateParts[2], convertToNumericMonth(cDateParts[1]), cDateParts[0], cTimeParts[0], cTimeParts[1], 0, 0);
} else {
cDateObject = new Date(cDateParts[2], convertToNumericMonth(cDateParts[1]), cDateParts[0], complaintTimeParts[0] + 12, cTimeParts[1], 0, 0);
}
where convertToNumericMonth() is a function which converts Jan-Dec to 0-11.But I do not get the correct values when I check cDateObject.getDate()/getMonth()/getYear(). The result is 2017/12/29.
What am I doing wrong? If I try to do alert(cdate,' ',cDateObject.getFullYear() I get this:
One issue is how 12hr time is converted to 24hr time. The date parts are strings, so for "03:45 PM" the following:
complaintTimeParts[0] + 12
will return "0312". Also, "12:00 AM" should have the hours set to 0, but your code will set the hours to 12.
The hours can be converted to 24hr time by converting to a number first, converting 12am to 0 and then adding 12 if it's PM. Also simpler if done separately from the rest of the calculation:
var hr = cTimeParts[0] % 12 + (cDateStringParts[2]=='AM'? 0 : 12);
Here the mod operator % will convert cTimeParts[0] to a number. Now the function can be:
function dateParse(cdate) {
var cDateStringParts = cdate.split(' ');
var cDateParts = cDateStringParts[0].split('-');
var cTimeParts = cDateStringParts[1].split(':');
var hr = cTimeParts[0] % 12 + (cDateStringParts[2]=='AM'? 0 : 12);
return new Date(cDateParts[2], convertToNumericMonth(cDateParts[1]),
cDateParts[0], hr, cTimeParts[1]);
}
function convertToNumericMonth(month) {
return {Jan:0,Feb:1,Mar:2,Apr:3,May:4,Jun:5,Jul:6,
Aug:7,Sep:8,Oct:9,Nov:10,Dec:11}[month];
}
console.log(dateParse('28-Dec-2016 04:25 AM').toString());
console.log(dateParse('28-Dec-2016 04:25 PM').toString());
Lastly, missing parts are set to 0 (or 1 for the date) so they don't need to be included.
This link might be a solution for your issue.
you cannot actually rely on the date parsing because, it is dependent on multiple factors like time zones, daylight saving etc.
you could also check your device's time zone and time settings because, the browser uses system data for parsing date.
i have checked the same logic on my browser and it worked fine for me.
here is the example.
if it is working this way, the issue would be that the values calculated by cDateParts is generating different values(very less possibility).
hope this would help you.

Javascript dates to array

I am working on a website where users can book vacation houses.
Booking always is from Saturday to Saturday. If users click on any date in that week, the whole week must be selected. I've got that part working.
I gave the selected dates the "date-range-selected" class. And if the first day was already booked, but only in the morning then I gave it the class "half-selected". Now because I need to calculate with these dates I need the full dates and not only the day number. Only the ones with the "half-selected" and the "date-range-selected" need to be added to an array.
I tried to push variables to that array and it seemed to work, but when I try to use the array after the for loop, it seems like all array content is changed to the date after the last selected date, what am I doing wrong?
//ex.selected dates are: 9-16 august
var halfke= document.getElementsByClassName("half-selected");
var rest = document.getElementsByClassName("date-range-selected");
var dagen = [];
if(typeof halfke[0] != 'undefined')
{
dagen.push(halfke[0].getElementsByClassName("ui-state-default")[0].innerHTML.trim());
}
for (index = 0; index < rest.length; ++index)
{
dagen.push(rest[index].getElementsByClassName("ui-state-default")[0].innerHTML.trim());
}
var myDate = new Date(cur);
var dw = myDate.getDay();
myDate.setDate(myDate.getDate() - (dw+1));
var myDate2 = new Date(cur);
myDate2.setDate(myDate2.getDate() + (6-dw));
//alert(dagen[0]);
var juiste_dagen = new Array();
for (var d = myDate; d <= myDate2; d.setDate(d.getDate() + 1)) {
//alert(dagen[0]+ " - " + String(d.getDate()))
if(dagen.indexOf(String(d.getDate()))>-1)
{
//alert(d);
juiste_dagen.push(d);
alert(juiste_dagen[0]);//here it alerts 9 august (as it should)
}
}
alert("done");
alert(juiste_dagen[0]);//here it alerts 17 august(which it should not do)
alert(juiste_dagen[1]);//here it alerts 17 august(which it should not do)
alert(juiste_dagen[2]);//here it alerts 17 august(which it should not do)
It's probably something small and stupid but I can't seem to find it.
Any help is appreciated!
This is a pass-by-reference problem and it's working as intended. Primitives (like numbers and strings) are pass-by-value. Date is an object, and it is passed by reference, which means without copying. Everywhere you pass a Date object is the same date. Look at the following code, tested just now in my Chrome console:
var myDate = new Date();
undefined
var juiste_dagen = [];
undefined
juiste_dagen.push(myDate);
1
juiste_dagen[0];
Fri Jul 18 2014 09:35:02 GMT-0500 (CDT)
myDate.setDate(19);
1405780502241
juiste_dagen[0];
Sat Jul 19 2014 09:35:02 GMT-0500 (CDT)
So the problem is in your last forloop where you do d.setDate(d.getDate() + 1). You're essentially setting all of the dates pushed into your array to this date on every iteration of the loop. Either use a simple number for a loop counter or create a new date each time before changing the day.

how can change the text string to date object?

i am getting string from server and i need to covert that fetching string in to new date object.. for doing this, i tried this function, but no use, any one can help me to convert strings to date object?
my code is :
var nationZone = {
getNewYorkLocalTime : 'getTime.php?lat=40.71417&lan=74.00639',
getLondonLocalTime : 'getTime.php?lat=51.5&lan=0.1166667',
getChennaiLocalTime : 'getTime.php?lat=13.0833333&lan=80.2833333',
getBangaloreLocalTime:'getTime.php?lat=12.9833333&lan=77.5833333'
}
$.each(nationZone , function(key, value){
$.get(value, function(response){
var newdate = $(response).find('localtime').text();
if(key == "getNewYorkLocalTime"){
var newyourktime = new Date(newdate);
newyourktime.getTime()
}
});
});
but, the newyourktime is showing local time only.. any help please? as well i am getting the response from server is : 17 Nov 2011 18:09:47 - like this.
Use http://www.datejs.com/
As an example:
var newyourktime = Date.parse('2011-11-11, 11:11 AM');
alert(newyourktime.toString('dd/mm/yyyy HH:mm:ss EST'));
Check out the Datejs library documentation to meet your requirements, after your date string is parsed, you can do a lot with it.
This will try to parse the date using the client machine own local settings, which is not good.
Instead of passing it as string, pass it as the total seconds that passed since 1/1/1970 at midnight and use this number when constructing the new Date object of JavaScript.
For example pass this number: 1321614000000 and you will get November 18th 2011, 1 PM
You could use substr
day = newdate.substr(0,2);
month = newdate.substr(3,3);
year = newdate.substr(7,4);
var newyorktime = new Date(year, month, day);
Substr

javascript: How to hide DIVs/ULs that represent past dates?

I have some code that looks like this:
<h3>Thursday Sep 10</h3>
<ul>great stuff in here</ul>
<h3>Friday Sep 18</h3>
<ul>other stuff in here</ul>
They have a basic jQuery hidey-showy thing happening: click on the H3, and the UL underneath expands or contracts. By default they are all showing/open.
I'd like to set it up so that any date that has passed (like Sep 10 in this example) is contracted by default.
I don't seem to be able to get my CMS to spit out a nice compare-able date (like epoch time) to use as an ID for the H3. Is there a way I can use js's Date() function to build something like that out of the existing information ("Thursday Sep 10"), or some other way entirely to get this done?
(All of the dates are in 2009 and the site won't exist in 2010, so hardcoding the year into any functions is A-OK if that's what needs to be done.)
Thanks!
The first hurdle is to convert your text dates into valid strings that can initialize JavaScript date objects.
The conversion process (including valid string formats) is covered on http://programming.top54u.com/post/Javascript-Convert-String-to-Date.aspx.
Unfortunately, your text representations are not valid inputs for the JavaScript Date constructor. You will need to write a function to convert your strings into a valid representation before using them in the Date constructor.
Once you have your Date objects initialized, you can compare them (see "Compare Two Dates" on http://www.w3schools.com/jS/js_obj_date.asp).
I agree with Mayo. If you had access to the date time value and wanted to convert it to a string similar to what you have ("Thursday Sep 10"), you could use this.
Keep it simple; you don't really need a proper date parser to compare your dates. I've got the feeling that you're looking for something quick and dirty:
var now = new Date();
var nowHash = now.getMonth() << 5 + now.getDate();
$("h3").each(function (e) {
var tokens = $(e).html().split(" ");
var hash = [ "Jan", "Feb", ..., "Dec" ].indexOf(tokens[1]) << 5 + tokens[2];
if (hash < nowHash) {
// contract the <ul> that follows
}
});
Month * 32 (or shift 5 bits to left) + day is enough to give you a unique hash of a date that can be compared with other dates.
Mayo is correct about having no quick way. So here is my take on DIY solution.
Basically you extract the date and compare the date yourself.
var aMonths = { "Jan":0, "Feb":1 ..., "Sep":8, ... };
var aToday = new Date();
var aH3Text = .....; // Get the value via jQuery
var aDataElements = aH3Text.split("");
var aMonthIndex = aMonths[aDataElements[1]];
var aDateIndex = aDataElements[2];
var aH3Date = new Date();
aH3Date.setFullYear(2009, aMonthIndex, aDateIndex);
if (aH3Date > today) {
// BEFORE today
} else {
// AFTER today
}
Hope this helps.

Categories