Beginner's Guide to Working with Dates in Google Apps Script
The Date
object helps you work with dates and times in your Google Apps Script projects. This guide will take you from basic date operations to practical applications with other Google services, explaining everything step-by-step along the way.
Prerequisites
This tutorial assumes that you're familiar with:
Setting Your Project Time Zone
Before working with dates, set your project's time zone:
Open the Apps Script editor
Click on ⚙️ (Project Settings) in the left sidebar
Find "Time zone" under "General settings"
Select your time zone (e.g., "(GMT-08:00) Pacific Time – Los Angeles")

This setting affects how dates work in your project, especially for:
Time-based triggers
Date interpretations when no time zone is specified
Working with Google services that use date/time information
Part 1: Creating and Reading DatesCreating the Current Date and Time
Syntax
new Date()
Parameters
None
Returns
A Date
object representing the current date and time
Example:function getCurrentDateExample() {
// Get the current date and time
let currentDate = new Date();
Logger.log("Current date and time: " + currentDate);
}
Creating a Specific DateSyntax
new Date(year, month, day)
Parameters:year: Four-digit year (e.g., 2023)
month: Month as a number from 0-11 (0=January, 11=December)
day: Day of the month (1-31)
Returns:
function getCurrentDateExample() {
// Get the current date and time
let currentDate = new Date();
Logger.log("Current date and time: " + currentDate);
}
Syntax
new Date(year, month, day)
year: Four-digit year (e.g., 2023)
month: Month as a number from 0-11 (0=January, 11=December)
day: Day of the month (1-31)
Returns:
A Date object set to the specified date at 00:00:00 (midnight)
Example:function createSpecificDateExample() {
// Create a date for March 15, 2023
// IMPORTANT: Months are 0-indexed (0=January, 11=December)
let specificDate = new Date(2023, 2, 15);
Logger.log("Specific date: " + specificDate);
}
Creating a Date with TimeSyntax
new Date(year, month, day, hours, minutes, seconds, milliseconds)
Parametersyear: Four-digit year (e.g., 2023)
month: Month as a number from 0-11 (0=January, 11=December)
day: Day of the month (1-31)
hours: Hour (0-23)
minutes: Minutes (0-59)
seconds: Seconds (0-59)
milliseconds: Milliseconds (0-999) - optional
Returns
function createSpecificDateExample() {
// Create a date for March 15, 2023
// IMPORTANT: Months are 0-indexed (0=January, 11=December)
let specificDate = new Date(2023, 2, 15);
Logger.log("Specific date: " + specificDate);
}
Syntax
new Date(year, month, day, hours, minutes, seconds, milliseconds)
year: Four-digit year (e.g., 2023)
month: Month as a number from 0-11 (0=January, 11=December)
day: Day of the month (1-31)
hours: Hour (0-23)
minutes: Minutes (0-59)
seconds: Seconds (0-59)
milliseconds: Milliseconds (0-999) - optional
Returns
A Date
object set to the specified date and time
Example:function createDateWithTimeExample() {
// Create a date for March 15, 2023 at 2:30 PM
let dateWithTime = new Date(2023, 2, 15, 14, 30, 0);
Logger.log("Date with time: " + dateWithTime);
}
Creating a Date from a StringSyntax
new Date(dateString)
Parameters:dateString: A string representing a date (ISO format recommended)
Returns
function createDateWithTimeExample() {
// Create a date for March 15, 2023 at 2:30 PM
let dateWithTime = new Date(2023, 2, 15, 14, 30, 0);
Logger.log("Date with time: " + dateWithTime);
}
Syntax
new Date(dateString)
dateString: A string representing a date (ISO format recommended)
Returns
A Date object parsed from the string
Example:function createDateFromStringExample() {
// Create a date from an ISO format string
let dateFromString = new Date("2023-03-15T14:30:00");
Logger.log("Date from ISO string: " + dateFromString);
}
ISO 8601 Format Recommendation
While the Date
constructor can often parse various date string formats, using the ISO 8601 format is strongly recommended for consistency and reliability. The ISO 8601 format represents dates and times like this: YYYY-MM-DDTHH:mm:ss.sssZ
.
YYYY: Year with century (e.g., 2023)
MM: Month (01-12)
DD: Day of the month (01-31)
T: Separator indicating the start of the time component
HH: Hour (00-23)
mm: Minute (00-59)
ss: Second (00-59)
sss: Optional milliseconds
Z: Optional time zone indicator ("Z" for UTC, or +/-HH:mm for time zone offset)
Using ISO 8601 format helps avoid ambiguity and ensures that your date strings are correctly parsed in Apps Script.
Creating a Date from MillisecondsSyntax
function createDateFromStringExample() {
// Create a date from an ISO format string
let dateFromString = new Date("2023-03-15T14:30:00");
Logger.log("Date from ISO string: " + dateFromString);
}
ISO 8601 Format Recommendation
While the Date
constructor can often parse various date string formats, using the ISO 8601 format is strongly recommended for consistency and reliability. The ISO 8601 format represents dates and times like this: YYYY-MM-DDTHH:mm:ss.sssZ
.
YYYY: Year with century (e.g., 2023)
MM: Month (01-12)
DD: Day of the month (01-31)
T: Separator indicating the start of the time component
HH: Hour (00-23)
mm: Minute (00-59)
ss: Second (00-59)
sss: Optional milliseconds
Z: Optional time zone indicator ("Z" for UTC, or +/-HH:mm for time zone offset)
Using ISO 8601 format helps avoid ambiguity and ensures that your date strings are correctly parsed in Apps Script.
Syntax
new Date(milliseconds)
Parametersmilliseconds: Number of milliseconds since January 1, 1970, 00:00:00 UTC
Returns
milliseconds: Number of milliseconds since January 1, 1970, 00:00:00 UTC
A Date object representing that time
Example:function createDateFromMillisecondsExample() {
// Create a date from milliseconds since January 1, 1970 (Unix Epoch)
let dateFromMs = new Date(1678888200000);
Logger.log("Date from milliseconds: " + dateFromMs);
}
Part 2: Getting Date Components
function createDateFromMillisecondsExample() {
// Create a date from milliseconds since January 1, 1970 (Unix Epoch)
let dateFromMs = new Date(1678888200000);
Logger.log("Date from milliseconds: " + dateFromMs);
}
Once you have a Date
object, you can extract various parts of it:
function getDateComponentsExample() {
// Create a date to work with
let date = new Date(2023, 2, 15, 14, 30, 45); // March 15, 2023, 2:30:45 PM
// Get the day of the month (1-31)
let day = date.getDate();
Logger.log("Day of month: " + day); // 15
// Get the month (0-11)
let month = date.getMonth();
Logger.log("Month: " + month); // 2 (March)
// Get the full year
let year = date.getFullYear();
Logger.log("Year: " + year); // 2023
// Get the day of week (0-6, where 0=Sunday, 6=Saturday)
let dayOfWeek = date.getDay();
Logger.log("Day of week: " + dayOfWeek); // 3 (Wednesday)
// Get the hour (0-23)
let hours = date.getHours();
Logger.log("Hours: " + hours); // 14 (2 PM)
// Get the minutes (0-59)
let minutes = date.getMinutes();
Logger.log("Minutes: " + minutes); // 30
// Get the seconds (0-59)
let seconds = date.getSeconds();
Logger.log("Seconds: " + seconds); // 45
// Get milliseconds (0-999)
let milliseconds = date.getMilliseconds();
Logger.log("Milliseconds: " + milliseconds); // 0
// Get timestamp (milliseconds since January 1, 1970)
let timestamp = date.getTime();
Logger.log("Timestamp: " + timestamp);
}
Part 3: Formatting DatesBasic Date Formatting
SyntaxUtilities.formatDate(date, timeZone, format)
Parametersdate: The Date object to format
timeZone: Time zone ID (e.g., "GMT", "America/New_York")
format: Format pattern to apply
Returns
Utilities.formatDate(date, timeZone, format)
date: The Date object to format
timeZone: Time zone ID (e.g., "GMT", "America/New_York")
format: Format pattern to apply
Returns
A string representation of the date in the specified format
Example:function basicFormattingExample() {
let date = new Date(2023, 2, 15, 14, 30, 45); // March 15, 2023, 2:30:45 PM
// Format date using Utilities.formatDate()
let formattedDate = Utilities.formatDate(
date,
Session.getScriptTimeZone(), // Uses the project's time zone
"yyyy-MM-dd HH:mm:ss"
);
Logger.log("Formatted date: " + formattedDate); // Example: "2023-03-15 14:30:45"
// Format as US date
let usDate = Utilities.formatDate(
date,
Session.getScriptTimeZone(),
"MM/dd/yyyy"
);
Logger.log("US date format: " + usDate); // "03/15/2023"
// Format as European date
let euDate = Utilities.formatDate(
date,
Session.getScriptTimeZone(),
"dd/MM/yyyy"
);
Logger.log("European date format: " + euDate); // "15/03/2023"
// Format with day name and month name
let longDate = Utilities.formatDate(
date,
Session.getScriptTimeZone(),
"EEEE, MMMM d, yyyy"
);
Logger.log("Long date format: " + longDate); // "Wednesday, March 15, 2023"
// Format with time
let dateTime = Utilities.formatDate(
date,
Session.getScriptTimeZone(),
"MMM d, yyyy 'at' h:mm a"
);
Logger.log("Date and time format: " + dateTime); // "Mar 15, 2023 at 2:30 PM"
}
Common Format Patterns
function basicFormattingExample() {
let date = new Date(2023, 2, 15, 14, 30, 45); // March 15, 2023, 2:30:45 PM
// Format date using Utilities.formatDate()
let formattedDate = Utilities.formatDate(
date,
Session.getScriptTimeZone(), // Uses the project's time zone
"yyyy-MM-dd HH:mm:ss"
);
Logger.log("Formatted date: " + formattedDate); // Example: "2023-03-15 14:30:45"
// Format as US date
let usDate = Utilities.formatDate(
date,
Session.getScriptTimeZone(),
"MM/dd/yyyy"
);
Logger.log("US date format: " + usDate); // "03/15/2023"
// Format as European date
let euDate = Utilities.formatDate(
date,
Session.getScriptTimeZone(),
"dd/MM/yyyy"
);
Logger.log("European date format: " + euDate); // "15/03/2023"
// Format with day name and month name
let longDate = Utilities.formatDate(
date,
Session.getScriptTimeZone(),
"EEEE, MMMM d, yyyy"
);
Logger.log("Long date format: " + longDate); // "Wednesday, March 15, 2023"
// Format with time
let dateTime = Utilities.formatDate(
date,
Session.getScriptTimeZone(),
"MMM d, yyyy 'at' h:mm a"
);
Logger.log("Date and time format: " + dateTime); // "Mar 15, 2023 at 2:30 PM"
}
Here are common date and time format patterns used with Utilities.formatDate()
:
Pattern | Description | Example |
---|---|---|
y | Year | 2023 |
yy | Year (2 digits) | 23 |
yyyy | Year (4 digits) | 2023 |
M | Month | 3 |
MM | Month (2 digits) | 03 |
MMM | Month (short name) | Mar |
MMMM | Month (full name) | March |
d | Day | 15 |
dd | Day (2 digits) | 15 |
E | Day of week (short) | Wed |
EEEE | Day of week (full) | Wednesday |
h | Hour (12-hour) | 2 |
hh | Hour (12-hour, 2 digits) | 02 |
H | Hour (24-hour) | 14 |
HH | Hour (24-hour, 2 digits) | 14 |
m | Minute | 30 |
mm | Minute (2 digits) | 30 |
s | Second | 45 |
ss | Second (2 digits) | 45 |
a | AM/PM | PM |
z | Time zone | PDT |
Z | Time zone offset | -0700 |
Example:function formatPatternsExample() {
// Show examples of various format patterns
let date = new Date(2023, 2, 15, 14, 30, 45); // March 15, 2023, 2:30:45 PM
let timezone = Session.getScriptTimeZone();
Logger.log("Full year (yyyy): " + Utilities.formatDate(date, timezone, "yyyy")); // 2023
Logger.log("Short year (yy): " + Utilities.formatDate(date, timezone, "yy")); // 23
Logger.log("Month (MM): " + Utilities.formatDate(date, timezone, "MM")); // 03
Logger.log("Month name (MMM): " + Utilities.formatDate(date, timezone, "MMM")); // Mar
Logger.log("Full month name (MMMM): " + Utilities.formatDate(date, timezone, "MMMM")); // March
Logger.log("Day (dd): " + Utilities.formatDate(date, timezone, "dd")); // 15
Logger.log("Weekday (E): " + Utilities.formatDate(date, timezone, "E")); // Wed
Logger.log("Full weekday (EEEE): " + Utilities.formatDate(date, timezone, "EEEE")); // Wednesday
Logger.log("Hour 24h (HH): " + Utilities.formatDate(date, timezone, "HH")); // 14
Logger.log("Hour 12h (hh): " + Utilities.formatDate(date, timezone, "hh")); // 02
Logger.log("AM/PM (a): " + Utilities.formatDate(date, timezone, "a")); // PM
Logger.log("Hour and minute (HH:mm): " + Utilities.formatDate(date, timezone, "HH:mm")); // 14:30
Logger.log("Full time (HH:mm:ss): " + Utilities.formatDate(date, timezone, "HH:mm:ss")); // 14:30:45
}
Parsing Dates from StringsSyntax
Utilities.parseDate(dateString, timeZone, format)
ParametersdateString: The string to parse
timeZone: Time zone ID (e.g., "GMT", "America/New_York")
format: Format pattern that matches the dateString
Returns
function formatPatternsExample() {
// Show examples of various format patterns
let date = new Date(2023, 2, 15, 14, 30, 45); // March 15, 2023, 2:30:45 PM
let timezone = Session.getScriptTimeZone();
Logger.log("Full year (yyyy): " + Utilities.formatDate(date, timezone, "yyyy")); // 2023
Logger.log("Short year (yy): " + Utilities.formatDate(date, timezone, "yy")); // 23
Logger.log("Month (MM): " + Utilities.formatDate(date, timezone, "MM")); // 03
Logger.log("Month name (MMM): " + Utilities.formatDate(date, timezone, "MMM")); // Mar
Logger.log("Full month name (MMMM): " + Utilities.formatDate(date, timezone, "MMMM")); // March
Logger.log("Day (dd): " + Utilities.formatDate(date, timezone, "dd")); // 15
Logger.log("Weekday (E): " + Utilities.formatDate(date, timezone, "E")); // Wed
Logger.log("Full weekday (EEEE): " + Utilities.formatDate(date, timezone, "EEEE")); // Wednesday
Logger.log("Hour 24h (HH): " + Utilities.formatDate(date, timezone, "HH")); // 14
Logger.log("Hour 12h (hh): " + Utilities.formatDate(date, timezone, "hh")); // 02
Logger.log("AM/PM (a): " + Utilities.formatDate(date, timezone, "a")); // PM
Logger.log("Hour and minute (HH:mm): " + Utilities.formatDate(date, timezone, "HH:mm")); // 14:30
Logger.log("Full time (HH:mm:ss): " + Utilities.formatDate(date, timezone, "HH:mm:ss")); // 14:30:45
}
Syntax
Utilities.parseDate(dateString, timeZone, format)
dateString: The string to parse
timeZone: Time zone ID (e.g., "GMT", "America/New_York")
format: Format pattern that matches the dateString
Returns
A Date
object representing the parsed date and time
Example:function parseDateExample() {
// Parse a date string with a specific format and time zone
let parsedDate = Utilities.parseDate(
"2023-03-15 14:30:00",
"GMT",
"yyyy-MM-dd HH:mm:ss"
);
Logger.log("Parsed date: " + parsedDate);
// Parse a US-formatted date
let usDate = Utilities.parseDate(
"03/15/2023",
Session.getScriptTimeZone(),
"MM/dd/yyyy"
);
Logger.log("Parsed US date: " + usDate);
// Parse a date with month name
let textDate = Utilities.parseDate(
"March 15, 2023",
Session.getScriptTimeZone(),
"MMMM d, yyyy"
);
Logger.log("Parsed text date: " + textDate);
// Flexible date parsing function
function tryParseDateFlexibly(dateString) {
// Common date formats to try
const formats = [
"yyyy-MM-dd",
"MM/dd/yyyy",
"dd/MM/yyyy",
"MMMM d, yyyy",
"MMM d, yyyy",
"yyyy-MM-dd'T'HH:mm:ss"
];
const timezone = Session.getScriptTimeZone();
// Try each format
for (let format of formats) {
try {
return Utilities.parseDate(dateString, timezone, format);
} catch (e) {
// Format didn't match, try the next one
continue;
}
}
// If none of the formats matched
throw new Error("Could not parse date: " + dateString);
}
// Test the flexible parsing
try {
Logger.log("Flexibly parsed ISO date: " + tryParseDateFlexibly("2023-03-15"));
Logger.log("Flexibly parsed US date: " + tryParseDateFlexibly("03/15/2023"));
Logger.log("Flexibly parsed text date: " + tryParseDateFlexibly("March 15, 2023"));
} catch (e) {
Logger.log("Error: " + e.message);
}
}
Part 4: Modifying DatesChanging Date Components
Syntax for setDatedate.setDate(dayValue)
Parameters:dayValue: A number from 1-31 representing the day of the month
Returns
function parseDateExample() {
// Parse a date string with a specific format and time zone
let parsedDate = Utilities.parseDate(
"2023-03-15 14:30:00",
"GMT",
"yyyy-MM-dd HH:mm:ss"
);
Logger.log("Parsed date: " + parsedDate);
// Parse a US-formatted date
let usDate = Utilities.parseDate(
"03/15/2023",
Session.getScriptTimeZone(),
"MM/dd/yyyy"
);
Logger.log("Parsed US date: " + usDate);
// Parse a date with month name
let textDate = Utilities.parseDate(
"March 15, 2023",
Session.getScriptTimeZone(),
"MMMM d, yyyy"
);
Logger.log("Parsed text date: " + textDate);
// Flexible date parsing function
function tryParseDateFlexibly(dateString) {
// Common date formats to try
const formats = [
"yyyy-MM-dd",
"MM/dd/yyyy",
"dd/MM/yyyy",
"MMMM d, yyyy",
"MMM d, yyyy",
"yyyy-MM-dd'T'HH:mm:ss"
];
const timezone = Session.getScriptTimeZone();
// Try each format
for (let format of formats) {
try {
return Utilities.parseDate(dateString, timezone, format);
} catch (e) {
// Format didn't match, try the next one
continue;
}
}
// If none of the formats matched
throw new Error("Could not parse date: " + dateString);
}
// Test the flexible parsing
try {
Logger.log("Flexibly parsed ISO date: " + tryParseDateFlexibly("2023-03-15"));
Logger.log("Flexibly parsed US date: " + tryParseDateFlexibly("03/15/2023"));
Logger.log("Flexibly parsed text date: " + tryParseDateFlexibly("March 15, 2023"));
} catch (e) {
Logger.log("Error: " + e.message);
}
}
Changing Date Components
date.setDate(dayValue)
Parameters:dayValue: A number from 1-31 representing the day of the month
Returns
dayValue: A number from 1-31 representing the day of the month
The number of milliseconds since January 1, 1970, 00:00:00 UTC
Note
Similar syntax applies for setMonth()
, setFullYear()
, setHours()
, etc.
Example:function modifyDateComponentsExample() {
// Create a date to modify
let date = new Date(2023, 2, 15); // March 15, 2023
// Change the day of the month
date.setDate(20);
Logger.log("After setting date to 20: " + date); // March 20, 2023
// Change the month
date.setMonth(4);
Logger.log("After setting month to 4 (May): " + date); // May 20, 2023
// Change the year
date.setFullYear(2024);
Logger.log("After setting year to 2024: " + date); // May 20, 2024
// Change the time (hours, minutes, seconds)
date.setHours(10, 15, 30);
Logger.log("After setting time to 10:15:30: " + date); // May 20, 2024, 10:15:30 AM
// IMPORTANT: Date objects are mutable - they change when modified
// This can cause unexpected behaviors if you're not careful
}
Adding Days to a Date
function modifyDateComponentsExample() {
// Create a date to modify
let date = new Date(2023, 2, 15); // March 15, 2023
// Change the day of the month
date.setDate(20);
Logger.log("After setting date to 20: " + date); // March 20, 2023
// Change the month
date.setMonth(4);
Logger.log("After setting month to 4 (May): " + date); // May 20, 2023
// Change the year
date.setFullYear(2024);
Logger.log("After setting year to 2024: " + date); // May 20, 2024
// Change the time (hours, minutes, seconds)
date.setHours(10, 15, 30);
Logger.log("After setting time to 10:15:30: " + date); // May 20, 2024, 10:15:30 AM
// IMPORTANT: Date objects are mutable - they change when modified
// This can cause unexpected behaviors if you're not careful
}
The function addDays(date, days)
demonstrates how to add (or subtract) days from a date.
Note: This is a custom function and is not a built-in method of the Date
object.
Parametersdate: The starting Date object
days: The number of days to add (positive) or subtract (negative).
Returns
date: The starting Date object
days: The number of days to add (positive) or subtract (negative).
A new Date
object representing the result of adding or subtracting the specified number of days.
function addDaysExample() {
// Function to add days to a date
function addDays(date, days) {
// Create a copy of the original date
let result = new Date(date);
// Add the specified number of days
result.setDate(result.getDate() + days);
return result;
}
// Example usage
let today = new Date();
let tomorrow = addDays(today, 1);
Logger.log("Tomorrow: " + tomorrow);
let nextWeek = addDays(today, 7);
Logger.log("Next week: " + nextWeek);
let yesterday = addDays(today, -1);
Logger.log("Yesterday: " + yesterday);
}
Adding Months to a Date
The function addMonths(date, months)
demonstrates how to add (or subtract) months from a date.
Note: This is a custom function and is not a built-in method of the Date
object.
Parametersdate: The starting Date object
months: The number of months to add (positive) or subtract (negative)
Returns
date: The starting Date object
months: The number of months to add (positive) or subtract (negative)
A new Date
object with months added
function addMonthsExample() {
// Function to add months to a date
function addMonths(date, months) {
// Create a copy of the original date
let result = new Date(date);
// Add the specified number of months
result.setMonth(result.getMonth() + months);
return result;
}
// Example usage
let today = new Date();
let nextMonth = addMonths(today, 1);
Logger.log("Next month: " + nextMonth);
let lastMonth = addMonths(today, -1);
Logger.log("Last month: " + lastMonth);
let nextYear = addMonths(today, 12);
Logger.log("Next year: " + nextYear);
}
Working with Month Boundaries
The monthBoundariesExample
function demonstrates how to determine the first and last days of a given month, and subsequently, how to calculate the number of days within that month. It utilizes two helper functions: firstDayOfMonth
which returns the first day of the month for a given date, and lastDayOfMonth
which returns the last day of the month. The example then logs the first day, last day, and the total number of days in the current month.
function monthBoundariesExample() {
// Function to get the first day of a month
function firstDayOfMonth(date) {
// Create a copy of the original date
let result = new Date(date);
// Set the day to 1
result.setDate(1);
return result;
}
// Function to get the last day of a month
function lastDayOfMonth(date) {
// Create a copy of the original date
let result = new Date(date);
// Set to first day of next month, then subtract one day
result.setMonth(result.getMonth() + 1, 0);
return result;
}
// Example usage
let today = new Date();
let firstDay = firstDayOfMonth(today);
Logger.log("First day of current month: " + firstDay);
let lastDay = lastDayOfMonth(today);
Logger.log("Last day of current month: " + lastDay);
// Get the number of days in the current month
let daysInMonth = lastDay.getDate();
Logger.log("Days in current month: " + daysInMonth);
}
Part 5: Date CalculationsCalculate Days Between Dates
The function daysBetween(date1, date2)
returns the number of days between the two dates.
Note: This is a custom function and is not a built-in method of the Date
object.
Parametersdate1: First Date object
date2: Second Date object
Returns
date1: First Date object
date2: Second Date object
Number of days between the two dates
function daysBetweenExample() {
// Function to calculate days between two dates
function daysBetween(date1, date2) {
// Convert both dates to milliseconds
let date1Ms = date1.getTime();
let date2Ms = date2.getTime();
// Calculate the difference in milliseconds
let differenceMs = Math.abs(date1Ms - date2Ms);
// Convert the difference to days
return Math.floor(differenceMs / (1000 * 60 * 60 * 24));
}
// Example usage
let date1 = new Date(2023, 0, 1); // January 1, 2023
let date2 = new Date(2023, 0, 15); // January 15, 2023
let days = daysBetween(date1, date2);
Logger.log("Days between: " + days); // 14
}
Calculate Age from Birth Date
The function calculateAge(birthDate)
calculates the current age in years.
Note: This is a custom function and is not a built-in method of the Date
object.
ParametersbirthDate: Date object representing the birth date
Returns
birthDate: Date object representing the birth date
Current age in years
function calculateAgeExample() {
// Function to calculate age based on birth date
function calculateAge(birthDate) {
let today = new Date();
let age = today.getFullYear() - birthDate.getFullYear();
// Adjust age if birthday hasn't occurred yet this year
let m = today.getMonth() - birthDate.getMonth();
if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
age--;
}
return age;
}
// Example usage
let birthDate = new Date(1990, 5, 15); // June 15, 1990
let age = calculateAge(birthDate);
Logger.log("Age: " + age);
}
Format a Duration as HH:MM:SS
The function formatDuration(milliseconds)
returns a duration (given in milliseconds) formatted as HH:MM:SS
Note: This is a custom function and is not a built-in method of the Date
object.
Parametersmilliseconds: Duration in milliseconds
Returns
milliseconds: Duration in milliseconds
Formatted string in HH:MM:SS format
function formatDurationExample() {
// Function to format milliseconds as HH:MM:SS
function formatDuration(milliseconds) {
let seconds = Math.floor(milliseconds / 1000);
let minutes = Math.floor(seconds / 60);
let hours = Math.floor(minutes / 60);
seconds = seconds % 60;
minutes = minutes % 60;
// Pad with leading zeros if needed
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
return hours + ":" + minutes + ":" + seconds;
}
// Example usage
let start = new Date(2023, 0, 1, 10, 0, 0); // Jan 1, 2023, 10:00 AM
let end = new Date(2023, 0, 1, 12, 30, 45); // Jan 1, 2023, 12:30:45 PM
let diffMs = end.getTime() - start.getTime();
Logger.log("Formatted duration: " + formatDuration(diffMs)); // "02:30:45"
}
Check for Leap Year
The function isLeapYear(year)
returns true
if the given year is a leap year, and false
otherwise.
Note: This is a custom function and is not a built-in method of the Date
object.
Parametersyear: The year to check
Returns
year: The year to check
Boolean
- true
if it's a leap year, false
otherwise
function isLeapYearExample() {
// Function to determine if a year is a leap year
function isLeapYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
}
// Example usage
Logger.log("Is 2023 a leap year? " + isLeapYear(2023)); // false
Logger.log("Is 2024 a leap year? " + isLeapYear(2024)); // true
Logger.log("Is 2000 a leap year? " + isLeapYear(2000)); // true
Logger.log("Is 1900 a leap year? " + isLeapYear(1900)); // false
}
Part 6: Working with Time ZonesGetting and Using Time Zones
The timeZoneBasicsExample
function demonstrates how to work with time zones in Apps Script. It retrieves the script's configured time zone using Session.getScriptTimeZone()
and then uses Utilities.formatDate()
to format the current date and time (now
) into different time zones: the script's time zone, GMT, America/New_York, and Asia/Tokyo. The function logs the resulting formatted date strings for each time zone, showing how the same moment in time appears differently based on the chosen time zone.
function timeZoneBasicsExample() {
let now = new Date();
// Get the script's time zone
let scriptTimezone = Session.getScriptTimeZone();
Logger.log("Script timezone (from project settings): " + scriptTimezone);
// Format a date in different time zones
let dateInScriptTz = Utilities.formatDate(
now,
scriptTimezone,
"yyyy-MM-dd HH:mm:ss"
);
Logger.log("Date in script timezone: " + dateInScriptTz);
let dateInGMT = Utilities.formatDate(
now,
"GMT",
"yyyy-MM-dd HH:mm:ss"
);
Logger.log("Date in GMT: " + dateInGMT);
let dateInNY = Utilities.formatDate(
now,
"America/New_York",
"yyyy-MM-dd HH:mm:ss"
);
Logger.log("Date in New York: " + dateInNY);
let dateInTokyo = Utilities.formatDate(
now,
"Asia/Tokyo",
"yyyy-MM-dd HH:mm:ss"
);
Logger.log("Date in Tokyo: " + dateInTokyo);
}
Converting Between Time Zones
The function convertTimezone(date, fromTimezone, toTimezone)
converts a Date
object from one time zone to another.
Parametersdate: The Date object to convert
fromTimezone: Original time zone ID
toTimezone: Target time zone ID
Returns
date: The Date object to convert
fromTimezone: Original time zone ID
toTimezone: Target time zone ID
A Date
object adjusted to the new time zone
function convertTimeZoneExample() {
// Function to convert a date from one time zone to another
function convertTimezone(date, fromTimezone, toTimezone) {
// Format in the original timezone
let dateString = Utilities.formatDate(
date,
fromTimezone,
"yyyy-MM-dd HH:mm:ss"
);
// Parse the string in the new timezone
return Utilities.parseDate(
dateString,
toTimezone,
"yyyy-MM-dd HH:mm:ss"
);
}
// Example usage
let myDate = new Date();
Logger.log("Original date: " + myDate);
let dateInTokyo = convertTimezone(myDate, "America/New_York", "Asia/Tokyo");
Logger.log("Converted to Tokyo time: " + dateInTokyo);
let dateInLondon = convertTimezone(myDate, "America/New_York", "Europe/London");
Logger.log("Converted to London time: " + dateInLondon);
}
Why Are My Converted Times Still Showing in Your Timezone?
The reason you're seeing all the logged dates in your timezone despite attempting to convert to Tokyo and London time is because of how Logger.log()
displays Date objects.
Of course, if your time zone is Tokyo or London, then the time zone displayed will appear correct, but this is coincidental because your time zone happened to be the same as the one you were converting the date to.
Here's the breakdown:
The Conversion is Happening: The
convertTimezone
function is correctly converting the time. TheUtilities.formatDate
andUtilities.parseDate
functions are doing their job.Logger.log()
andDate
Objects: When you log aDate
object usingLogger.log()
, it doesn't display the date in the time zone you converted to. Instead, it displays the date using the time zone of the script execution environment.The Underlying
Date
Object: TheDate
object itself stores a point in time as milliseconds since the Unix epoch (January 1, 1970, 00:00:00 UTC). It doesn't inherently "have" a time zone. The time zone is only relevant when you format the date for display.
Part 7: Common Pitfalls and Best PracticesRemember: Months are 0-indexed
The monthsZeroIndexedExample
function demonstrates an important quirk of JavaScript dates: month numbers are zero-indexed. This means January is 0, February is 1, and so on. The example shows how this can lead to confusion and provides a helper function (createDate
) that allows you to use 1-indexed month numbers for clearer code.
function monthsZeroIndexedExample() {
// This is February 15, not January 15
let date = new Date(2023, 1, 15);
Logger.log("Month (0-indexed): " + date.getMonth()); // 1 (February)
// Helper function for clearer code
function createDate(year, month, day) {
// Adjust month to be 1-indexed for better readability
return new Date(year, month - 1, day);
}
// Now this is February 15
let betterDate = createDate(2023, 2, 15);
Logger.log("Better date: " + betterDate);
}
Copy Dates to Avoid Accidental Changes
The copyDatesExample
function demonstrates the correct way to copy Date
objects in JavaScript. It highlights that simply assigning a Date
object to a new variable does not create a copy; both variables will reference the same underlying Date
object. To create a true copy, you need to use the new Date(originalDate)
constructor. This ensures that modifying one date does not affect the other.
function copyDatesExample() {
// WRONG: This modifies the original date
function wrongWayExample() {
let originalDate = new Date(2023, 0, 15);
let modifiedDate = originalDate; // This doesn't create a copy!
modifiedDate.setDate(20);
Logger.log("Original date after modification: " + originalDate); // Jan 20, not Jan 15
}
// CORRECT: Create a new copy
function correctWayExample() {
let safeOriginalDate = new Date(2023, 0, 15);
let safeModifiedDate = new Date(safeOriginalDate); // This creates a proper copy
safeModifiedDate.setDate(20);
Logger.log("Safe original date: " + safeOriginalDate); // Still Jan 15
Logger.log("Safe modified date: " + safeModifiedDate); // Jan 20
}
wrongWayExample();
correctWayExample();
}
Date Rollover is Automatic
The dateRolloverExample
function demonstrates how JavaScript handles "date rollover." When you set the date to a value that exceeds the number of days in the month, it automatically rolls over to the next month. This behavior is used to create a lastDayOfMonth
function, which cleverly calculates the last day of any month, including correctly handling leap years.
function dateRolloverExample() {
// Setting February 28 to day 31 rolls over to March 3
let endOfMonth = new Date(2023, 1, 28); // Feb 28
endOfMonth.setDate(31);
Logger.log("After setting Feb date to 31: " + endOfMonth); // Mar 3
// This behavior can be useful for finding the last day of a month
function lastDayOfMonth(year, month) {
// Create date for first day of next month, then go back one day
return new Date(year, month, 0).getDate();
}
Logger.log("Days in February 2023: " + lastDayOfMonth(2023, 2)); // 28
Logger.log("Days in February 2024: " + lastDayOfMonth(2024, 2)); // 29 (leap year)
}
Escape Special Characters in Format Strings
The escapeFormatStringExample
function demonstrates how to correctly escape special characters when using Utilities.formatDate()
. It shows that attempting to use the unescaped letter 'T' in the format string (common in ISO 8601) will result in an error. To avoid this, you need to escape the 'T' with single quotes (e.g., yyyy-MM-dd'T'HH:mm:ss
). This ensures that the 'T' is treated as a literal character and not as a special formatting symbol.
function escapeFormatStringExample() {
// WRONG: Will throw an error
function badFormatExample() {
try {
let badFormat = Utilities.formatDate(new Date(), "UTC", "yyyy-MM-ddTHH:mm:ss");
} catch(e) {
Logger.log("Error with format string: " + e.message);
}
}
// CORRECT: Escape 'T' with single quotes
function goodFormatExample() {
let goodFormat = Utilities.formatDate(new Date(), "UTC", "yyyy-MM-dd'T'HH:mm:ss");
Logger.log("Correctly formatted ISO-like date: " + goodFormat);
}
badFormatExample();
goodFormatExample();
}
Conclusion
In this guide I showed you how to work with dates in Google Apps Script, from basic creation and formatting to more practical applications. Here are the key points to remember:
Set the correct project time zone to ensure consistent date behavior
Months are zero-indexed (0=January, 11=December) when creating dates
Always create copies of dates to avoid unintended changes
Use
Utilities.formatDate() and Utilities.parseDate()
for consistent resultsSpecify time zones explicitly when formatting or parsing dates
Escape special characters in format patterns using single quotes
Date objects are mutable - they change when modified
By using these techniques, you can confidently work with dates in your Google Apps Script projects for Sheets, Calendar, Drive, and other Google Workspace services.,
Small Scripts, Big Impact
Join 1,500+ professionals who are supercharging their productivity with Google Sheets automation
By subscribing, you agree to our Privacy Policy and Terms of Service