Passing value into methods by dot prefixes - javascript

What I want to do should be incredibly simple but I suppose I'm not understanding the basic concepts and causing me more confusion than I'd like to admit.
I want to pass a value into a function by "chaining" it instead of passing the value as an argument.
I want to be able to do this:
var formattedDate = myDate.convertTime()
Instead of:
var formattedDate = convertTime(myDate);
In my search I've come across many examples of how to use call functions inside objects, but they always start with declaring a new object and calling the function inside that object that simply updates predefined variables like age, name, or location as in new Obj(name, age) which doesn't seem to be what I am looking for when applied to my situation. I'd really appreciate some guidance in the right direction.

Are you looking for something like following
String.prototype.myFunction = function() {
return this.toUpperCase();
}
var text = "sample text";
console.log(text.myFunction()); // calling user defined function
Fiddle: https://jsfiddle.net/mna7jxrs/
Update 1:
For example, We're passing a date string to convertTime() and it is converting it to UTC String
Date.prototype.convertTime = function() {
return this.toUTCString();
}
var date = new Date();
console.log(date); // Mon Oct 31 2016 11:56:57 GMT+0530 (India Standard Time)
console.log(date.convertTime()); // Mon, 31 Oct 2016 06:26:57 GMT
Fiddle: https://jsfiddle.net/doc7gL2g/

What you want to do is add a method to your object myDate.
Lets assume myDate is a date created by var myDate = new Date();.
If you want to add it only to the current object, you can do this way:
var myDate=new Date();
myDate.convertTime = function() {
console.log("I’m working on", this);
};
myDate.convertTime(); // -> see console
Now to make it more generic, you want to do something we call monkey patching:
Date.prototype.convertTime = function() {
console.log("I’m working on", this);
};
var myDate = new Date();
myDate.convertTime(); // -> see console
var myOtherDate = new Date();
myOtherDate.convertTime(); // -> see console
A working pen for the monkey patch: http://codepen.io/BuonOmo/pen/RGzYmz?editors=0012

Related

Using alert with object date

I'm learning JavaScript and I'm trying to figure out object date. Specifically toLocaleDateString method.
I've come across two different basic examples of it. The first one is:
var d = new Date();
var n = d.toLocaleDateString();
alert(d);
And the second one is:
var myDate = new Date();
alert(myDate.toLocaleDateString());
Both work fine, but they give different date formats. First one gives: Mon Jul 16 2018 18:34:00 GMT+0200 (Central European Summer Time), while the second one is just 7/16/2018. And I can't see why? What am I missing here?
Thanks!
small error, in the first example you should be alerting n instead of d
var d = new Date();
var n = d.toLocaleDateString();
alert(n);
d is the date object while n is the date string. you are getting different date formats because you are alerting a date object in the first example and a date string in the second
This is simply because you are not alerting the modified date string (which is n) in the first alert:
var d = new Date();
var n = d.toLocaleDateString();
alert(n);
var myDate = new Date();
alert(myDate.toLocaleDateString());
You're printing the wrong variable in the first block. When you declare a variable with the reserved word var in the second line you're storing there the formatted date that you want to output, so you can just alert(n) or you can avoid declaring the var:
var d = new Date();
d.toLocaleDateString();
alert(d);

Property date to String for parsing

