Difference between date.getHours() and date.hours in AS3 ? - actionscript-3

var date:Date = new Date();
date.setTime(date.getTime() + date.getTimezoneOffset() * 60000); // converts to GMT
trace(date.hours);
trace(date.getHours());
I need hours in GMT. Should I use date.hours ? or should I use date.getHours() ?

You should not convert the date object and plain get date.hoursUTC.

This is clearly explained on the manual:
hours is a property:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Date.html#hours
getHours a function / method of de Date Object
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Date.html#getHours()
You can easily retrieve the date for different zones with PHP
date_default_timezone_set
and format it with the date (Date/Time Functions)

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.

How to retrieve current time stamp, add X hours to it, and then store as a variable in POSTMAN?

I'm writing POSTMAN tests.
It takes a current time stamp from my account which is under UTC 00. I need to make it +11 hours and store it as a variable.
I can extract a current time frame under UTC 00 and store it as a global variable, but it misses a step for adding 11 hours to it.
var current_timestamp = new Date();
pm.globals.set("current_timestamp", current_timestamp.toISOString());
Actual stored variable:
2019-01-14T01:28:11.068Z
Expected stored variable:
2019-01-14T12:28:11.068Z
use .setHours()
var current_timestamp = new Date();
console.log(current_timestamp.toISOString())
// 2019-01-14T06:13:47.757Z
current_timestamp.setHours(current_timestamp.getHours() + 11);
console.log(current_timestamp.toISOString())
// 2019-01-14T17:13:47.757Z
pm.globals.set("current_timestamp", current_timestamp.toISOString())
Postman supports moment.js in scripts. Here is an example of how you might use it:
var moment = require('moment')
pm.globals.set('endOfDayWeekFromNowUTC', moment().endOf('day').add(1, 'weeks').utc().format('MM/DD/YYYY HH:mm:ss'))
Here is some information on how to parse dates with moment.js.

Google Apps Script and RFC 3339 issue

