Date difference in javascript / jQuery - javascript

I am querying facebook graph api. It returns date in following format: 2012-01-23T23:52:29+0000.
I need to find difference of dates of this type in javascript. It's not a valid date in javascript ( by Date.parse() or new Date() )
I am thinking of replacing 'T' with ' ' (a space), '-' with '/' and '+0000' with '' (empty string). Is this the only way? Or am I missing something here?
Also, if this is the only way, can someone give me a regex to replace all in one go?
Execution speed is my main concern.

I'd say yes to replacing - with /, since that's that the ISO-whatever standard dictates (Facebook likes to screw things around, like <meta> tags with property attributes instead of name like they should be).
Keep the timezone part, since JS understands that and will handle it accordingly.
Overall, you want new Date(input.replace(/-/g,'/'));.
In response to comments, a better (more complete) solution would be:
new Date(input.replace(/-/g,'/').replace("T"," ").replace(/\+[0-9]+$/,''));

Related

jQuery / Javascript substitution 'Syntax error, unrecognized expression'

I am implementing jQuery chaining - using Mika Tuupola's Chained plugin - in my rails project (using nested form_for partials) and need to dynamically change the chaining attribute:
The code that works without substitution:
$(".employee_title_2").remoteChained({
parents : ".employee_title_1",
url : "titles/employee_title_2",
loading : "Loading...",
clear : true
});
The attributes being substituted are .employee_title_1 and .employee_title_2:
var t2 = new Date().getTime();
var A1 = ".employee_title_1A_" + t2;
var B2 = ".employee_title_2B_" + t2;
In ruby speak, I'm namespacing the variables by adding datetime.
Here's the code I'm using for on-the-fly substitution:
$(`"${B2}"`).remoteChained({
parents : `"${A1}"`,
url : "titles/employee_title_2",
loading : "Loading...",
clear : true
});
Which throws this error:
Uncaught Error: Syntax error, unrecognized expression:
".employee_title_2B_1462463848339"
The issue appears to be the leading '.' How do I escape it, assuming that's the issue? Researching the error message Syntax error, unrecognized expression lead to SO question #14347611 - which suggests "a string is only considered to be HTML if it starts with a less-than ('<) character" Unfortunately, I don't understand how to implement the solution. My javascript skills are weak!
Incidentally, while new Date().getTime(); isn't in date format, it works for my purpose, i.e., it increments as new nested form fields are added to the page
Thanks in advance for your assistance.
$(`"${B2b}"`).remoteChained({
// ^ ^
// These quotes should not be here
As it is evaluated to a string containing something like:
".my_class"
and to tie it together:
$('".my_class"')...
Same goes for the other place you use backtick notation. In your case you could simply use:
$(B2).remoteChained({
parents : A1,
url : "titles/employee_title_2",
loading : "Loading...",
clear : true
});
The back tick (``) syntax is new for Javascript, and provides a templating feature, similar to the way that Ruby provides interpolated strings. For instance, this Javascript code:
var who = "men";
var what = "country";
var famous_quote = `Now is the time for all good ${who} to come to the aid of their #{what}`;
is interpolated in exactly the same way as this Ruby code:
who = "men"
what = "country"
famous_quote = "Now is the time for all good #{who} to come to the aid of their #{what}"
In both cases, the quote ends up reading, "Now is the time for all good men to come to the aid of their country". Similar feature, slightly different syntax.
Moving on to jQuery selectors, you have some flexibility in how you specify them. For instance, this code:
$(".my_class").show();
is functionally equivalent to this code:
var my_class_name = ".my_class";
$(my_class_name).show();
This is a great thing, because that means that you can store the name of jQuery selectors in variables and use them instead of requiring string literals. You can also build them from components, as you will find in this example:
var mine_or_yours = (user_selection == "me") ? "my" : "your";
var my_class_name = "." + mine_or_yours + "_class";
$(my_class_name).show();
This is essentially the behavior that you're trying to get working. Using the two features together (interpolation and dynamic jQuery selectors), you have this:
$(`"${B2}"`).remote_chained(...);
which produces this code through string interpolation:
$("\".employee_title_2B_1462463848339\"").remote_chained(...);
which is not correct. and is actually the cause of the error message from jQuery, because of the embedded double quotes in the value of the string. jQuery is specifically complaining about the extra double quotes surrounding the value that you're passing to the selector.
What you actually want is the equivalent of this:
$(".employee_title_2B_1462463848339").remote_chained(...);
which could either be written this way:
$(`${B2}`).remote_chained(...);
or, much more simply and portably, like so:
$(B2).remote_chained(...);
Try this little sample code to prove the equivalence it to yourself:
if (`${B2}` == B2) {
alert("The world continues to spin on its axis...");
} else if (`"${B2}"` == B2) {
alert("Lucy, you've got some 'splain' to do!");
} else {
alert("Well, back to the drawing board...");
}
So, we've established the equivalency of interpolation to the original strings. We've also established the equivalency of literal jQuery selectors to dynamic selectors. Now, it's time to put the techniques together in the original code context.
Try this instead of the interpolation version:
$(B2).remoteChained({
parents : A1,
url : "titles/employee_title_2",
loading : "Loading...",
clear : true
});
We already know that $(B2) is a perfectly acceptable dynamic jQuery selector, so that works. The value passed to the parents key in the remoteChained hash simply requires a string, and A1 already fits the bill, so there's no need to introduce interpolation in that case, either.
Realistically, nothing about this issue is related to Chained; it just happens to be included in the statement that's failing. So, that means that you can easily isolate the failing code (building and using the jQuery selectors), which makes it far easier to debug.
Note that the Javascript syntax was codified just last year with ECMAScript version 6, so the support for it is still a mixed bag. Check your browser support to make sure that you can use it reliably.

How to create a datetime object in javascript when using javascript remoteTK/remote toolkit

I am new to salesforce and I know my question sounds silly. But I need someone to tell me the direction I should go.
My question is how can I convert string or object like this
{Start_time__C:"2014-07-24T20:55:00.000+0000"}
and this
{perDiem: true}
into salesforce object. And then I can use create function in remoteTK.
I am currently building custom app on salesforce1. In my visualforce page, I need to create new record, which has datetime, and boolean as its fields.
Thank you in advance!
I don't know much about the remoteTK but before you deep dive into it you might want to look into the "Remote Objects" from Spring'14. This seems to be the new hip / official way of doing remoting (which doesn't mean I'm saying rTK is bad!) and slightly easier to use.
https://salesforce.stackexchange.com/questions/33072/visualforce-remote-objects
https://developer.salesforce.com/blogs/developer-relations/2014/03/spring-14-using-visualforce-remote-objects-with-canjs.html
http://andyinthecloud.com/2014/01/22/spring14-visualforce-remote-objects-introduction/
http://www.salesforce.com/us/developer/docs/pages/Content/pages_remote_objects_example_extended.htm
The main difference between them seems to be that you could use rTK in a non-visualforce page as underneath it just relies on REST callouts. The remote objects use a special VF tag so it's VF-only.
In the end I think it won't matter much which library you'll use. Sample remote object code:
// Create work order line item
var workOrderLineItem = new SObjectModel.WorkOrderLineItem__c();
workOrderLineItem.set('Description__c', 'Answering the question');
workOrderLineItem.set('Hours__c', answer);
workOrderLineItem.set('WorkOrder__c', result[0]);
workOrderLineItem.create(function(error, result, event)
{
// Errors?
if(error!=null)
alert(error);
else
alert('Success');
});
vs. the sample from remoteTK:
var objectType = 'Account';
var fields = {'Name': 'salesforce.com', 'Description':'CRM'};
client.create(objectType , fields,
function(response) {
getAccounts(function() {
$j.mobile.pageLoading(true);
$j.mobile.changePage('#mainpage', "slide", true, true);
});
}, errorCallback);
So a JavaScript object with fields is being created in both cases. For Booleans you should be good sending 'true' or 'false' strings.
For dates you might have to experiment a bit. Generally I've been passing Unix timestamp (miliseconds since Jan 1 1970), this seemed to work OK for me in REST calls or Visualforce Remoting (by which I mean #RemoteAction stuff, yet another tool).
The RemoteTKController.writeFields() seems to be using Date.valueOf(someString) when casting. This means the format should be 'yyyy-MM-dd HH:mm:ss' which is close enough - check if it will work out of the box and remove the timezone part from your string if it causes problems? You could simplify your examples a lot by skipping the remote part and directly check in Developer Console or Execute Anonymous how the parser reacts to different dates you'll feed it.
There's another function that seems to use REST API instead of the controller. This one will just pass the payload to REST API's POST request. Looking at how it's built you should be fine just passing a real JavaScript Date object as value, the JSON.stringify call should figure out how to serialize that. If you really want to craft the string yourself - check the REST API guide. The dates should look like that and all remoteTK'create call does is make a request similar to this one
This is an old thread, but in case it helps someone I was able to get this working. The yyyy-MM-dd HH:mm:ss format was very close. All it needed was a 'T' between the date and time to be acceptable. From there is was just making sure that all components came through as two digits, and converting the date to UTC time. Here's my final Javascript function:
function ConvertDate(dtin){
var d = new Date(dtin);
var convertdate = d.getUTCFullYear() + '-' + ('0' + (d.getUTCMonth()+1)).slice(-2) + '-' + ('0' + d.getUTCDate()).slice(-2) +'T' + ('0' + d.getUTCHours()).slice(-2)+':'+('0' + d.getUTCMinutes()).slice(-2)+':'+d.getUTCSeconds()+'0';
return convertdate;
}
From there I could pass the converted date to the sObject function without error.

Can something help me to see how to deal with single quote escaping in the following scenario

We write js programs for clients which allow them to craft the display text. Here is what we did
We have a raw js file which replaced those strings with tokens, for example
month = [_MonthToken_];
name = '_NameToken_';
and have a xml file to allow user to specify the text like
<xml>
<token name="MonthToken">'Jan','Feb','March'</token>
<token name="NameToken">Alice</token>
</xml>
and have a generator to replace the token with the text and generate the final js file.
month = ['Jan','Feb','March'];
name = 'Alice';
However, I found there is a bug in this scenario. When somebody specifies the name to be "D'Angelo" (for example.) the js will run into a error because the name variable will become
name='D'Angelo'
We have thought of several ways to fix the problem but none of which are perfect.
We may ask our clients to escape the characters, may it seems not appropriate given that they may not know js and there are more cases to escape (", ), which could make them unhappy :|
We also think of changing the generator to escape ', but sometimes the text may be replacing an array, the single quote there should not be escaped. (there are other cases, we may detect it case by case, but it is tedious)
We may have done something wrong for the whole scenario/architecture. but we don't want to change that unless we have confirmed that it is definitely necessary.
So, is there any solution? I will look into every ideas. Thank you in advanced!
(I may also need a better title :P)
I think your xml schema is poor designed, and this is the root cause of your problems.
Basically, you are forcing the author of the xml to put Javascript code inside of the name="MonthToken" element, while you pretend that she can do this without Javascript syntax knowledgement. I guess that you are planning to use eval on the parsed element content to build month and name variables.
The problem you discovered it's not the only one: you also are subject to Javascript code injection: what if a user forge an element such as:
<token name="MonthToken">alert('put some evil instruction here')</token>
I would suggest to change the xml schema in this way:
<xml>
<token name="MonthToken">Jan</token>
<token name="MonthToken">Feb</token>
<token name="MonthToken">March</token>
<token name="NameToken">Alice</token>
</xml>
Then in your generator, you'll have to parse each MonthToken element content, and add it to the month array. Do the same for the name variable.
In this way:
You don't use eval, and so you have no possibility of code injection
Your user doesn't no more have to know how to quote month names
You automatically handle quotes or apostrophe in names, because you are not using them as js code.
If you want month variable to become a string when user enter just a month, then simply transform the variable: with something similar to this:
if (month.length == 1) {
month = month[0];
}

JSON Date without eval?

Short description:
Is there a javascript JSON-converter out there that is able to preserve Dates and does not use eval?
Example:
var obj1 = { someInt: 1, someDate: new Date(1388361600000) };
var obj2 = parseJSON(toJSON(obj1));
//obj2.someDate should now be of type Date and not String
//(like in ordinary json-parsers).
Long description:
I think most people working with JSON already had the problem of how to transmit a Date:
var obj = { someInt: 1, someDate: new Date(1388361600000) }
When converting this to JSON and back, the date suddenly became a String:
JSON.parse(JSON.stringify(obj))
== { someInt: 1, someDate: "2013-12-30T00:00:00.000Z" }
This is a huge disadvantage since you cannot easily submit a Date using JSON. There is always some post-processing necessary (and you need to know where to look for the dates).
Then Microsoft found a loophole in the specification of JSON and - by convention - encodes a date as follows:
{"someInt":1,"someDate":"\/Date(1388361600000)\/"}
The brilliance in this is that there is a now a definitive way to tell a String from a Date inside a valid JSON-string: An encoded String will never contain the substring #"/" (a backslash followed by a slash, not to be confused with an escaped slash). Thus a parser that knows this convention can now safely create the Date-object.
If a parser does not know this convention, the date will just be parsed to the harmless and readable String "/Date(1388361600000)/".
The huge drawback is that there seems to be no parser that can read this without using eval. Microsoft proposes the following way to read this:
var obj = eval("(" + s.replace(/\"\\\/Date\((\d+)\)\\\/\"/g, function (match, time) { return "new Date(" + time + ")"; }) + ")");
This works like a charm: You never have to care about Dates in JSON anymore. But it uses the very unsafe eval-method.
Do you know any ready-to-use-parser that achieves the same result without using eval?
EDIT
There was some confusion in the comments about the advantages of the tweaked encoding.
I set up a jsFiddle that should make the intentions clear: http://jsfiddle.net/AJheH/
I disagree with adeno's comment that JSON is a notation for strings and cannot represent objects. Json is a notation for compound data types which must be in the form of a serialized objects, albeit that the primitive types can only be integer, float, string or bool. (update: if you've ever had deal with spaghetti coded XML, then you'll appreciate that maybe this is a good thing too!)
Presumably hungarian notation has lost favour with Microsoft if they now think that creating a non-standard notation incorporating the data type to describe a type is better idea.
Of itself 'eval' is not evil - it makes solving some problems a lot easier - but it's very difficult to implement good security while using it. Indeed it's disabled by default with a Content Security Policy.
IMHO it boils down to storing the date as 1388361600000 or "2013-12-30T00:00:00.000Z". IMHO the latter has significantly more semantic value - taken out of context it is clearly a date+time while the latter could be just about anything. Both can be parsed by the ECMAscript Date object without resorting to using eval. Yes this does require code to process the data - but what can you do with an sort of data without parsing it? he only time I can see this as being an advanage is with a schemaless database - but in fairness this is a BIG problem.
The issue is the following line of code, here is an example function and take a look at parseWithDate function, add the script to the page and change the following line to this it will work.
http://www.asp.net/ajaxlibrary/jquery_webforms_serialize_dates_to_json.ashx
var parsed1 = JSON.parse(s1); // changed to below
var parsed1 = JSON.parseWithDate(s1);
Updated jsFiddle that works http://jsfiddle.net/GLb67/1/

Parse ONLY a time string with DateJS

I'm using the excellent (but large) DateJS library to handle dates and times in my webapp. I just came across something that I'm not sure how to handle.
I want my users to be able to enter Time strings only, without a date, but they should be able to enter it in any manner they please. For instance:
5:00 pm
17:00
5:00pm
5:00p
5p
etc.
Using Date.parse(value) converts these strings into a full date, which is exactly what I want. However, it also allows the user to enter any other part of a date string, such as:
sat 5pm
1/1/2010 5pm
etc.
I'm trying to use DateJS to validate an input field for a time value. Something like:
function validateTime(value) {
return Date.parse(value) !== null;
}
Is there a way to use DateJS features to solve this? There are other SO questions that provide solutions, but if DateJS has a way to do this, I don't really want to add more custom code to my app to do this.
Shortly after asking my question, I discovered that Date.parseExact() can take an array of format strings. Somehow I'm missed that. I managed to get something working with the following code:
function validateTime(input) {
return Date.parseExact(input, [
"H:m",
"h:mt",
"h:m t",
"ht","h t"]) != null ||
Date.parseExact(input, [
"h:mtt",
"h:m tt",
"htt","h tt"]) != null;
};
Note that some formats don't seem to be able to be included together at the same time, which is why I split them into two separate parseExact() calls. In this case, I couldn't include any string that contained a single t in it with format strings that contained a double tt in it.
The additive approach seems cumbersome. Takes away the beauty of DateJS in my opinion. I needed the same solution and decided to just sneakily append the date in front of my input string before parsing with DateJS:
var parsed = Date.parse(Date.today().toString('M/d/yyyy') + ' ' + this.value);
if (parsed) {
alert(parsed.toString('h:mm tt'));
}
Now DateJS will not be sniffing around for any of its date-part parsing patterns, as you have already subbed it in.
Hope this helps someone!

Categories