التعامل مع التواريخ والأوقات

غالبًا ما تحتاج نصوص "إعلانات Google" إلى العمل مع التواريخ والأوقات. وتشمل حالات الاستخدام الشائعة استرجاع التقارير لنطاق زمني محدد، وجدولة الحملات أو المجموعات الإعلانية للتشغيل في أوقات محددة، وإخراج وقت تشغيل النص البرمجي إلى جدول بيانات آخر مرة. يصف هذا الدليل المفاهيم المهمة، والمشاكل الشائعة، والمنهجيات المقترَحة عند العمل مع التواريخ والأوقات في ملفّات برمجية "إعلانات Google".

المفاهيم الأساسية

للعمل مع التواريخ والأوقات في نصوص "إعلانات Google" البرمجية، استخدِم عنصر تاريخ المضمّن في JavaScript. يمثّل عنصر التاريخ في JavaScript لحظة معيّنة من الوقت. هناك عدة طرق لإنشاء عنصر تاريخ جديد:

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

غالبًا ما يشعر مستخدمو Scripts الجدد بالارتباك بشأن كيفية تعامل عناصر التاريخ مع المناطق الزمنية. إنّ الطريقة الطبيعية ولكن غير الصحيحة للتفكير في عنصر التاريخ هي الوقت على الساعة في منطقة زمنية واحدة. على سبيل المثال، في المقتطف أعلاه، يفترض بعض المستخدمين بغير وعي أنّ date صالحة في منطقة زمنية واحدة فقط، وهي المنطقة الزمنية التي تم استخدامها لإنشائها والتي تتضمن فرقًا زمنيًا قدره -5 ساعات. في طريقة العرض الخاطئة هذه، يجب "تحويل" date لاستخدامه في مناطق زمنية أخرى.

بدلاً من ذلك، فإنّ الطريقة الصحيحة للتفكير في عنصر التاريخ هي أنّه لحظة معيّنة في الوقت مستقلة عن أي منطقة زمنية. رغم أن لحظة معينة تظهر بشكل مختلف على الساعات في مناطق زمنية مختلفة، إلا أنها نفس اللحظة. على سبيل المثال، راجِع المقتطف التالي:

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

بما أنّ كائن التاريخ يمثّل لحظة معيّنة في الوقت، لا يلزم "تحويله" في جميع المناطق الزمنية. بدلاً من ذلك، يمكن عرضها كسلسلة يتم تنسيقها لمنطقة زمنية معيّنة.

لعرض تاريخ كسلسلة بتنسيق ومنطقة زمنية معيّنين، استخدِم Utilities.formatDate(date, timeZone, format). على سبيل المثال:

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

حدّدت هذه الأمثلة المنطقة الزمنية مباشرةً باستخدام رقم تعريف المنطقة الزمنية. لاسترداد المنطقة الزمنية المرتبطة بحساب "إعلانات Google" الذي يشغّل النص البرمجي، استخدِم AdsApp.currentAccount().getTimeZone().

الصعوبات الشائعة

المنطقة الزمنية التلقائية عند تسجيل عنصر تاريخ

عند تسجيل عنصر تاريخ مباشرةً باستخدام Logger.log()، يتم عرضه باستخدام تنسيق تلقائي ومنطقة زمنية. على سبيل المثال:

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

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

المنطقة الزمنية التلقائية هي America/Los_Angeles (التوقيت حسب المحيط الهادئ)، بغض النظر عن المنطقة الزمنية المرتبطة بحساب "إعلانات Google". إذا كنت تريد عرض عنصر التاريخ كسلسلة باستخدام تنسيق ومنطقة زمنية مخصّصَين للتسجيل أو لأغراض أخرى، استخدِم دائمًا Utilities.formatDate(date, timeZone, format).

المنطقة الزمنية التلقائية عند إنشاء عنصر تاريخ

عند إنشاء عنصر تاريخ باستخدام سلسلة لا تقدّم توقيتًا زمنيًا أو فرقًا زمنيًا، يُفترض أنّ المنطقة الزمنية هي America/Los_Angeles (توقيت المحيط الهادئ)، بغض النظر عن المنطقة الزمنية المرتبطة بحساب "إعلانات Google". على سبيل المثال:

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

عند إنشاء عنصر تاريخ باستخدام سلسلة، يجب دائمًا تضمين توقيت المنطقة الزمنية لضمان أن يمثّل عنصر التاريخ اللحظة التي تريدها فعليًا.

المنطقة الزمنية التلقائية في طرق عنصر التاريخ

