I have a script that converts and Excel file to a Google Sheet. However, the newly created Google Sheet defaults to the Pacific timezone. We already have our Company set to Eastern timezone in Google Admin. I also have the local machine that is executing the script set to Eastern timezone and the user is also set to Eastern timezone. The script project is set to Eastern timezone as well. If I goto Google Apps and create a sheet from scratch, it defaults to Eastern timezone as desired. But when the script creates the new sheet, it always defaults to Pacific timezone. Since it seems there's no way to set the timezone via a script function, is there anyway to make it default to Eastern timezone? Note as well that here in the Eastern timezone, we have the stupid daylight savings time. So it changes between -4 and -5, which is such a pain!
My reason for this is that after I convert the Excel to Google Sheet, I have to import the records into another import sheet. The imported data has dates and times that keep getting sku'd after or during the import. Since I import using the getRange.getValues function, it always performs the new Date(). I have tried the Utilities.format function as well. But I don't know if I can be sure that the timezone will stay the same. And since I can't read what timezone the created sheet has, it becomes a gamble.
I would appreciate any help that could be offered in the way of scripting fixes. It is not feasible for me to have to go in each time and change the timezone manually within the sheet itself.
Thanks for any help!
Doug
The conversion code:
function convertExceltoGoogleSheet(fileName, newFileName) {
try {
var fileName = fileName || "microsoft-excel.xlsx";
var excelFile = DriveApp.getFilesByName(fileName).next();
var fileId = excelFile.getId();
var folderId = Drive.Files.get(fileId).parents[0].id;
var blob = excelFile.getBlob();
//If no newFileName passed, create one
if (newFileName.trim() == '') {
//Generate formatted filename
var dateInfo = getDateInfo(-20);
var mo = dateInfo[2].toString();
if (mo.length < 2) {
var mo = "0" + mo;
}
var newFileName = dateInfo[0].toString() + "-" + mo + "-" + filename;
}
var resource = {
//title: excelFile.getName().replace(/.xlsx?/, ""), //use original filename
title: newFileName, //Use formatted filename from above
key: fileId,
parents: [{"id": folderId}]
};
var newFile = Drive.Files.insert(resource, blob, {
convert: true
});
return newFile.id;
} catch (f) {
Logger.log(f.toString());
}
}
Related
I need to set the other object's timezone to match now object which has utc timezone.
I'm comparing two datetime objects but the 'difference' value does not match the expected value. Most likely down to the fact that both objects have different Time Zones (Utc & Bst).
void main() {
var now = new DateTime.now().toUtc();
print(now);
print(now.timeZoneName);
var other = DateTime.parse("2020-05-22 18:27:32.608069");
print(other);
print(other.timeZoneName);
var diff = now.difference(other);
print(diff);
}
output:
2020-05-22 19:26:39.169Z
UTC
2020-05-22 18:27:32.608
British Summer Time
1:59:06.561000
You don't want to convert, you want to read in a date/time as UTC.
Change
var other = DateTime.parse("2020-05-22 18:27:32.608069");
to
var other = DateTime.parse("2020-05-22 18:27:32.608069z");
If other is already constructed, you need to make a new object with DateTime.utc()
https://api.dart.dev/stable/2.8.2/dart-core/DateTime/DateTime.utc.html
var newDate = new DateTime.utc(other.year, other.month, other.day, other.hour, other.minute, other.second, other.millisecond, other.microsecond);
I am trying to parse a UTC Date string to DateTime and then parse it to local, however I am having troubles with converting it to the local time. In the UK it should be plus one, however when I print .isUtc it returns as false.
This is what I have now:
print(widget.asset.purchaseDate);
DateTime temp = DateTime.parse(widget.asset.purchaseDate);
print(temp.toLocal());
I/flutter (5434): 2020-05-07 21:29:00
I/flutter (5434): 2020-05-07 21:29:00.000
You need to indicate a timezone to DateTime.parse, otherwise it assumes local time. From the dartdoc:
An optional time-zone offset part, possibly separated from the
previous by a space. The time zone is either 'z' or 'Z', or it is a
signed two digit hour part and an optional two digit minute part.
Since you know your string represents UTC, you can tell the parser by adding the Z suffix.
var temp = DateTime.parse(widget.asset.purchaseDate + 'Z');
print(temp.isUtc); // prints true
While #Richard Heap's answer stands I'd like DateTime.parseUtc() to exist.
If there will be a day when dart allows static extension methods here is an implementation that would work:
extension DateTimeExtension on DateTime {
static DateTime parseUtc(String formattedDate) => DateTime.parse('${formattedDate}z');
static DateTime? tryParseUtc(String? formattedDate) {
if (formattedDate != null) {
return DateTime.tryParse('${formattedDate}z');
}
return null;
}
}
Currently you'd have to use it with the extension classes name, like so:
DateTimeExtension.parseUtc(someDate)
or
DateTimeExtension.tryParseUtc(someOtherDate)
I think the latter is more useful where someOtherDate is nullable
I would like to persist the last row with yesterday's date.
My data looks like the following:
I have tried the following to persist the data, which works well.
function moveValuesOnly() {
var ss = SpreadsheetApp.getActive().getSheetByName('Store values');
Logger.log(ss.getName());
// get yesterday's date
var now = new Date();
var yesterday = new Date();
yesterday.setDate(now.getDate()-1);
yesterday = Utilities.formatDate(yesterday, "GMT+1", 'yyyy-MM-dd');
Logger.log("yesterday: " + yesterday);
var source = ss.getRange('4:4');
source.copyTo(ss.getRange('4:4'), {contentsOnly: true});
source.setFontWeight("bold");
}
Find below an example spreadsheet:
Sample Spreadsheet
As you can see I am getting yesterday's date correctly formatted in my script as in my Date column. I also can correctly 'persist' the data.
My problem is that I do not know how to get the range where yesterday's date occurs so that I can hand it over in my script to persist it.
Any suggestions how to get the row that matches yesterday's date.
not totally sure what you mean by "persist" but the function below returns the row number for the first row with yesterday's date in it:
function getYesterdayRow(yesterdayDate,columnRange) {
var displayValues = columnRange.getDisplayValues();
for (var i = 0; i < displayValues.length; i++) {
var displayValue = displayValues[i][0];
if (displayValue === yesterdayDate) return i + 1;
}
return 0;
}
You can call it like this in your code after you've defined yesterday:
var yesterdayRow = getYesterdayRow(yesterday,ss.getRange(A:A))
Note that this function quickly fixes your current need, but it uses getdisplayValues(), which is a quick cheat to not have to deal with processing the date. You should probably modify this function so that it would work with other date formats. (Use getValues(), get the day, time and month from yesterday, then the same from each value in the for loop, and make sure to account for any timezone offsets.)
The Requirement
I can retrieve list of google-calendar events following this reference: https://developers.google.com/calendar/v3/reference/events/list
How can I get list of all the events between 2017-03-30T14:30:00 and 2017-03-30T15:30:00 according to the calendar's timeZone?
My investigation
There are optional parameters timeMin, timeMax. The problem is that they should have one of the following formats (RFC3339 timestamp):
2017-03-30T14:30:00Z, here Z stand for Zulu = UTC timeZone
2017-03-30T14:30:00+03, here +03 stands for the timeZone shift comparing to UTC
In both cases I have to get the calendar's timeZone (how can I get it in format I need with offset, e.g. -04, +00, +03?) and then perform some extra calculations/manipulations.
Obviously in my case I would prefer just to pass the values without mentioning the timeZone and make API use the calendar's timeZone.
There is another optional parameter timeZone but this is the timeZone that will be used in the response, not in the filter. The default is the calendar's timeZone which is good for me.
Finally I found the way to apply GC (Google Calendar) TZ on a datetime:
from dateutil import tz
from datetime import datetime
tzinfo = tz.gettz(default_calendar['timeZone'])
# Option1: create date without TZ and then apply GC TZ using astimezone:
dt = datetime(2018,7,3,14,30,0)
dt_in_gc_tz = dt.astimezone(tzinfo) # 2018-07-03 14:30:00+03:00
# Option2: just create dateTime with GC TZ:
dt_in_gc_tz = datetime(2018, 7,3,14,30,0, tzinfo=tzinfo) # 2018-07-03 14:30:00+03:00
# Convert to RFC3339 timestamp string:
dt_in_gc_tz.isoformat() # '2018-07-03T14:30:00+03:00'
You don't have to use the 'q' property for this. Instead, use timeMin and timeMax with timeMin being the earlier date. In the try-it format looks like this:
const moment = require('moment-timezone');
const timeMin = moment(start_time).toISOString();
const timeMax = moment(end_time).toISOString();
oauth2Client.setCredentials({ refresh_token });
const token = await oauth2Client.getAccessToken();
const response = await axios.get(
`https://www.googleapis.com/calendar/v3/calendars/${email}/events?key=${config.get('service:google:api_key')}&timeMin=${timeMin}&timeMax=${timeMax}`, {
headers: {
'Authorization': `Bearer ${token.res.data.access_token}`
}
});
I have this recorded in SQL Server:
1- startTime (datetime): 5/2/2009 08:30 (brazilian time format: d/m/y)
2- startTime (datetime): 4/2/2009 14:30 (brazilian time format: d/m/y)
My application just records time... the date it's SQL that generates by itself be getting the date of today.
When I ask VS 2008 to order this datetime fields, it returns me that code #2 is before #1, because 4/2/2009 comes before 5/2/2009.
But, actually I want it to order by time only and ignore the date.
Is it possible??
Thanks!!
André
from d in dates
orderby d.TimeOfDay
select d;
or
dates.OrderBy(d => d.TimeOfDay);
Note: This will work as long as this is plain LINQ and not LINQ-to-SQL. If you're using LINQ-to-SQL to query your database, you'll need something that will translate to SQL.
You might also try fixing your app so it always saves the same base date with the time (like '01/01/1900' or whatever) and then you do not have to do all these slow and inefficient date stripping operations every time you need to do a query.
Or as Joel said, truncate or strip off the date portion before you do the insert or update.
Well, you can't really store a datetime without a date, but you could just store the total seconds as an double (using #florian's method).
You'd have to add a second method to convert this back to a date in your object, if you still need a date, such as:
public class BusinessObjectWithDate
{
private string _someOtherDbField = "";
private double _timeInMS = 0; // save this to the database
// sort by this? in sql or in code. You don't really need this
// property, since TimeWithDate actually saves the _timeInMS field
public double TimeInMS {
get { return _timeInMS; }
}
public DateTime TimeWithDate { // sort by this too, if you want
get { return (new DateTime(1900,1,1).AddMilliseconds(_timeInMS)); }
set { _timeInMS = value.TimeOfDay.TotalMilliseconds; }
}
}
var f = new BusinessObjectWithDate();
MessageBox.Show( f.TimeWithDate.ToString() ); // 1/1/1900 12:00:00 AM
f.TimeWithDate = DateTime.Now;
MessageBox.Show( f.TimeWithDate.ToString() ); // 1/1/1900 1:14:57 PM
You could also just store the real date time, but always overwrite with 1/1/1900 when the value gets set. This would also work in sql
public class BusinessObjectWithDate
{
private DateTime _msStoredInDate;
public DateTime TimeWithDate
{
get { return _msStoredInDate; }
set {
var ms = value.TimeOfDay.TotalMilliseconds;
_msStoredInDate = (new DateTime(1900, 1, 1).AddMilliseconds(ms));
}
}
}
Try this in your sql:
ORDER BY startTime - CAST(FLOOR(CAST(startTime AS Float)) AS DateTime)