Actionscript 3 Date adds 1 month - actionscript-3

Hi I'm having a problem setting a date in as3
here is the code i'm using
var endDate = new Date(2009,9,10);
trace (endDate);
the trace statement always shows the date as 1 month further on the the date I have added eg
10th Oct 2009 instead of 10th september 2009
Is there a way around this?

The month is 0 index.
var endDate = new Date(2009,9-1,10);

Yeah, dates are zero indexed in AS, so you'll need to subtract one

0 indexed like the other said. Try and take a look at this post for more tips on the date object:
How can you save time by using the built in Date class?

It might be because you are converting strings to numbers.
(Implicit coercion of a value of type String to an unrelated type Number.)
If you just make it:
var day:Number=parseInt("10");
var month:Number=parseInt("9");
var year:Number=parseInt("2009");
var adjMonth =month-1;
var endDate = new Date(year,adjMonth,day);
trace(endDate.toString());
It'll work fine.

Related

Google Script Forcing Date Format [duplicate]

I'm trying to get from a time formatted Cell (hh:mm:ss) the hour value, the values can be bigger 24:00:00 for example 20000:00:00 should give 20000:
Table:
if your read the Value of E1:
var total = sheet.getRange("E1").getValue();
Logger.log(total);
The result is:
Sat Apr 12 07:09:21 GMT+00:09 1902
Now I've tried to convert it to a Date object and get the Unix time stamp of it:
var date = new Date(total);
var milsec = date.getTime();
Logger.log(Utilities.formatString("%11.6f",milsec));
var hours = milsec / 1000 / 60 / 60;
Logger.log(hours)
1374127872020.000000
381702.1866722222
The question is how to get the correct value of 20000 ?
Expanding on what Serge did, I wrote some functions that should be a bit easier to read and take into account timezone differences between the spreadsheet and the script.
function getValueAsSeconds(range) {
var value = range.getValue();
// Get the date value in the spreadsheet's timezone.
var spreadsheetTimezone = range.getSheet().getParent().getSpreadsheetTimeZone();
var dateString = Utilities.formatDate(value, spreadsheetTimezone,
'EEE, d MMM yyyy HH:mm:ss');
var date = new Date(dateString);
// Initialize the date of the epoch.
var epoch = new Date('Dec 30, 1899 00:00:00');
// Calculate the number of milliseconds between the epoch and the value.
var diff = date.getTime() - epoch.getTime();
// Convert the milliseconds to seconds and return.
return Math.round(diff / 1000);
}
function getValueAsMinutes(range) {
return getValueAsSeconds(range) / 60;
}
function getValueAsHours(range) {
return getValueAsMinutes(range) / 60;
}
You can use these functions like so:
var range = SpreadsheetApp.getActiveSheet().getRange('A1');
Logger.log(getValueAsHours(range));
Needless to say, this is a lot of work to get the number of hours from a range. Please star Issue 402 which is a feature request to have the ability to get the literal string value from a cell.
There are two new functions getDisplayValue() and getDisplayValues() that returns the datetime or anything exactly the way it looks to you on a Spreadsheet. Check out the documentation here
The value you see (Sat Apr 12 07:09:21 GMT+00:09 1902) is the equivalent date in Javascript standard time that is 20000 hours later than ref date.
you should simply remove the spreadsheet reference value from your result to get what you want.
This code does the trick :
function getHours(){
var sh = SpreadsheetApp.getActiveSpreadsheet();
var cellValue = sh.getRange('E1').getValue();
var eqDate = new Date(cellValue);// this is the date object corresponding to your cell value in JS standard
Logger.log('Cell Date in JS format '+eqDate)
Logger.log('ref date in JS '+new Date(0,0,0,0,0,0));
var testOnZero = eqDate.getTime();Logger.log('Use this with a cell value = 0 to check the value to use in the next line of code '+testOnZero);
var hours = (eqDate.getTime()+ 2.2091616E12 )/3600000 ; // getTime retrieves the value in milliseconds, 2.2091616E12 is the difference between javascript ref and spreadsheet ref.
Logger.log('Value in hours with offset correction : '+hours); // show result in hours (obtained by dividing by 3600000)
}
note : this code gets only hours , if your going to have minutes and/or seconds then it should be developped to handle that too... let us know if you need it.
EDIT : a word of explanation...
Spreadsheets use a reference date of 12/30/1899 while Javascript is using 01/01/1970, that means there is a difference of 25568 days between both references. All this assuming we use the same time zone in both systems. When we convert a date value in a spreadsheet to a javascript date object the GAS engine automatically adds the difference to keep consistency between dates.
In this case we don't want to know the real date of something but rather an absolute hours value, ie a "duration", so we need to remove the 25568 day offset. This is done using the getTime() method that returns milliseconds counted from the JS reference date, the only thing we have to know is the value in milliseconds of the spreadsheet reference date and substract this value from the actual date object. Then a bit of maths to get hours instead of milliseconds and we're done.
I know this seems a bit complicated and I'm not sure my attempt to explain will really clarify the question but it's always worth trying isn't it ?
Anyway the result is what we needed as long as (as stated in the comments) one adjust the offset value according to the time zone settings of the spreadsheet. It would of course be possible to let the script handle that automatically but it would have make the script more complex, not sure it's really necessary.
For simple spreadsheets you may be able to change your spreadsheet timezone to GMT without daylight saving and use this short conversion function:
function durationToSeconds(value) {
var timezoneName = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
if (timezoneName != "Etc/GMT") {
throw new Error("Timezone must be GMT to handle time durations, found " + timezoneName);
}
return (Number(value) + 2209161600000) / 1000;
}
Eric Koleda's answer is in many ways more general. I wrote this while trying to understand how it handles the corner cases with the spreadsheet timezone, browser timezone and the timezone changes in 1900 in Alaska and Stockholm.
Make a cell somewhere with a duration value of "00:00:00". This cell will be used as a reference. Could be a hidden cell, or a cell in a different sheet with config values. E.g. as below:
then write a function with two parameters - 1) value you want to process, and 2) reference value of "00:00:00". E.g.:
function gethours(val, ref) {
let dv = new Date(val)
let dr = new Date(ref)
return (dv.getTime() - dr.getTime())/(1000*60*60)
}
Since whatever Sheets are doing with the Duration type is exactly the same for both, we can now convert them to Dates and subtract, which gives correct value. In the code example above I used .getTime() which gives number of milliseconds since Jan 1, 1970, ... .
If we tried to compute what is exactly happening to the value, and make corrections, code gets too complicated.
One caveat: if the number of hours is very large say 200,000:00:00 there is substantial fractional value showing up since days/years are not exactly 24hrs/365days (? speculating here). Specifically, 200000:00:00 gives 200,000.16 as a result.

