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

غالبًا ما تحتاج النصوص البرمجية في "إعلانات 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);

غالبًا ما يرتبك مستخدمو النصوص البرمجية الجدد بشأن كيفية تعامل كائنات التاريخ مع المناطق الزمنية. هناك طريقة طبيعية ولكنها غير صحيحة للتفكير في عنصر التاريخ هي الوقت المحدد في ساعة في منطقة زمنية واحدة. على سبيل المثال، في المقتطف أعلاه، يفترض بعض المستخدمين عن طريق الخطأ أنّ السمة 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);

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

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

عند إنشاء عنصر تاريخ باستخدام سلسلة لا توفّر معادلة للمنطقة الزمنية، يُفترض أن تكون المنطقة الزمنية هي أمريكا/لوس أنجلوس (توقيت المحيط الهادئ)، بغض النظر عن المنطقة الزمنية المرتبطة بحساب "إعلانات 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".

صيغة التاريخ

تحتاج بعض النصوص إلى إجراء عمليات حسابية بسيطة بالتواريخ، مثل العثور على تاريخ قبل أو بعده بيوم معين من تاريخ. عند إجراء العمليات الحسابية للتاريخ، استخدِم getTime(). يؤدي استدعاء getTime() في كائن تاريخ إلى عرض عدد المللي ثانية منذ بداية 1 كانون الثاني (يناير) 1970 بالتوقيت العالمي المنسق (UTC). يمكنك إجراء عملية حسابية على هذه القيمة، ثم تطبيق القيمة الجديدة على كائن تاريخ باستخدام السمة 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());

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