getSpreadsheetTimeZone() returns wrong Time Zone - google-apps-script

I have a G Sheet script which is executed form Add-ons -> 'Add-on name -> 'do stuff'
During the add-on execution, I have to generate a date in user's time zone or at least in a spreadsheet time zone. I'm doing the following:
var timeZone = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
var date = Utilities.formatDate(new Date(), timeZone, 'yyyy-MMM-dd HH:mm:ss z');
Problem I have, that SpreadsheetApp.getActive().getSpreadsheetTimeZone() gives me a wrong time zone than it's set in my spreadsheet settings.
Here is the flow. I create a new spreadsheet, by default, it's in Central European Time (CET) I run my add-on which should execute the above code and insert a date in the spreadsheet. However, I get the date in Pacific Standard Time (PST). When I go to the Spreadsheet settings and change the time zone and re-run my add-on I get exactly right time zone which is in the settings.
Any ideas what could be wrong?
Notes:
My add-on published privately.
SpreadsheetApp.getActive().getSpreadsheetTimeZone() - returns exactly America/Los_Angeles value in the case of PST

Related

Old spreadsheets have wrong time and timezone .getValue() from cell

Problem: wrong time and timezone .getValue() from cell with format time
The bug occurs in old spreadsheets from 2017, but not a spreadsheet from 2022 january or new spreadsheets. update: it did appear in a new sheet as well
What steps will reproduce the problem?
Spreadsheet settings -> timezone GMT+1 (your current timezone)
in cell A1 write 20:00:00
set format cell A1 to "time"
execute this function in google apps script
function showTimeInCellA1() {
const date = SpreadsheetApp.getActiveSheet().getRange("A1").getValue();
SpreadsheetApp.getUi().alert("date in A1 is " + date);
}
Problem: it will alert "date in A1 is Sat Dec 30 1899 19:09:21 GMT+0009"
Expected: I expected time 20:00:00 and GMT+1(because settings spreadsheet are GMT+1)
This appears to be a bug!
Leaving this here for future readers as I think this may have been reported by OP.
There is already a report on Google's Issue Tracker which detail the same kind of behaviour:
wrong time and timezone .getValue() from cell with format time
Google does seem to know about this issue but you can also hit the ☆ next to the issue number in the top left of the page so to let Google know more people are encountering the behaviour so it is more likely to be seen to faster.
A workaround could be to add some years and use the time value of the new date object. I did not examine the exact number of years to be added in order to get valid time information - just tried to get past 1970 which worked for me.
var val2=new Date(val).getTime()+1000*60*60*24*365.25*72 // add ~72 years
Logger.log(new Date(val2))
The value of the current cell in Google Sheets is "8:00:00 AM"
A helper function was used to add the time to a given date:
function utils_buildDate(date,time){
var d=new Date(date);
// +-----------------------------------------------------------------
// | fix time value problem (no date is given in sheet)
// | https://issuetracker.google.com/issues/230650549?pli=1
time=new Date(time).getTime()+1000*60*60*24*365.25*72 // add ~72 years
// +-----------------------------------------------------------------
d.setHours(new Date(time).getHours());
d.setMinutes(new Date(time).getMinutes());
d.setSeconds(new Date(time).getSeconds());
return d;
}

Google Script when taking time from sheets adds +1 minute