تحتوي كائنات التواريخ في JavaScript على عدة طرق تفترض وجود منطقة زمنية تلقائية، مثل:

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

ويشمل ذلك أيضًا طرق الدفع المشابهة set___() (مثل setMonth()) وgetTimezoneOffset().

في نصوص "إعلانات Google" البرمجية، تكون المنطقة الزمنية التلقائية هي أمريكا/لوس_أنجلوس (المحيط الهادئ)، بغض النظر عن المنطقة الزمنية المرتبطة بحساب "إعلانات Google". وبالتالي، إذا لم يكن حسابك على "إعلانات Google" في هذه المنطقة الزمنية، عليك تجنُّب استخدام هذه الطرق بوجه عام.

للحصول على السنة أو الشهر أو التاريخ أو اليوم أو الساعات أو الدقائق لعنصر تاريخ في المنطقة الزمنية لحسابك، استخدِم Utilities.formatDate(date, timeZone, format) بتنسيق يحدّد الجزء من التاريخ أو الوقت الذي تريده، واستخدِم AdsApp.currentAccount().getTimeZone() للحصول على المنطقة الزمنية لحسابك.

إنشاء عنصر تاريخ من سلسلة تاريخ منسَّقة

يمكنك إنشاء كائن تاريخ عن طريق تمرير سلسلة تاريخ منسقة إلى دالة إنشاء التاريخ. على سبيل المثال:

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

يمكن للدالة الإنشائية تحليل تنسيقات سلسلة تاريخ معينة فقط. للتأكّد من تحليل سلسلة التاريخ بشكل صحيح، يجب تقديمها دائمًا بتنسيق MMMM dd, yyyy HH:mm:ss Z.

على سبيل المثال، لإنشاء عنصر تاريخ لظهر اليوم في المنطقة الزمنية للحساب الحالي:

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

لا تستخدم النمط 'z' لإنشاء سلاسل التاريخ التي سيتم تمريرها إلى الدالة الإنشائية للتاريخ، حيث لن تكون الدالة الإنشائية قادرة دائمًا على تحليلها. استخدِم فقط نمط "Z".

حساب التاريخ

تحتاج بعض النصوص البرمجية إلى إجراء عمليات حسابية بسيطة باستخدام التواريخ، مثل العثور على تاريخ قبل X يوم أو بعده. استخدِم getTime() عند إجراء عمليات حسابية على التواريخ. يؤدي استدعاء getTime() على عنصر تاريخ إلى عرض عدد المللي ثانية منذ بداية 1 كانون الثاني (يناير) 1970 بالتوقيت العالمي المنسق. يمكنك إجراء عملية حسابية على هذه القيمة، ثم تطبيق القيمة الجديدة على عنصر تاريخ باستخدام setTime() أو تقديمها كمَعلمة عند إنشاء عنصر تاريخ جديد.

على سبيل المثال:

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

في هذا المثال، تمثّل السمة yesterday قبل 24 ساعة بالضبط.

إعداد التقارير

عند استرداد تقرير باستخدام AdsApp.search()، يتطلب طلب البحث GAQL تحديد التواريخ بالتنسيق yyyy-MM-dd (على سبيل المثال، 2021-06-30 هو 30 حزيران (يونيو) 2021).

وبالمثل، تتطلّب طريقة getStatsFor() المتاحة في العديد من نصوص "إعلانات Google" العناصر تحديد التواريخ بالتنسيق نفسه. يمكنك استخدام Utilities.formatDate(date, timeZone, format) لتنسيق عنصر تاريخ بهذا التنسيق.

على سبيل المثال، لاسترداد تقرير من يوم إلى ثلاثة أيام:

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

جداول البيانات

وغالبًا ما تكتب نصوص "إعلانات Google" البرمجية مخرجات في جدول بيانات، بما في ذلك كائنات التاريخ. عند ضبط خلية في جدول بيانات من خلال تمرير عنصر تاريخ، يتم استخدام المنطقة الزمنية لجدول البيانات لتفسير هذا التاريخ. على سبيل المثال، لنفترض أنّه لدينا جدول بيانات تم ضبط منطقته الزمنية على توقيت المحيط الهادئ:

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

ستكون القيمة في A1‏ ‎17-شباط(فبراير)-21 10:00:00.

لضمان كتابة عناصر التاريخ في جدول بيانات على النحو المتوقّع، اضبط المنطقة الزمنية لجدول البيانات لتتطابق مع المنطقة الزمنية لحسابك على "إعلانات Google":

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

يمكنك أيضًا ضبط وقت جدول البيانات يدويًا.