I'm returning some json from one of my controllers similar to the following:
render :json => {
:date => "new Date(new Date('Jan 01 2000').getTime() + #{500.seconds.to_i} * 1000)"
}
I'm expecting it to return a new date set to 500 seconds past midnight (or exactly 00:08:20). This json gets passed and processed by a JavaScript function that's expecting a date, however it seems to be interpreting it as a string.. I get an error message similar to:
Type mismatch. Value new Date(new Date('Jan 01 2000').getTime() + 500
* 1000) does not match type date
Running that in the Firebug console produces a perfectly valid date, however. How can I get JavaScript to inerpet my json as a date?
Edit
To provide a little more context I'm sending a series of JSON requests to a JavaScript function that build charts using Google's Visualization API.
JSON is not Javascript, it is just a data serialization format, much like XML.
What you have is actually a string of Javascript code that you need to interpret (or avoid having to interpret, preferably). The only way for that to be valid JSON is, indeed, for it to be a string value. Even then, it should not parse correctly without being inside an array or an object property.
You should refactor whatever's returning that Javascript code to instead return just 'Jan 01 2000', and then do that processing in Ruby. Or however it would be best refactored; it's hard to tell without more context.
Related
I have saved a datetime value created by Luxon into a postgres database column, of type TIMESTAMP(3). I want to then use that value, convert it into other time zones, etc. However, I can't seem to figure out how to "use" it.
I created the object using the following
const { DateTime } = require("luxon");
const myDate = DateTime.now().toUTC().toISO()
I then inserted it into a postgres database, into a column of type TIMESTAMP(3).
I extract it out of the database using a query. When I log it, it says its value is:
console.log(extracted_date); //=> "2021-12-27T09:57:16.184Z"
console.log(typeof extracted_date); //=> object
// The following return "unparsable" or undefined objects
DateTime.fromISO(extracted_date);
DateTime.fromObject(extracted_date);
I can find plenty of tutorials about how to insert dates into sql, but nothing on how to take that date object and actually do something with it. I want to, for instance, convert its time zone.
To use that date object you can initiate a new Date, like so:
console.log(extracted_date); //=> "2021-12-27T09:57:16.184Z"
const javascriptDate = new Date(extracted_date);
Than you can use it directly or with the luxon library.
console.log(javascriptDate.toGMTString()); // => "Mon, 27 Dec 2021 09:57:16 GMT"
console.log(javascriptDate.toISOString()); // => "2021-12-27T09:57:16.184Z"
console.log(javascriptDate.valueOf()); // => 1640599036184
This object core is actually, a value that represents milliseconds since 1 January 1970 UTC, and added to that are time and string parsing functions, generally speaking.
More Info
In some systems dates are store in the database as the value -
date.valueOf() - which make it clearer (for a developer) you have to manipulate it, and perhaps reduce problems of showing the wrong timestamp to users. In the other hand - you lose the readability. Another opion is using only UTC time in your system and convert the timestamp on client side or before presenting the data. The use of UTC will make sure all of your dates will have same language'.
If you want to read more about timestamp,
here are some references:
UTC vs ISO format for time
What is the "right" JSON date format?
I have already tried out this question but it didn't solve my question.
I have a PHP server which sends a date via JSON to the user where it is then processed by Javascript:
PHP: 'date' => date('D M d Y H:i:s O', strtotime($array['Time']))
Javascript var time = new Date(data.date).toLocaleString()
But instead of getting 18. January 2015 ..., I get 3. March 5877521 -596:-31:-23 GMT+0:53:28. What is wrong there?
Some things you might need to know: The server has the central european timezone as well as the date sent. I am trying (above is only an example) to internationalize the date with javascript.
Why pass a string? JS's date constructor will accept a timestamp:
var time = new Date(<?php echo strtotime($array['Time']) ?>000);
Note the 000 in there. JS uses milliseconds, while strtotime returns in seconds, so effectively you'd be building:
var time = new Date(12345678000);
^^^^^^^^---seconds from php
^^^---instant conversion to milliseconds.
I had to parse the timestamp as in Marc B's answer into an int (why ever?):
I solved it now: new Date(parseInt(data.date)) works
First, note that this error is quite common on the web, common enough that it's not [just] a "you" problem.
The reason for the weird March date millions of years in the future seems to be a bug in specific JavaScript engines. I noticed the same date appeared when some tests of ours were run in Chutzpah, a Jasmine test runner for Windows, when our test had an invalid date cast to a locale string and we ran only on its embedded setup from the command line (aka, not in a separate browser).
For our case, it turns out it was PhantomJS that was causing the issue. (PhantomJS used WebKit as its engine. I'd imagine your issue was from an engine with a similar lineage.)
Here's a minimal example that causes the error:
in a file called phantonTest.js
console.log(new Date('').toLocaleString('en-us', { timeZoneName: 'short' }));
phantom.exit();
then execute it...
>phantomjs.exe phantomTest.js
March 3, 5877521 at -8:-31:-23 GMT-4:56:02
You get a slightly date, but are performing a similar operation. You likely have an invalid date coming from strtotime($array['Time']) and the user a similar browser engine. QED, etc.
My Rails application returns JSON object with two Time attributes as a String but Firefox doesn't parse them correctly to Date objects.
A sample JSON object:
{
from: '/Date(2014-11-14 11:26:00)/',
to: '/Date(2014-11-15 12:00:00)/',
...
}
The JSON objects are created with the following Ruby method:
def create_json
{
from: '/Date(' + (self.starts_at.to_s) + ')/',
to: '/Date(' + (self.ends_at.to_s) + ')/',
...
}
In order to parse the JSON object, a regex extracts the argument from the string value and passes it as a string or a numeric value to the Date constructor and tries to instantiate two new Date objects:
var from = new Date('2014-11-14 11:26:00')
var to = new Date('2014-11-15 12:00:00')
This works in Chrome but fails in Firefox.
I tested a couple of Ruby (on Rails) methods to find out which works best to instantiate new Date objects in JavaScript. The results are:
Ruby Class Time .to_s (Link):
The output of this method works in Google Chrome but doesn't work in Firefox.
Rails .to_formatted_s(:rfc822) (Link):
The output of this method works in Google Chrome and works limited in Firefox.
It didn't work for me in Firefox when I was trying to parse dateStrings that were using German day abbreviations (e.g. 'Do, 13 Nov 2014 ...' instead of 'Thu, 13 Nov 2014 ...')
Ruby Class Time .to_i.to_s (Link)
The output of this method doesn't work in Google Chrome and doesn't work in Firefox either because it returns seconds instead of milliseconds since the Epoch.
converted Ruby class Time (... .to_i * 1000).to_s:
The output of this method works in Google Chrome and in Firefox - finally ;-).
Hope this saves you some pain!
I'm building a Windows 8 Metro app (aka "Modern UI Style" or "Windows Store app") in HTML5/JavaScript consuming JSON Web Services and I'm bumping into the following issue: in which format should my JSON Web Services serialize dates for the Windows 8 Metro JSON.parse method to deserialize those in a date type?
I tried:
sending dates using the ISO-8601 format, (JSON.parse returns a string),
sending dates such as "/Date(1198908717056)/" as explained here (same result).
I'm starting to doubt that Windows 8's JSON.parse method supports dates as even when parsing the output of its own JSON.stringify method does not return a date type.
Example:
var d = new Date(); // => a new date
var str = JSON.stringify(d); // str is a string => "\"2012-07-10T14:44:00.000Z\""
var date2 = JSON.parse(str); // date2 is a string => "2012-07-10T14:44:00.000Z"
Here's how I got this working in a generic way (though it I'd rather find a format supported out-of-the-box by Windows 8's JSON.parse method):
On the server, I'm serializing my strings using:
date1.ToString("s");
This uses the ISO 8601 date format which is always the same, regardless of the culture used or the format provider supplied (see here for more information).
On the client-side, I specified a "reviver" callback to JSON.parse which looks for dates using a regexp and converts them into a date object automatically.
In the end, the deserialized object will contain actual JavaScript date types and not strings.
Here's a code sample:
var responseResult = JSON.parse(request.responseText, function dateReviver(key, value) {
if (typeof value === 'string') {
var re = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)$/
var result = re.exec(value);
if (result) {
return new Date(Date.UTC(+result[1], +result[2] - 1, +result[3], +result[4],+result[5], +result[6]));
}
});
Hope this helps,
Carl
This is not something that's unique to Windows 8's JSON.parse – it's the by-design behavior of the ECMA standard JSON parser. Therefore, there is (and can be) no "out-of-the-box support" for dates.
Per spec, JSON values can only be a String, Number, Boolean, Array, Object, or null. Dates are not supported. (IMO, this is an oversight on the part of the spec, but it's what we have to live with.)
Since there is no date type, your app has to work out how to handle dates on its own. The best way to handle this is to send dates as ISO 8601 strings (yyyy-MM-dd'T'HH:mm:ss'Z') or as milliseconds since the epoch (Jan 1 1970 00:00:00 UTC). The important part here is to make sure time is in UTC.
If performance is important, I would not use a reviver callback with JSON.parse. I did a lot of testing, and the overhead involved with invoking a function for every single property in your object cuts performance in half.
On the other hand, I was honestly surprised with how well testing a regex against every string value stood up against only parsing known property names. Just make sure you define the regex once, outside the loop!
Obviously, the absolute fastest ways to turn JSON values into Dates is if you know exactly what properties need to be parsed for dates. However, given the surprisingly good performance of the regex-based search methods, I don't think it's worth the extra complexity unless you really need the extra performance.
A note on using ISO strings vs milliseconds since epoch: tested independently, milliseconds wins. In IE, there's no difference, but Firefox really seems to struggle with ISO strings. Also note that the Date constructor takes milliseconds in all browsers. It also takes a the ISO string, but not in IE ≤ 8.
i made this code for inserting data to an system mail that know to work with xml file.
the problem is that i try to create some javascript code for getting the current date of day, and then put it inside the filed date, but without success.
i know hot create the date in javascript, my problem is in thx xml file, i mean
how can i impplemt the date inside the filed date in the xml file.
the code(xml side):
123456
NOW
COMPLETE
ENGLISH
1274
liran
**
413
3280
86308
;
UNIX
email;dateofday
liroy7#gmail.com;(i want here to return the date from the javascript)
thanks,
I'm not sure I understand, but you can use getTime() on your Date objec to insert it into the XML file as milliseconds, and if you need to convert it back into a JavaScript object you can parse it directly.
function putInXmlFile(d) {
writeToXML(d.getTime());
}
function getFromXmlFile() {
var date = new Date(getFromXML());
}
It works because the JavaScript Date object can parse from the milliseconds from the epoch (which is returned by getTime).