var pickupTimeOld = wysylka.getRange("C5").getValue()
var pickupTime = Utilities.formatDate(pickupTimeOld, "GMT+1", 'HH:mm')
I am facing an issue while taking the value from google sheets which is for example 9:50:00, it's changing the time to 09:26. I can not find where it subtracts 24 minutes, as from the code everything is fine. Is ther eany possibilty that the confiuguration of google sheets make that issue? What can be reason of this substract.
Screen of formating in google sheets:
Chances are that the issue is caused by your code not observing the date component of the datetime value you want to present as HH:mm.
Your code gets a datetime value from the spreadsheet, but based on the screenshot, it looks like that datetime value only has a time component. That means that the date component will default to the spreadsheet epoch, i.e., 30 December 1899. Timezone offsets used to be pretty weird in 1899, so if you omit the date component, you may get surprising results.
Even today, not all timezones are whole hours — there are :30 and :45 offsets in the world in places like Canada, Australia, New Zealand, India, Iran, Afghanistan and Nepal. Dublin Mean Time used to be UTC-00:25:21 and Bombay Time used to be UTC+04:51. Malaya and Singapore used UTC+07:20 as daylight saving time until 1941. And so on.
JavaScript dates are always in UTC, but when you are presenting them, it uses the date's timezone and zoneinfo to determine the offset to use on the particular date that the date object reflects in the timezone of the runtime environment.
In Google Apps Script, certain properties of the runtime environment are set by the script project. The script project has a timezone of its own, separately from the hosting spreadsheet, and these two timezones may differ. That is why it is important to use Utilities.formatDate() and the spreadsheet's timezone when presenting a datetime value to the user.
Your code assumes the GMT+1 timezone, which may be different from the timezone of the spreadsheet. Most likely, your timezone is EET rather than GMT+1. These two are not the same thing. Currently the most important difference is that EET observes daylight saving time (EEST) while GMT+1 does not. It is possible that in the year 1899 there were other differences as well, which may explain the 24-minute discrepancy you describe.
To get the time value as it shows in the spreadsheet, you need to include the date component, and format the resulting datetime in the timezone of the spreadsheet, like this:
const dateString = wysylka.getRange('B5').getDisplayValue().replace(/^(\d+)-(\d+)-(\d+)$/, '20$3-$2-$1 ');
const timeString = wysylka.getRange('C5').getDisplayValue();
const datetime = new Date(dateString + timeString);
const timezone = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
const pickupTimeString = Utilities.formatDate(datetime, timezone, 'HH:mm');
You may also want to check that your spreadsheet's File > Settings > Time zone is set correctly. Note that changing the timezone will change the presentation of datetime values in the spreadsheet, so they may need correction after you change the timezone.
Try this:
var wysylka = SpreadsheetApp.getActiveSheet();
var pickupTimeOld = wysylka.getRange("C5").getDisplayValue();
var tz = Session.getTimeZone(); // or SpreadsheetApp.getActive().getSpreadsheetTimeZone();
var today = Utilities.formatDate(new Date(), tz, 'yyyy-MM-dd');
var pickupTime = Utilities.formatDate(new Date(today + ' ' + pickupTimeOld), tz, 'HH:mm');
Probably in your case it makes sense to define today about this way:
var today = wysylka.getRange("B5").getDisplayValue()

Wrong Date google spread sheet

