Highcharts date off by one day - javascript

I'm passing in milliseconds for the x-axis and then defining the x-axis as:
xAxis: {
type: 'datetime'
},
However, Highcharts seems to be not getting the exact date on the x-axis but is instead off by one day. To illustrate, hover over any of the bars (fiddle at the bottom of this post) and you will see what Highcharts interprets the day as but then click any of them and I have an on-click event to alert you what the actual date is supposed to be. Notice how it is off by one day.
Is this a known bug in Highcharts? Any workarounds?
Here is my fiddle: http://jsfiddle.net/hohenheim/j8cTE/33/

I believe all you need to do is format/consider for UTC. Highcharts default is UTC (0). (http://api.highcharts.com/highcharts#global) if you change to this:
function appendAds(date1) {
alert(new Date(date1).toUTCString());
$('#tableTitle').html("<u>Info for " + timeConverter(date1) + ":</u>");
...
}
(fiddle) http://jsfiddle.net/j8cTE/34/
You will see that it shows correct date with that "toUTCString()" added. You will likely want to convert it to something more pleasant to read, but remember that you will have to keep UTC in mind if you don't use "toUTCString()".
UPDATE:
I wanted to explain that I used "toUTCString()" since it was quick and something I knew off the top of my head. This method wouldn't work for all things, such as further down in your appendAds function since it is a string. To explain UTC and date formatting, parsing and manipulation in full would be too much for this post. But I will try to go over a few key points when dealing with dates on the web. Also, please see MDN for other date info (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date).
If you need accurate information and/or logic for dates, you will need to know the date format you get (from server, database, etc...) - whether it is UTC or not, for example. Then you need to consider if it needs to be manipulated for display (such as for the viewers browser's timezone). And finally, if that date is being used internally, you need to consider if, when, and where you need to convert it once again (as appropriate).

Related

Moment.js not formatting time in microseconds

I'm using moment.js to format a datetime value as follows:
time = moment(this.params['timeValue']).format("HHmmss.SSS")
Here, this.params['timeValue'] is a string. An example value is 2020-02-05 10:00:00.123 . formatting using moment returns the value 100000.123. Sometimes my datetime value goes to microsecond value, but moment js seems to cut the formatted value to millisecond level. For example formatting 2020-02-05 10:00:00.123456 returns 100000.123. I've tried this, but it did not work:
time = moment(this.params['timeValue']).format("HHmmss.SSSSSS")
Could you help me how to handle the formatting of a datetime value with microseconds. If moment.js doesn't handle it, is there any other library I could use?
Moment.js wraps the native date type, which goes down to only milliseconds. You will only get the first three digits, the moment.js documentation shows an example of the fractional seconds (as per your second code snippet), but also mentions that it will only display the 3 significant digits, filling the rest with zeros.
Check out this SO question for more information about microseconds in JavaScript.

Managing multiple date formats in Javascript

Similar questions has been asked many times but I couldn't find a more concrete solution. The things I'm doing are:
I have a <input type="date"> inside my HTML which when clicked opens a calender with date in dd/mm/yyyy format.
I change the html5 date to timestamp to send to my db by Date.parse(html5Date) and in the server I modify the date and send it back to my Angular app.
I now convert the timestamp back to Date object by new Date(timestamp).To print the date in a human-friendly format inside a table I do [date.getDate(), date.getMonth() + 1, date.getFullYear()].join('/').
On edit (PUT request), I again capture the date from HTML, convert it to timestamp, send it to server and process the returning date back to html date.
Other than these, I also do a ton of functionalities like date comparison, adding hours to the dates, show time of the day etc inside the HTML:
Just these simple operations are over 120 lines of code which I think is ridiculous and error prone. I've looked into Angular Datepicker but it's a bit confusing. Also sometimes the HTML date is of type Object and sometimes it's String so Date.parse() gives error.
Are there any developer friendly methods that does : copy HTML5 date (from datepicker) --> change to timestamp (for angular&server) --> format timestamp back to string/object (for html)? Thank You :)
Note: Angular throws a lot of annoying error in console saying dateformat is wrong (being html date type) but doesn't stop code from running
Sounds like you are doing waaay to many conversions. I would argue that there should only be one way dates are represented: as Date objects in the programming language. There are only a few conversions that need to happen:
Date <=> Integer milliseconds since the epoch to pass to server
Date <=> String human-readable format to display to user
Any thing beyond this is asking for trouble. Comparisons can be made by casting to int date.getTime(), comparing, and casting back to Date. Ditto for additions. Note that Date.parse is implementation dependent in what it will accept, although all of them will accept ISO 8601 formatted date strings anything else is guesswork. Which means you will have to deal with converting strings by hand, something like the following:
var toDate = str => {
var splitter = str.indexOf("/") === -1 ? "-" : "/";
var [mon, day, year] = str.split(splitter);
return new Date(year, mon - 1, day);
};
var toDateString = date => {
return "" + date.getFullYear() + (date.getMonth() + 1) +...
};
Note that there's no validation, that's left as an exercise to the reader.
A WORD ABOUT MOMENT.JS
moment.js is awesome. Its also huge, its a kitchen-sink API with a heft to match. You're already loading angular, so think carefully before bulking the size of your payload with another huge library.
Moment.js is a powerful date formatting and manipulation library. A lot of things you can do in Moment.js are a single line of code, which makes life a lot easier. I agree, without using a library like this date formatting and handling can be a pain.
http://momentjs.com/
EDIT: fyi, I use this with my Angular app and find it extremely useful!

Kendo DateTimePicker Not Handling UTC Offset

We are using the Kendo datetimepicker, implemented using the AngularJS directives:
<input type="text" kendo-date-time-picker k-ng-model="TheDateModel">
Where: TheDateModel = 2016-02-15 20:58:24.0000000 +00:00
I am in the CST timezone, which is -6 hour offset from the GMT. The current result of the datetimepicker shows a time of 8:58 pm but my expected result is 2:58 pm.
What in the world am I doing wrong?
Disclaimer: I work for Kendo UI team
The Kendo UI Datepicker uses JavaScript Date object internally to hold the selected date value. As you probably know, it always uses the local (browser) timezone. We tried to explain that caveat in our docs too:
JavaScript Date Object - Basics
Due to this default behavior, the widget will use the already converted Date value (with the applied local timezone). The widget doesn't manipulate the value timezone, as it does not have sufficient information how to do that.
Solution
The best approach in this case is to convert the Date strings (like the one you mentioned "2016-02-15 20:58:24.0000000 +00:00") manually before feed the DatePicker widget. For instance, here is one possible approach to do that:
http://dojo.telerik.com/EyuRA
Notice how the value is parsed and then adjusted in the loadData method. Similar thing should be done by the developer that needs to handle different TZ in their app.
I've been down this road and had to implement this:
http://www.telerik.com/support/code-library/using-utc-time-on-both-client-and-server-sides
So I found the solution to my problem. First off for clarity, and sorry for the misinformation, but my date was coming down from the server as 2016-02-15T20:58:24.0000000+00:00 - add the T and remove all spaces.
All that needed to be done was to add the k-parse-formats attribute to the directive as follows:
<input type="text" kendo-date-time-picker k-parse-formats=['yyyy-MM-ddTHH:mm:sszzz'] k-ng-model="TheDateModel">
Boom, considers the offset and your current timezone, and correctly parses and displays the date and time. Just be aware, that when you specify your own parse formats, to include all possible formats that your dates could be.
For example, I then ran into a problem where I had milliseconds greater than 0 coming through on my dates: 2016-02-15T20:58:24.1234567+00:00. This broke the datetimepicker again. Simpler fix: just changed my parsing format to: yyyy-MM-ddTHH:mm:ss.fffffffzzz. Make sure the number of f is greater than or equal to the number of possible milliseconds.
<input type="text" kendo-date-time-picker k-parse-formats=['yyyy-MM-ddTHH:mm:ss.fffffffzzz'] k-ng-model="TheDateModel">

Preserve time but convert to another timezone

I'm developing an app that lets users create dates/events in other timezones so I need to convert something like
2014-12-01T19:00:00.000Z to any particular timezone such as 'America/Phoenix'.
I'm using moment to handle it:
moment.tz(dt, 'America/New_York').format();
This outputs: 2014-12-01T14:00:00-05:00 which isn't what I want.
All I want to do is change the timezone not the time such that it would become 2014-12-01T19:00:00-05:00
Perhaps I could add the offset of 5 (depending on zone) before i convert the timezone so it would remain the same time? Maybe there is a better way?
Thanks, James
You should recognize that the Z in your string means that the timestamp should be interpreted as UTC. So if you change that to a different offset without adjusting the time accordingly, you are actually picking a different moment in time. Usually, that's not the right thing to do.
By adjusting the time to match the offset for the time zone, Moment is doing the right thing. It's interpreting the input string as UTC, and then adjusting it to the time zone provided.
It sounds like you would like to ignore the Z and treat the time as if it were already in a particular time zone. The best place to change that would be wherever the string is originally generated. If it's not in UTC, it shouldn't be putting the Z at the end in the first place.
However, you could certainly strip it off in JavaScript and get the result you're asking for.
var s = "2014-12-01T19:00:00.000Z";
moment.tz(s.replace(/Z$/,''), 'America/New_York').format();
You can use moment methods like:
startOf
hour
minute
get
Example:
moment.tz(dt, 'America/New_York').startOf('day').hour(dt.get('hour')).minute(dt.get('minutes')).format()
This will print the same hour and minute as the dt variable.
Hope it helps

Comparing dates in Javascript

Imagine there are two labels on a webpage both displaying a date. How would you find out which is the greater date taking into account what the users locale is.
Say Label 1 : 04/11/2009 Label 2: 09/10/2009
If it were in the US Label 2 > Label 1
If it were the UK Label 1 > Label 2
The date constructor ignores locale information so var d = new Date('04/11/2009') will always be the 11th April 2009 rather than the 4th November 2009 no matter the locale. Does anyone know any tricks to get around this? Any libraries worth checking out?
(the only wayout i can see at the moment is get the locale info using js and then parse the label so i can create a date object with another constructor but this seems to much for a supposedly simple problem?Furthermore this is not going to work well with lots of locales)
Recommend using a library like Globalize.js or Date.js

Categories