Google Sheets Macro - JS

I'm trying to get the month of a cell containing a value in this format (dd/mm/yyyy)
var date = new Date(scadenziario.getRange(eRow,eCol).getValue());
var month = date.getMonth();
I am not sure why, but it doesn't work.
The cell cointaining the date display this in the sheet: 20/05/2021
I would like the month variable to be matching the month of the cell, in this case 5.
The date in the cell is not a date object. You can verify that if you run ISDATE:
One way to solve your issue is to use getDisplayValue instead and slice the relevant part of the resulting string:
const date = scadenziario.getRange(eRow,eCol).getDisplayValue();
const month = date.slice(3,5).replace("0","");
Last but not least, you want to get 5 and not 05 so one way is to get 05 and remove the 0 part. If the date is 12 then you will get the full number 12.

Google scripts converting text parameter to acceptable date object

I have scoured SO and the interwebs and discovered the horror that is date handling in Google Apps Script. I have found conflicting answers about date() and formatDate(), and have yet to find a definitive, working guide that shows the exact steps to take arbitrary text and create a date object
I have a simple ui.Prompt() that asks for a date in human-friendly terms, like "MM-DD-YYYY". I want to do date math on it, so ...
// result from ui.Prompt(), ie "03/01/2019" march 1st
var mytextdate = result.getResponseText();
//I want to do date math, so need a date object ...
var year_num = +mytextdate.substring(6,10);
var month_num = +mytextdate.substring(0,2);
var day_num = +mytextdate.substring(3,5);
var date_mytextdate = new date(year_num, month_num -1, day_num);
The script fails with 'date is undefined' at this point, before I can even do my date math. However I can retrieve the values for year_num, month_num, and day_num without a problem. What else do I need to make `date()' valid?
Make you last line:
var date_mytextdate = Utilities.formatDate(new Date(year_num, month_num -1, day_num),Session.getScriptTimeZone(),"MM-dd-yyyy");
Utilities.formatDate()

Date conversion from 29/08/2013 to milliseconds

I did test several simple date format convertion, like the one bellow and similar other:
var toParse:String = "Thu Aug 29 2013";
var milliseconds:Number = Date.parse(toParse);
I'd like to know if there exist something as simple as this method to convert the format 29/08/2013 to milliseconds.
Thanks and cheers.
It works the same with 29/08/2013 although the Date.parse just takes it as mm/dd/yyyy. So you need to do:
var toParse:String = "08/29/2013";
var milliseconds:Number = Date.parse(toParse);

ComboBoxes with current date in Flash

Ok there is a pretty complicated thing I need done in Flash CS4 with as3. I've looked around the web but I couldn't find much useful info.
Basically I have 3 ComboBoxes, one for the UTC date, another for the UTC month and another for the UTC year. I need it to be done so that the comboboxes will show the dates inbetween a set date (a date which I initially set in the flash script) and the current UTC date. For example, if I put the set date as 1st of Feb 2013, and the current date is 4th of March, I want the user to only be able to select February and March in the 'month' combobox. If they select February, then the available dates in the 'date' combobox should be 1 - 28, but if March is selected then only 1 - 4 should be available. This should be able to update every day automatically, so for example on March 5th, the number 5 should be added so it should be 1 - 5 available on the 'date' combobox if March is selected and so on...
I honestly have no idea how to go about this, but I really need it done one way or another. If anyone could help me I would be thankful.
When you select a new month, your two boundary dates can update accordingly, then this function can help you generate the date in between
private function test():void
{
var date1:Date = new Date(2012, 11, 25);
var date2:Date = new Date();
generateDateBetween(date1, date2);
}
private function generateDateBetween(date1:Date, date2:Date):void
{
for (var i:Number = date1.time; i < date2.time; i+= 3600*24*1000)
{
var date:Date = new Date();
date.time = i;
trace(date);
}
}