I'm reading a Google Sheet in javascript through Google Drive API.
I have this my function to get the last modification var dt = file.getLastUpdated() it's give me this result 4/5/2018 8:48:22 NOT my cuurent Time.
I used var formattedDate = Utilities.formatDate(file.getLastUpdated() , "GMT", "yyyy.MM.dd HH:mm:ss.SSS"); convert date to grenwich time but still the same issue.
I correct the Time Zone of my google script project to (GMT+01:00) Berlin and still wrong date time
You should be using "CET" in formatDate().
Utilities.formatDate(file.getLastUpdated() , "CET", "yyyy.MM.dd HH:mm:ss.SSS");
The formatDate() function takes 3 parameters: date, timeZone, and format. If you pass it "GMT", then the date/time will presented in that time zone. Instead, you need to pass it "CET" (for Central European Time) to have time displayed in that time zone.
EDIT: A potentially more stable way, that could better handle daylight savings (CET vs CEST), is to use Session.getScriptTimeZone(). This does require that you have your script time zone set, which you did correctly already. (There may not be a difference, as I don't know for sure how this is handled.)
Utilities.formatDate(file.getLastUpdated(), Session.getScriptTimeZone(), "yyyy.MM.dd HH:mm:ss.SSS");
check the time zone settings. (File > Spreadsheet Settings) Timezone is the second option.

google calendar, spreadsheet and script handle time zone differently

I am trying to write a script to add events from Spreadsheet to Calendar. I found the time of added events is always 1 hour off. I checked the time zone settings and here's what I found.
Calendar: (GMT-04:00) Eastern Time
Spreadsheet: (GMT-05:00) Eastern Time
Script: (GMT-05:00) Eastern Time
So they are all Eastern Time, but the Calendar uses the Daylight Savings Time while the Spreadsheet and Script.
I know I can manually adjust GMT every time DST changes so that the resulting time is right. But is there a better way, so that I can set and forget?
Instead of hardcoding the timezone with GMT-04:00 use the literal expression of your geographic area (aka Canonical ID) as defined in this standard : Joda.org
this is what Google Apps Script is using.
You can also get that more simply using
SpreadsheetApp.getActive().getSpreadsheetTimeZone()
or from the calendar object : calendar.getTimeZone()
all these parameters will handle daylight savings automatically, which is not the case for the GMT+xx:xx method.
You shouldn't have any problem as long as both are on the same timezone. Calendars have a setTimeZone(timeZone) method and spreadsheets have a setSpreadsheetTimeZone(timeZone) method so it is easy to synchronize both
EDIT
Following comment
Since you seem to combine date and time in a unique date object and that the daylight saving puts you into trouble (because "pure time" values in spreadsheets are converted to a date JavaScript object automatically and with summer time correction), below is a small code that I use to workaround this issue. I added a few logs to show intermediate values;
function combineDateAndTime(){
// in this example cell A1 has a date and cell B1 has time
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var dateOnly = sh.getRange('A1').getValue();
var timeOnly = sh.getRange('B1').getValue();
Logger.log('dateOnly object is : '+dateOnly+'\ntimeOnly object is : '+timeOnly);
var hours = Number(Utilities.formatDate(timeOnly, 'GMT'+timeOnly.toString().split('GMT')[1],'hh'));
var minutes = timeOnly.getMinutes();
var completeDateAndTime = new Date(dateOnly.setHours(hours,minutes,0,0));
Logger.log('completeDateAndTime is : '+completeDateAndTime);
}
Note : there are other ways to retrieve hour values, see this post for example.

Google apps script - form input time changes when copied

I have a Google form to collect info on people leaving the organisation. One of the questions is 'What date and what time do they leave' The response is in the format dd/mm/yyyy, hh:mm. so a typical response would be 24/04/2015 17:00:00, and that's what I see in the Form responses 1 worksheet when the form is submitted.
I need to add the day of the week and copy the information into another worksheet within the spreadsheet, so I use
var leaveDate = inputSheet.getRange("G" + lastRow).getValue();
var leaveDateTime = Utilities.formatDate(leaveDate, "GMT", "EEE dd-MM-yyyy hh:mm:ss");
The issue I'm seeing is that when I paste the value the time is changing, and what gets pasted is
Fri 24-04-2015 04:00:00
Can anyone explain why this is happening and what I can do to resolve it?
Thanks
Apps Script converts date types to the time zone set up in the script editor. In the script editor, you need to set the time zone, even if you've set it in the spreadsheet.
Set the time zone to your local time zone.
Make sure the time zone in your spreadsheet, and the time zone in your script editor match.
If you have multiple editors of the spreadsheet in multiple time zones, and the other users have set the time to their local time, then obviously, their time and your time won't be the same. If someone left the organization on the other side of the world, at 4pm their time, they didn't leave the organziation at 4pm your time. You could assume that if the spreadsheet states 4pm, that it was their local time, and convert the time. In that case, you'd need to know the time zone of every time entry that is made, and then adjust it as necessary.
Try:
...
// var leaveDateTime = Utilities.formatDate(leaveDate, "GMT", "EEE dd-MM-yyyy hh:mm:ss");
var leaveDateTime = Utilities.formatDate(leaveDate, "GMT", "EEE dd-MM-yyyy HH:mm:ss");
...
UPDATE
Thanks to #sandy-good and #wchiquito for pointing me in the right direction. There were 2 issues. First issue is using hh instead of HH. The second issue is that we are on GMT+1 at the moment, and will be until end October, at which point we go back to GMT! As I don't want to code around that I'm going to simplify it by dropping the day, which then means I don't have to reformat the date.