إزاحة صفرية غيرت تاريخ البداية في مثالنا؛ الترحيل سبق العد.
افصل الترحيل عن الإزاحة
busday_offset ترحّل البداية إلى يوم صالح أولًا، ثم تعد الإزاحة بالأيام الصالحة. [1]
weekmask يرتب الأيام من الاثنين إلى الأحد؛ holidays تحدد تواريخ غير صالحة. [1]
سنستعمل تقويمًا مؤلفًا: قناع 1010100، أي الاثنين والأربعاء والجمعة، مع تاريخ مستبعد واحد هو 2026-10-09. لا تمثل هذه الشروط مؤسسة أو بلدًا أو جدول عطلات رسميًا.
في NumPy 2.3.5 على CPython 3.12.14، أنشأنا D=np.array("2026-10-10",dtype="datetime64[D]")، وH=np.array(["2026-10-09"],dtype="datetime64[D]"). المدخل D قيمة مفردة بشكل ()، ومصفوفة H ذات شكل (1,).
حسب weekday في مرجع Python، يوم البداية 10 أكتوبر سبت، ويوم الاستبعاد 9 أكتوبر جمعة. السبت غير مختار بالقناع، والجمعة المذكورة مستبعدة رغم أن القناع يختار يوم الجمعة عادةً.
نقارن roll="forward" وroll="backward" مع offsets من -1 وصفر و+1. نحفظ اتجاه الترحيل وقيمة الإزاحة في حقلين؛ فقد يتقدم الترحيل في التاريخ ثم تعد الإزاحة إلى الخلف.
الصفر يكشف نقطة بدء العد
نفذنا np.busday_offset(D,0,roll="forward",weekmask="1010100",holidays=H). خرج التاريخ 2026-10-12، الاثنين. تحركت البداية غير الصالحة رغم أن الإزاحة المطلوبة صفر.
في مرجعنا، بدأ الترحيل من السبت 10. الأحد 11 غير مختار، والاثنين 12 مختار وغير موجود في H، فوقفنا عنده. بعد هذه المرحلة لا توجد خطوة إزاحة نعدها عندما تكون قيمتها صفرًا.
وبالإعداد backward والإزاحة صفرًا، خرج 2026-10-07، الأربعاء. الجمعة 9 مستبعدة، والخميس 8 غير مختار، والأربعاء 7 مختار وغير مستبعد؛ لذلك هو نقطة الترحيل إلى الخلف في هذا المثال.
إن كتابة «صفر يعني تاريخ المدخل نفسه» ستخطئ في هاتين الحالتين. الصفر هنا لا يلغي مرحلة تصحيح البداية التي طلبناها بإعداد roll؛ يترك تاريخ تلك المرحلة دون خطوات إضافية.
مع forward والإزاحة +1، خرج 2026-10-14. بعد الوصول إلى الاثنين 12، الثلاثاء 13 غير مختار، والأربعاء 14 هو أول يوم صالح تالٍ. نعد الأربعاء خطوة واحدة، ولا نعد الاثنين خطوة +1.
مع backward والإزاحة +1، خرج 2026-10-12. البداية المعدلة هي الأربعاء 7؛ الخميس 8 غير مختار، والجمعة 9 مستبعدة، والسبت 10 والأحد 11 غير مختارين، ثم الاثنين 12 خطوة صالحة واحدة.
القيمة +1 واحدة في الفرعين، لكن نقطة العد مختلفة: الاثنين 12 أو الأربعاء 7. إذا استبدلنا النتيجتين باسم «اليوم التالي» فقط، أخفينا مرحلة الترحيل التي فسرت الفرق بينهما.
كل نتيجة رئيسية من datetime64[D] وبشكل (). نسجل دقة اليوم كما شغّلناها؛ لا نحول التاريخ الناتج إلى ساعة انتهاء خدمة أو موعد وصول رسالة.
إزاحة سالبة ليست ترحيلًا جديدًا
مع forward والإزاحة -1، خرج 2026-10-07. وصل الترحيل أولًا إلى الاثنين 12، ثم عد مرجعنا يومًا صالحًا سابقًا: الأحد 11 والسبت 10 غير مختارين، والجمعة 9 مستبعدة، والخميس 8 غير مختار، ثم الأربعاء 7.
مع backward والإزاحة -1، خرج 2026-10-05. وصل الترحيل إلى الأربعاء 7، ثم تجاوز الثلاثاء 6 غير المختار إلى الاثنين 5. لا يكفي تغيير إشارة الإزاحة لتجعل فرعي roll يبدأان من التاريخ نفسه.
إذن forward مع -1 أعاد تاريخًا أسبق من مدخلنا، بينما forward مع صفر أعاد تاريخًا لاحقًا. كلمة forward تخص اختيار البداية الصالحة في هذه المقارنة، ولا تضمن أن النتيجة النهائية لاحقة إذا كان العد اللاحق سالبًا.
للتحكم، أضفنا يومًا تقويميًا واحدًا إلى السبت 10 باستعمال timedelta في Python؛ ظهر الأحد 2026-10-11. هذا التاريخ غير صالح في تقويمنا، ويختلف عن نتيجة forward مع +1 وهي الأربعاء 14.
is_busday تعيد True للتاريخ الصالح وFalse لغيره وفق القناع والاستبعادات. [2]
طبقناها على كل ناتج في الفحوص، فكانت النتائج النهائية صالحة. لكن True لا تخبرنا كم خطوة قطعنا أو من أين بدأ العد؛ احتفظنا بمسار مرجع Python إلى جانب التاريخ النهائي.
نتابع في بطاقة كل تجربة ثلاثة تواريخ: مدخل البداية، ونقطة الترحيل، والناتج بعد الإزاحة. يتطابق الأخيران في حالات الصفر، ويختلفان في فرعي +1 و-1 المسجلين.
لا نستعمل هذا التقويم لتحديد موعد معاملة أو مهلة جهة. القاعدة والأيام المستبعدة هنا مدخلات اخترناها للشرح؛ ولم نعطِ ساعات أو مناطق زمنية أو يوم عمل لخدمة مسماة.