In the Google reference documentation I found a short function to convert RFC3339 date string to a valid Date object. The code is very simple and goes like this :
function parseDate(string) {
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
return new Date(parts.join(' '));
}
The problem is that it does not work.(I'm surprised they publish a code that doesn't work... am I missing something ?)
I also had an issue while using JSON to stringify and parse dates because the JSON method returns a UTC value (a Z at the end) and because of that I lose the Time zone information. Google's code does not handle that issue either (even if it worked).
Below is a demo code I used to test it and a solution I wrote to get what I want. Not sure it's very efficient nor well written but at least I get the result I want (I'm executing this code in a script set to GMT+2, Belgium summer time).
I'm open to any suggestion to improve this code.(and that would be the subject of this question)
I added a lot of logs and comments in the code to make it as clear as possible :
function testJSONDate() {
Logger.log('starting value : "2016/3/31 12:00:00"');
var jsDate = JSON.stringify(new Date("2016/3/31 12:00:00"));// time is 12:00 I'm in GMT+2
Logger.log('JSON.stringify value : '+jsDate);
Logger.log('JSON parse jsDate : '+JSON.parse(jsDate)); // time is 10:00, UTC
var jsDateWithoutQuotes = jsDate.replace(/"/,'');
var date = parseDate(jsDateWithoutQuotes);
Logger.log('parsed RFC3339 date using Google\'s code : '+date); // does not return a valid date
var otherFunction = parseDate2(jsDateWithoutQuotes);
Logger.log('parsed RFC3339 date using other code : '+otherFunction); // does return a valid date in my TZ
}
function parseDate(string) {
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
return new Date(parts.join(' '));
}
function parseDate2(string) {
var refStr = new Date().toString();
var fus = Number(refStr.substr(refStr.indexOf('GMT')+4,2));
Logger.log('TZ offset = '+fus);
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
var t = parts[1].split(':');
return new Date(new Date(parts[0]).setHours(+t[0]+fus,+t[1],0));
}
Logger results :
EDIT following first answer
After a small change in the code I managed to get Google's snippet to work but the problem of time zone being lost still remains because of the way JSON converts JS date objects.
new code and logger result below:
function testJSONDate() {
Logger.log('starting value : 2016/3/31 12:00:00');
var jsDate = JSON.stringify(new Date("2016/3/31 12:00:00"));// time is 12:00 I'm in GMT+2
Logger.log('JSON.stringify value : '+jsDate);
Logger.log('JSON parse jsDate : '+JSON.parse(jsDate)); // time is 10:00, UTC
var jsDateWithoutQuotesAndMillisecAndZ = jsDate.replace(/"/g,'').split('.')[0];
Logger.log('jsDateWithoutQuotesAndMillisecAndZ = '+jsDateWithoutQuotesAndMillisecAndZ);
var date = parseDate(jsDateWithoutQuotesAndMillisecAndZ);
Logger.log('parsed RFC3339 date using Google\'s code : '+date); // does not return a valid date
var otherFunction = parseDate2(jsDateWithoutQuotesAndMillisecAndZ);
Logger.log('parsed RFC3339 date using other code : '+otherFunction); // does return a valid date in the right tz
}
You have taken a little helper function out of context. It was only meant as a stopgap device to get the strings returned by a particular API (Google Calendar API) to parse correctly in Apps Script. It is not any kind of universal date converter. A project member threw it together when filing an issue, and a follow-up message in that thread points out another detail that the function doesn't handle.
As of now, the date parser in Apps Script correctly parses the following formats:
function testdate() {
Logger.log(new Date("2016/03/31 10:00:00")); // local time
Logger.log(new Date("2016/03/31 10:00:00 +2:00")); // with given offset
Logger.log(new Date("2016-03-31T08:00:00.000Z")); // in UTC
}
Note that milliseconds are required for UTC timestamp, but are not allowed for the others.
What you do with a datetime string that needs to be parsed but is not one of the above, depends on its format. If you have 2016-03-31T10:00:00 (apparently, this is what Google Calendar API returns) and this is meant to be in local time, then you need exactly what the quoted parse function does: replace T by space and - by /. If the same string represents UTC time, one needs to add .000Z at the end. And so on.

Actionscript 3 : get time to specific timezone (not the computer one)

I have an UTC timestamp and I would like to display the corresponding date and hour in a specific timezone (e.g. France local time) which is not the local timezone of the computer which might be in US. It seems complicated to take into account Daylight saving time.
On Flash/as3 documentation, I only found the Date class which have no function to specify the timezone (only use local time or UTC).
If I understand your problem, flash.globalization.DateTimeFormatter is your solution.
The DateTimeFormatter class provides locale-sensitive formatting for
Date objects and access to localized date field names. The methods of
this class use functions and settings provided by the operating
system.
Here's a function i found somewhere, probably right on stack oveflow to check if daylight savings is in effect.
public static function isObservingDTS(): Boolean {
var winter: Date = new Date(2011, 01, 01); // after daylight savings time ends
var summer: Date = new Date(2011, 07, 01); // during daylight savings time
var now: Date = new Date();
var winterOffset: Number = winter.getTimezoneOffset();
var summerOffset: Number = summer.getTimezoneOffset();
var nowOffset: Number = now.getTimezoneOffset();
if ((nowOffset == summerOffset) && (nowOffset != winterOffset)) {
return true;
} else {
return false;
}
}
flex will keep a date in UTC and a timezone offset. any displaying of the date will show the timezone corrected form of the date, unless you calculate the new time and spit the date out as a string. something like this
private function convertToTimezone(dtDate: Date, timezoneOffset: Number = 0): String {
//timezoneOffset in minutes
dtDate.setTime(dtDate.getTime() + (timezoneOffset * 60000) + (isObservingDTS() ? (60 * 60 * 1000) : 0));
return dtDate.toUTCString();
}
not very elegant, but it should get you there.

How to get the current time in Google spreadsheet using script editor?

There is an option to write a script and bind it to a trigger. The question is, how to get the current time in the script body?
function myFunction() {
var currentTime = // <<???
}
use the JavaScript Date() object. There are a number of ways to get the time, date, timestamps, etc from the object. (Reference)
function myFunction() {
var d = new Date();
var timeStamp = d.getTime(); // Number of ms since Jan 1, 1970
// OR:
var currentTime = d.toLocaleTimeString(); // "12:35 PM", for instance
}
I considered with timezone in my Google Docs like this:
timezone = "GMT+" + new Date().getTimezoneOffset()/60
var date = Utilities.formatDate(new Date(), timezone, "yyyy-MM-dd HH:mm"); // "yyyy-MM-dd'T'HH:mm:ss'Z'"
my script for Google docs
Use the Date object provided by javascript. It's not unique or special to Google's scripting environment.
Anyone who says that getting the current time in Google Sheets is not unique to Google's scripting environment obviously has never used Google Apps Script.
That being said, do you want to return current time as to what? The script user's timezone? The script owner's timezone?
The script timezone is set in the Script Editor, by the script owner. But different authorized users of the script can set timezone for the spreadsheet they are using from File/Spreadsheet settings menu of Google Sheets.
I guess you want the first option. You can use the built in function to get the spreadsheet timezone, and then use the Utilities class to format date.
var timezone = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
var date = Utilities.formatDate(new Date(), SpreadsheetApp.getActive().getSpreadsheetTimeZone(), "EEE, d MMM yyyy HH:mm")
Alternatively, get the timezone offset from UTC time using Javascript's date method, format the timezone, and pass it into Utilities.formatDate().
This requires one minor adjustment though. The offset returned by getTimezoneOffset() runs contradictory to how we often think of timezone. If the offset is positive, the local timezone is behind UTC, like US timezones. If the offset is negative, the local timezone is ahead UTC, like Asia/Bangkok, Australian Eastern Standard Time etc.
const now = new Date();
// getTimezoneOffset returns the offset in minutes, so we have to divide it by 60 to get the hour offset.
const offset = now.getTimezoneOffset() / 60
// Change the sign of the offset and format it
const timeZone = "GMT+" + offset * (-1)
Logger.log(Utilities.formatDate(now, timeZone, 'EEE, d MMM yyyy HH:mm');
The Date object is used to work with dates and times.
Date objects are created with new Date().
var date= new Date();
function myFunction() {
var currentTime = new Date();
Logger.log(currentTime);
}