Praca z datami i godzinami

Skrypty Google Ads często muszą mieć podaną datę i godzinę. Typowym zastosowaniem jest pobieranie raportów dla określonego zakresu dat, planowanie wyświetlania kampanii lub grup reklam w określonych godzinach, a także przesyłanie do arkusza kalkulacyjnego informacji o czasie ostatniego uruchomienia skryptu. W tym przewodniku opisujemy ważne pojęcia, typowe błędy i zalecane sposoby korzystania z dat i godzin w skryptach Google Ads.

Podstawowe pojęcia

Aby korzystać z dat i godzin w skryptach Google Ads, użyj wbudowanego obiektu daty w JavaScript. Obiekt daty w JavaScripcie reprezentuje konkretny moment w czasie. Nowy obiekt daty można utworzyć na kilka sposobów:

// 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);

Nowi użytkownicy skryptów często nie są pewni, jak obiekty daty obsługują strefy czasowe. Naturalnym, ale nieprawidłowym sposobem rozumienia obiektu daty jest godzina na zegarze w obrębie jednej strefy czasowej. Na przykład w powyższym fragmencie kodu niektórzy użytkownicy błędnie założą, że właściwość date jest prawidłowa tylko w 1 strefie czasowej, czyli strefie czasowej z przesunięciem o -5 godzin użytej do jej utworzenia. W takim pomylonym widoku należałoby „przekonwertować” dane typu date, aby można było ich używać w innych strefach czasowych.

Zamiast tego prawidłowym sposobem myślenia o obiekcie daty jest konkretny moment w czasie niezależny od strefy czasowej. Konkretny moment jest inaczej wyświetlany na zegarach w różnych strefach czasowych, ale jest to ten sam moment. Weźmy na przykład ten fragment kodu:

// 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);

Obiekt daty reprezentuje konkretny moment w czasie, więc nie trzeba go „konwertować” w różnych strefach czasowych. Mogą być natomiast renderowane jako ciąg znaków sformatowany dla określonej strefy czasowej.

Aby wyrenderować datę jako ciąg znaków o określonym formacie i strefie czasowej, użyj funkcji Utilities.formatDate(date, timeZone, format). Na przykład:

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\''));

W tych przykładach strefa czasowa została określona bezpośrednio za pomocą identyfikatora strefy czasowej. Aby pobrać strefę czasową powiązaną z kontem Google Ads, na którym uruchomiono skrypt, użyj parametru AdsApp.currentAccount().getTimeZone().

Częste problemy

Domyślna strefa czasowa podczas rejestrowania obiektu daty

W przypadku bezpośredniego logowania obiektu daty za pomocą Logger.log() jest on renderowany z użyciem formatu domyślnego i strefy czasowej. Na przykład:

const date = new Date('February 17, 2021 13:00:00 -0500');

// Wed Feb 17 10:00:00 GMT-08:00 2021
console.log(date);

Domyślna strefa czasowa to America/Los_Angeles (czas pacyficzny) – niezależnie od strefy czasowej powiązanej z kontem Google Ads. Jeśli chcesz renderować obiekt daty jako ciąg znaków z użyciem formatu niestandardowego i strefy czasowej do logowania lub do innych celów, zawsze używaj Utilities.formatDate(date, timeZone, format).

Domyślna strefa czasowa podczas tworzenia obiektu daty

Gdy tworzysz obiekt daty za pomocą ciągu znaków, który nie określa przesunięcia strefy czasowej, przyjmuje się, że strefa czasowa to America/Los_Angeles (czas pacyficzny), niezależnie od strefy czasowej powiązanej z kontem Google Ads. Przykład:

// 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);

Gdy tworzysz obiekt daty za pomocą ciągu znaków, zawsze uwzględniaj przesunięcie strefy czasowej, aby mieć pewność, że obiekt daty przedstawia odpowiedni moment.

Domyślna strefa czasowa w metodach obiektów daty

Obiekty daty JavaScriptu mają kilka metod, które wykorzystują domyślną strefę czasową, np.:

  • getFullYear()
  • getMonth()
  • getDate()
  • getDay()
  • getHours()
  • getMinutes()