مرجع التواريخ وحدود الفحوص
اختبر مرجع Python صلاحية تاريخ d بشرطين: الخانة الموافقة لـ d.weekday() في القناع تساوي 1، والتاريخ غير موجود في مجموعة الاستبعادات. لا يستدعي المرجع أي دالة تقويم من NumPy.
بدأنا من التاريخ الأصلي وتحركنا يومًا تقويميًا في اتجاه roll حتى تحقق الشرطان. ثم كررنا خطوات الإزاحة: تحرك يومًا في اتجاه إشارتها، وتجاوز غير الصالح حتى تصل إلى يوم صالح؛ كرر ذلك abs(offset) مرة.
بهذه الطريقة نحفظ تاريخ الترحيل ومسار الخطوات الصالحة. الإزاحة صفر تترك المسار فارغًا، والموجبة تجعل خطواته متقدمة، والسالبة تجعلها متراجعة. توقع القيمة النهائية يأتي من هذا المسار المستقل.
للشبكة، استعملنا الأقنعة 1010100 و1111100 و0000011. مع كل قناع ثلاث قوائم استبعاد: فارغة؛ أو 2026-10-09؛ أو ذلك التاريخ مع 2026-10-14. جميعها شروط مؤلفة للفحص.
أخذنا 22 تاريخًا متتابعًا من 2026-09-28 حتى 2026-10-19، وسبع إزاحات صحيحة من -3 إلى +3، واتجاهي roll. العدد 3×3×22×7×2=2772 حالة؛ تتضمن بدايات صالحة وأخرى تحتاج ترحيلًا.
لكل حالة أربعة فحوص: تطابق الناتج مع التوقع ونوعه وشكله؛ وصلاحيته بمرجعنا وبفحص is_busday؛ وطول مسار الإزاحة واتجاهه وصلاحية خطواته؛ وثبات بايتات المدخل ومصفوفة الاستبعادات وشكليهما.
أضفنا الحالات الرئيسية الست إلى الشبكة بهذه الفحوص الأربعة. ثم أضفنا ثلاثة فحوص: التواريخ الستة المعلنة؛ وهوية السبت والجمعة المستبعدة والأربعاء الصالح؛ وتحكم اليوم التقويمي وفرق نتيجتي +1.
الحساب (2772+6)×4+3=11115، ومرت جميعها. is_busday مقارنة إضافية لصلاحية النتائج، لا مصدر توقع التاريخ؛ لا يغني نجاحها عن التحقق من مرحلتي المسار.
النطاق قيم مفردة datetime64[D] منتهية، واتجاها forward وbackward، والأقنعة والاستبعادات والإزاحات المحددة. لم نفحص NaT أو قناعًا خاليًا أو خيارات raise وnat وmodified أو broadcasting أو busdaycal أو out.
لم نقس أداء أو ملكية ذاكرة، ولم نحسب ساعات أو مناطق زمنية أو نتحقق من تقويم مؤسسة حقيقية. ثبات المدخل في الفحص يصف التجربة ولا يحدد صلاحية استعمال التقويم في موعد خارجي.
| roll | offset | نقطة الترحيل | الناتج |
|---|---|---|---|
| forward | -1 | 2026-10-12 | 2026-10-07 |
| forward | 0 | 2026-10-12 | 2026-10-12 |
| forward | 1 | 2026-10-12 | 2026-10-14 |
| backward | -1 | 2026-10-07 | 2026-10-05 |
| backward | 0 | 2026-10-07 | 2026-10-07 |
| backward | 1 | 2026-10-07 | 2026-10-12 |
للتوسع: تقويم حساب مدة الخدمة.
المراجع
أُعدّ هذا المقال بمساعدة الذكاء الاصطناعي، وخضع لمراجعة ذاتية بالأداة نفسها. لا يُنسب إلى مراجع بشري أو خبير مستقل. منهجية المحتوى.