I'm trying to insert creation date into table view in specific format.
Now it's like DD/MM/YYYY HH:MM:ss and I want it like DD/MM/YYYY.
YAHOO.Bubbling.fire("registerRenderer", {
propertyName: "test:date",
renderer: function functionPrice(record, label){
var jsNode = record.jsNode,
properties = jsNode.properties;
var rawDate = properties['test:date'];
var date= rawDate().toString().substring(0, 11);
return '<div id="attachments">' + date + '</div>';
}
});
In this case, column contains [Object obj.
I also tried convert it to toISOString but it returns Invalid Date.
Column is set like d:date but output is d:datetime and I don't know why.
Thank you.
If your date format is fixed, this is a safe way to create a Date instance:
var value = "31/12/2017 00:00:00";
var dd = value.substring(0,2);
var mm = value.substring(3,5);
var yyyy = value.substring(6,10);
var d = new Date(yyyy, mm - 1, dd); // Sun Dec 31 2017 00:00:00 GMT+0800 (+08)
To change dates the dates displayed in the date picker control, but this file may not exist in your environment. See if the following file exists:
<alfresco home>\tomcat\shared\classes\alfresco\web-extension\site-webscripts\org\alfresco\components\form\form.get_en.properties
If it doesn’t exist, copy it from here (create the form folder if necessary):
<alfresco home>\tomcat\webapps\share\WEB-INF\classes\alfresco\site-webscripts\org\alfresco\components\form\form.get_en.properties
Open the form.get_en.properties file for editing. Search for “form-control.date-picker” to find the proper properties to change (we found four values on a recent installation).
Restart Alfresco to make the changes take effect.

Why is this function behaving weirdly

I have the following JavaScript as below
function getExpiryDate(contract) {
var expiryDay;
var contractType;
var today = new moment();
var today1 = new moment();
var x = myFunction(4, 3);
var abc =3;
var xyz= 4;
var c = myFunction(abc, xyz);
console.log("abc is: "+abc);
console.log("xyz is: "+xyz);
console.log(today1);
expiryDay = getlastDayofMonth('Thursday',today1);
console.log(today1); /* Why has the value of today changed? */
}
function getlastDayofMonth(dayName,date1) {
var endDate = date1.endOf('month');
var lastDayOfMonth = endDate.format('dddd');
var weekDayToFind = moment().day(dayName).weekday(); //change to searched day name
var searchDate = endDate; //now or change to any date
while (searchDate.weekday() !== weekDayToFind)
{
searchDate.subtract(1, 'days');
}
return searchDate;
}
function myFunction(a, b) {
return a * b; // Function returns the product of a and b
}
When I execute I get the following output.
expirydate.js:11 abc is: 3
expirydate.js:12 xyz is: 4
expirydate.js:13 Moment { _d: Wed Aug 31 2016 10:21:04 GMT+0530 }
expirydate.js:15 Moment { _d: Thu Aug 25 2016 23:59:59 GMT+0530 }
I am totally confused on why the value of today1 changes when it is used in the function.
Because in JS, objects are passing by reference and not by value. It means you are working on the same object.
To prevent this you have to clone date1 value in the function into a variable with a scope restricted to the function
This is happening because Moment is written in a mutable style of code. It's fairly surprising behavior. After reading through your code a few times I couldn't find any obvious problem until I looked at the Moment documentation.
The .endOf() method mutates the date, aka changes the date of the moment object you call it on:
Mutates the original moment by setting it to the end of a unit of time.
So when you call that method here:
var endDate = date1.endOf('month');
It's mutating date1, meaning it modifies date1 in place and changes its time. In fact, it looks like almost all of moment's methods mutate the moment object. There's a discussion on Github about why the API is designed poorly.
In terms of solving your specific problem, it's a personal style preference. I think it's undesirable to force the user to clone an object before passing it to a function. So I would clone the moment passed in inside the function:
function getlastDayofMonth(dayName,date1) {
var endDate = date1.clone().endOf('month');

How to JSON stringify a javascript Date and preserve timezone

I have a date object that's created by the user, with the timezone filled in by the browser, like so:
var date = new Date(2011, 05, 07, 04, 0, 0);
> Tue Jun 07 2011 04:00:00 GMT+1000 (E. Australia Standard Time)
When I stringify it, though, the timezone goes bye-bye
JSON.stringify(date);
> "2011-06-06T18:00:00.000Z"
The best way I can get a ISO8601 string while preserving the browser's timezone is by using moment.js and using moment.format(), but of course that won't work if I'm serializing a whole command via something that uses JSON.stringify internally (in this case, AngularJS)
var command = { time: date, contents: 'foo' };
$http.post('/Notes/Add', command);
For completeness, my domain does need both the local time and the offset.
Assuming you have some kind of object that contains a Date:
var o = { d : new Date() };
You can override the toJSON function of the Date prototype. Here I use moment.js to create a moment object from the date, then use moment's format function without parameters, which emits the ISO8601 extended format including the offset.
Date.prototype.toJSON = function(){ return moment(this).format(); }
Now when you serialize the object, it will use the date format you asked for:
var json = JSON.stringify(o); // '{"d":"2015-06-28T13:51:13-07:00"}'
Of course, that will affect all Date objects. If you want to change the behavior of only the specific date object, you can override just that particular object's toJSON function, like this:
o.d.toJSON = function(){ return moment(this).format(); }
I'd always be inclined to not mess with functions in the prototype of system objects like the date, you never know when that's going to bite you in some unexpected way later on in your code.
Instead, the JSON.stringify method accepts a "replacer" function (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The_replacer_parameter) which you can supply, allowing you to override the innards of how JSON.stringify performs its "stringification"; so you could do something like this;
var replacer = function(key, value) {
if (this[key] instanceof Date) {
return this[key].toUTCString();
}
return value;
}
console.log(JSON.stringify(new Date(), replacer));
console.log(JSON.stringify({ myProperty: new Date()}, replacer));
console.log(JSON.stringify({ myProperty: new Date(), notADate: "I'm really not", trueOrFalse: true}, replacer));
Based on Matt Johnsons 's answer, I re-implemented toJSON without having to depend on moment (which I think is a splendid library, but a dependency in such a low level method like toJSON bothers me).
Date.prototype.toJSON = function () {
var timezoneOffsetInHours = -(this.getTimezoneOffset() / 60); //UTC minus local time
var sign = timezoneOffsetInHours >= 0 ? '+' : '-';
var leadingZero = (Math.abs(timezoneOffsetInHours) < 10) ? '0' : '';
//It's a bit unfortunate that we need to construct a new Date instance
//(we don't want _this_ Date instance to be modified)
var correctedDate = new Date(this.getFullYear(), this.getMonth(),
this.getDate(), this.getHours(), this.getMinutes(), this.getSeconds(),
this.getMilliseconds());
correctedDate.setHours(this.getHours() + timezoneOffsetInHours);
var iso = correctedDate.toISOString().replace('Z', '');
return iso + sign + leadingZero + Math.abs(timezoneOffsetInHours).toString() + ':00';
}
The setHours method will adjust other parts of the date object when the provided value would "overflow". From MDN:
If a parameter you specify is outside of the expected range, setHours() attempts to update the date information in the Date object accordingly. For example, if you use 100 for secondsValue, the minutes will be incremented by 1 (minutesValue + 1), and 40 will be used for seconds.
When I stringify it, though, the timezone goes bye-bye
That’s because Tue Jun 07 2011 04:00:00 GMT+1000 (E. Australia Standard Time) is actually the result of the toString method of the Date object, whereas stringify seems to call the toISOString method instead.
So if the toString format is what you want, then simply stringify that:
JSON.stringify(date.toString());
Or, since you want to stringify your “command” later on, put that value in there in the first place:
var command = { time: date.toString(), contents: 'foo' };
If you have a JS Date Object and want to stringify it to preserve the timezone, then you should definitely use toLocaleDateString().
It is a very powerful helper function that can help you format your Date object in every way possible.
For example, if you want to print "Friday, February 1, 2019, Pacific Standard Time",
const formatDate = (dateObject : Date) => {
const options: any = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
timeZoneName: 'long'
};
return dateObject.toLocaleDateString('en-CA', options);
};
Thus, by modifying the options object, you can achieve different styles of formatting for your Date Object.
For more information regarding the ways of formatting, refer to this Medium article: https://medium.com/swlh/use-tolocaledatestring-to-format-javascript-dates-2959108ea020
let date = new Date(JSON.parse(JSON.stringify(new Date(2011, 05, 07, 04, 0, 0))));
I've created a small library that preserves the timezone with ISO8601 string after JSON.stringify. The library lets you easily alter the behavior of the native Date.prototype.toJSON method.
npm: https://www.npmjs.com/package/lbdate
Example:
lbDate().init();
const myObj = {
date: new Date(),
};
const myStringObj = JSON.stringify(myObj);
console.log(myStringObj);
// {"date":"2020-04-01T03:00:00.000+03:00"}
The library also gives you options to customize the serialization result if necessary.

Google Form on Submit get values and format the time

I am using Google Apps Script with a Google form. When the user submits the Google Form I get a value from a question. I then take that value and make it a date object, from what I saw on this post about daylight savings I use that to determine the timezone. I run the date object through Utilities.formatDate and want to get the correctly formatted date.
example: 9:00 AM
But instead I am getting a completely different time than expected.
My question is: Can someone help me understand why the below code is outputting a time that is 3 hours different?
function onSubmit(e) {
var values = e.values;
Logger.log(values);
try {
var start1 = new Date(values[3]);
var startN = new Date(start1).toString().substr(25,6)+"00";
var startT = Utilities.formatDate(start1, startN, "h:mm a");
Logger.log(startT);
} catch(error) {
Logger.log(error);
}
}
The assumption that Utilities formatDate does not support GMT... parameter is not true.
The post you mentioned in reference is used to get calendar events and is a useful way to get the right value when you get events from another daylight saving period (getting the TZ info from the calendar event itself), for example events for next month will be in "summer time" while we are still in "winter time"...
Your issue might come from different sources depending on time zone settings of your script vs timezone of the source. Could you describe the exact configuration in which you use this script ?
In the mean time, here is a small code that demonstrates how the code is working + the logger results :
function testOnSubmit() {
var eventInfo = {};
var values = {};
values['3'] = new Date();
eventInfo['values'] = values;
Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n\n');
onSubmit(eventInfo);
}
function onSubmit(e) {
var values = e.values;
try {
var start1 = new Date(values[3]);
Logger.log('onSubmit log results : \n');
Logger.log('start1 = '+start1)
var startN = new Date(start1).toString().substr(25,6)+"00";
Logger.log('startN = '+startN);
var startT = Utilities.formatDate(start1, startN, "h:mm a");
Logger.log('result in timeZone = '+startT);
} catch(error) {
Logger.log(error);
}
}
EDIT : additionally, about the 30 and 45' offset, this can easily be solved by changing the substring length like this :
var startN = new Date(start1).toString().substr(25,8);
the result is the same, I had to use the other version a couple of years ago because Google changed the Utilities.formatDate method at some moment (issue 2204) but this has been fixed.
EDIT 2 : on the same subject, both methods actually return the same result, the GMT string has only the advantage that you don't have to know the exact timezone name... there is also the Session.getScriptTimeZone() method. Below is a demo script that shows the resulst for 2 dates in January and July along with the log results :
function testOnSubmit() {
var eventInfo = {};
var values = {};
values['3'] = new Date(2014,0,1,8,0,0,0);
eventInfo['values'] = values;
Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n\n');
onSubmit(eventInfo);
values['3'] = new Date(2014,6,1,8,0,0,0);
eventInfo['values'] = values;
Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n');
onSubmit(eventInfo);
}
function onSubmit(e) {
var values = e.values;
var start1 = new Date(values[3]);
Logger.log('onSubmit log results : ');
Logger.log('start1 = '+start1)
var startN = new Date(start1).toString().substr(25,8);
Logger.log('startN = '+startN);
Logger.log('result in timeZone using GMT string = '+Utilities.formatDate(start1, startN, "MMM,d h:mm a"));
Logger.log('result in timeZone using Joda.org string = '+Utilities.formatDate(start1, 'Europe/Brussels', "MMM,d h:mm a"));
Logger.log('result in timeZone using Session.getScriptTimeZone() = '+Utilities.formatDate(start1, Session.getScriptTimeZone(), "MMM,d h:mm a")+'\n');
}
Note also that the Logger has its own way to show the date object value ! it uses ISO 8601 time format which is UTC value.
Try this instead:
var timeZone = Session.getScriptTimeZone();
var startT = Utilities.formatDate(start1, timeZone, "h:mm a");
The Utilities.formatDate function expects a time zone that is a valid IANA time zone (such as America/Los_Angeles), not a GMT offset like GMT+0700.
I am making the assumption that Session.getScriptTimeZone() returns the appropriate zone. If not, then you might need to hard-code a specific zone, or use a different function to determine it.
Additionally, the +"00" in the script you had was assuming that all time zones use whole-hour offsets. In reality, there are several that have 30-minute or 45-minute offsets.

Categories

Resources