Obejmuje to również odpowiedniki tych metod w formacie set___() (np. setMonth()) i metody getTimezoneOffset().

W skryptach Google Ads domyślna strefa czasowa to America/Los_Angeles (czas pacyficzny) – niezależnie od strefy czasowej powiązanej z kontem Google Ads. Jeśli Twoje konto Google Ads nie znajduje się w tej strefie czasowej, zazwyczaj nie korzystaj z tych metod.

Aby uzyskać rok, miesiąc, datę, dzień, godziny lub minuty dla obiektu daty w strefie czasowej konta, użyj Utilities.formatDate(date, timeZone, format) z formatem określającym część daty lub godziny oraz użyj AdsApp.currentAccount().getTimeZone(), aby ustawić strefę czasową konta.

Tworzenie obiektu daty na podstawie sformatowanego ciągu daty

Obiekt daty możesz utworzyć, przekazując sformatowany ciąg daty do konstruktora daty. Na przykład:

const date = new Date('February 17, 2021 13:00:00 -0500');

Konstruktor może analizować tylko określone formaty ciągów dat. Aby ciąg daty był poprawnie analizowany, zawsze podawaj go w formacie MMMM dd, yyyy HH:mm:ss Z.

Aby np. utworzyć obiekt daty na dzisiejszą południe w strefie czasowej bieżącego konta:

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);

Nie używaj wzorca „z” do tworzenia ciągów dat, które będą przekazywane do konstruktora dat, ponieważ konstruktor nie zawsze może go przeanalizować. Używaj tylko wzoru „Z”.

Matematyka daty

Niektóre skrypty muszą wykonywać proste obliczenia matematyczne z datami, np. ustalić datę X dni przed podaną datą lub po niej. Podczas matematyki związanej z datami używaj funkcji getTime(). Wywołanie getTime() w obiekcie daty zwraca liczbę milisekund od początku 1 stycznia 1970 r. czasu UTC. Możesz wykonać obliczenia matematyczne na tej wartości, a potem zastosować nową do obiektu daty za pomocą funkcji setTime() lub podając ją jako parametr podczas tworzenia nowego obiektu daty.

Na przykład:

const MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
const now = new Date();
const yesterday = new Date(now.getTime() - MILLIS_PER_DAY);

W tym przykładzie wartość yesterday miała miejsce dokładnie 24 godziny temu.

Raportowanie

Podczas pobierania raportu za pomocą funkcji AdsApp.search() zapytanie GAQL wymaga określenia dat w formacie yyyy-MM-dd (np. 2021-06-30 to 30 czerwca 2021 r.).

Podobnie metoda getStatsFor() dostępna w wielu obiektach skryptów Google Ads wymaga określenia dat w tym samym formacie. Aby sformatować obiekt daty w tym formacie, użyj Utilities.formatDate(date, timeZone, format).

Aby np. pobrać raport sprzed 1–3 dni:

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'));

Arkusze kalkulacyjne

Skrypty Google Ads często zapisują w arkuszu kalkulacyjnym dane wyjściowe, w tym obiekty dat. Gdy ustawisz komórkę w arkuszu kalkulacyjnym, przekazując obiekt daty, do interpretacji tej daty używana jest strefa czasowa arkusza kalkulacyjnego. Załóżmy na przykład, że mamy arkusz kalkulacyjny ze strefą czasową ustawioną na czas pacyficzny:

// Suppose today is February 17, 2021 13:00:00 -0500 (Eastern Time)
const now = new Date();
spreadsheet.getRange('A1').setValue(now);

Wartość w komórce A1 to 17-Feb-21 10:00:00.

Aby mieć pewność, że obiekty dat są zapisywane w arkuszu kalkulacyjnym zgodnie z oczekiwaniami, ustaw strefę czasową arkusza kalkulacyjnego tak, aby odpowiadała strefie czasowej konta Google Ads:

spreadsheet.setSpreadsheetTimeZone(AdsApp.currentAccount().getTimeZone());

Możesz też ustawić czas w arkuszu kalkulacyjnym ręcznie.