Google Ads scripts often need to work with dates and times. Common use cases include retrieving reports for a specific date range, scheduling campaigns or ad groups to run at specific times, and outputting to a spreadsheet the time the script last ran. This guide describes important concepts, common pitfalls, and recommended approaches when working with dates and times in Google Ads scripts.
Basic concepts
To work with dates and times in Google Ads scripts, use JavaScript's built-in date object. A JavaScript date object represents a particular moment in time. There are several ways to create a new date object:
// Create a date object for the current date and time.
const now = new Date();
// Create a date object for a past date and time using a formatted string.
const date = new Date('February 17, 2021 13:00:00 -0500');
// Create a copy of an existing date object.
let copy = new Date(date);
New Scripts users are often confused by how date objects handle timezones. A
natural but incorrect way to think of a date object is as the time on a
clock in a single timezone. For example, in the snippet above, some users
mistakenly assume that date
is valid only in one timezone, namely the
timezone with a -5 hours offset that was used to create it. In that mistaken
view, date
would need to be "converted" to be used in other timezones.
Instead, the correct way to think about a date object is as a particular moment in time independent of any timezone. Although a particular moment is shown differently on clocks in different timezones, it is the same moment. For example, consider this snippet:
// Create two date objects with different times and timezone offsets.
const date1 = new Date('February 17, 2021 13:00:00 -0500');
const date2 = new Date('February 17, 2021 10:00:00 -0800');
// getTime() returns the number of milliseconds since the beginning of
// January 1, 1970 UTC.
// True, as the dates represent the same moment in time.
console.log(date1.getTime() == date2.getTime());
// False, as the dates are separate objects, though they happen to
// represent the same moment in time.
console.log(date1 == date2);
Since a date object represents a particular moment in time, it does not need to be "converted" across timezones. Instead, it can be rendered as a string that is formatted for a particular timezone.
To render a date as a string with a particular format and timezone, use
Utilities.formatDate(date, timeZone,
format)
.
For example:
const date = new Date('February 17, 2021 13:00:00 -0500');
// February 17, 2021 13:00:00 -0500
console.log(Utilities.formatDate(date, 'America/New_York', 'MMMM dd, yyyy HH:mm:ss Z'));
// February 17, 2021 10:00:00 -0800
console.log(Utilities.formatDate(date, 'America/Los_Angeles', 'MMMM dd, yyyy HH:mm:ss Z'));
// 2021-02-17T18:00:00.000Z
console.log(Utilities.formatDate(date, 'Etc/GMT', 'yyyy-MM-dd\'T\'HH:mm:ss.SSS\'Z\''));
These examples specified the timezone directly using a timezone
ID. To retrieve the
timezone associated with the Google Ads account running your script, use
AdsApp.currentAccount().getTimeZone()
.
Common pitfalls
Default timezone when logging a date object
When directly logging a date object using Logger.log()
, it is rendered using
a default format and timezone. For example:
const date = new Date('February 17, 2021 13:00:00 -0500');
// Wed Feb 17 10:00:00 GMT-08:00 2021
console.log(date);
The default timezone is America/Los_Angeles (Pacific time), regardless of the
timezone associated with the Google Ads account. If you would like to render
the date object as a string using a custom format and timezone for logging or
other purposes, always use Utilities.formatDate(date, timeZone,
format)
.
Default timezone when creating a date object
When creating a date object using a string that does not provide a timezone offset, the timezone is assumed to be America/Los_Angeles (Pacific time), regardless of the timezone associated with the Google Ads account. For example:
// Create a date without specifying the timezone offset.
const date = new Date('February 17, 2021 13:00:00');
// Wed Feb 17 13:00:00 GMT-08:00 2021
console.log(date);
When creating a date object using a string, always include a timezone offset to ensure the date object represents the moment in time you actually want.
Default timezone in date object methods
JavaScript date objects have several methods that assume a default timezone, such as:
getFullYear()
getMonth()
getDate()
getDay()
getHours()
getMinutes()
This also includes these methods' set___()
equivalents (for example,
setMonth()
), and getTimezoneOffset()
.
In Google Ads scripts, the default timezone is America/Los_Angeles (Pacific time), regardless of the timezone associated with the Google Ads account. Therefore, unless your Google Ads account is in this timezone, you should generally avoid using these methods.
To get the year, month, date, day, hours, or minutes for a date object in your
account's timezone, use Utilities.formatDate(date, timeZone,
format)
with a format specifying the part of the date or time you want, and use
AdsApp.currentAccount().getTimeZone()
to get your account's timezone.
Creating a date object from a formatted date string
You can create a date object by passing a formatted date string to the date constructor. For example:
const date = new Date('February 17, 2021 13:00:00 -0500');
The constructor can only parse certain date string formats. To make sure your
date string is parsed correctly, always provide it in the MMMM dd, yyyy
HH:mm:ss Z
format.
For example, to construct a date object for noon today in the current account's timezone:
const now = new Date();
const timeZone = AdsApp.currentAccount().getTimeZone();
const noonString = Utilities.formatDate(now, timeZone, 'MMMM dd, yyyy 12:00:00 Z');
const noon = new Date(noonString);
Do not use the 'z' pattern to create date strings that will be passed to a date constructor, as the constructor will not always be able to parse it. Only use the 'Z' pattern.
Date math
Some scripts need to perform simple math with dates, such as finding a date X
days before or after a given date. When performing date math, use getTime()
.
Calling getTime()
on a date object returns the number of milliseconds since
the beginning of January 1, 1970 UTC. You can perform math on this value, then
apply the new value to a date object using setTime()
or providing it as a
parameter when creating a new date object.
For example:
const MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
const now = new Date();
const yesterday = new Date(now.getTime() - MILLIS_PER_DAY);
In this example, yesterday
is exactly 24 hours ago.
Reporting
When retrieving a report using AdsApp.search()
,
the GAQL query requires dates to be specified
in the format yyyy-MM-dd
(for example, 2021-06-30
would be June 30, 2021).
Likewise, the getStatsFor()
method available on many Google Ads scripts
objects requires dates to be specified in the same format. Use
Utilities.formatDate(date, timeZone,
format)
to format a date object in this format.
For example, to retrieve a report from one to three days ago:
const MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
const now = new Date();
const from = new Date(now.getTime() - 3 * MILLIS_PER_DAY);
const to = new Date(now.getTime() - 1 * MILLIS_PER_DAY);
const timeZone = AdsApp.currentAccount().getTimeZone();
const results = AdsApp.search(
'SELECT campaign.name, metrics.clicks'
'FROM campaign '
'WHERE segments.date BETWEEN '
Utilities.formatDate(from, timeZone, 'yyyy-MM-dd') ' AND '
Utilities.formatDate(to, timeZone, 'yyyy-MM-dd'));
Spreadsheets
Google Ads scripts often write output to a spreadsheet, including date objects. When setting a cell in a spreadsheet by passing a date object, the spreadsheet's timezone is used to interpret that date. For example, suppose we have a spreadsheet whose timezone is set to Pacific Time:
// Suppose today is February 17, 2021 13:00:00 -0500 (Eastern Time)
const now = new Date();
spreadsheet.getRange('A1').setValue(now);
The value in A1 will be 17-Feb-21 10:00:00.
To ensure date objects are written to a spreadsheet as you expect, set the spreadsheet's timezone to match your Google Ads account's timezone:
spreadsheet.setSpreadsheetTimeZone(AdsApp.currentAccount().getTimeZone());
You can also set a spreadsheet's time manually.