time --- دوال متعلقة بالوقت¶
توفر وحدة time دوالاً للحصول على الوقت والتاريخ الحاليين، وقياس الفترات الزمنية، وللتأخيرات.
حقبة الوقت: تستخدم كاميرات OpenMV Cam المبنية على Alif و i.MX RT حقبة POSIX وهي 1970-01-01 00:00:00 UTC. وتستخدم كاميرات OpenMV Cam المبنية على STM32 حقبة 2000-01-01 00:00:00 UTC. يمكن تحديد سنة الحقبة في وقت التشغيل باستخدام gmtime(0)[0].
الحفاظ على التاريخ/الوقت التقويمي الفعلي: يتطلب هذا ساعة زمن حقيقي (RTC). على OpenMV Cam يُوفَّر وقت النظام بواسطة كائن machine.RTC. يمكن ضبط الوقت التقويمي الحالي باستخدام machine.RTC().datetime(tuple) ويُحافَظ عليه بواسطة إحدى الطرق التالية:
بطارية احتياطية (مكوّن اختياري على بعض كاميرات OpenMV Cam).
بروتوكول وقت شبكي مثل
ntptime(يتطلب اتصالاً بالشبكة).ضبطه يدوياً عند كل تشغيل. يُحافَظ على الـ RTC عادةً عبر عمليات إعادة التعيين البرمجية، لكنه يُفقد عند انقطاع الطاقة ما لم تكن هناك بطارية احتياطية مركّبة.
إذا لم يُحافَظ على الوقت التقويمي، فإن الدوال أدناه التي تشير إلى الوقت المطلق الحالي لن تتصرف كما هو متوقع.
الدوال¶
- time.gmtime(secs: int | None = None) Tuple[int, int, int, int, int, int, int, int]¶
- time.localtime(secs: int | None = None) Tuple[int, int, int, int, int, int, int, int]¶
يحوّل الوقت secs المعبّر عنه بالثواني منذ الحقبة (انظر أعلاه) إلى صف tuple من 8 عناصر يحتوي على:
(year, month, mday, hour, minute, second, weekday, yearday)إذا لم يُوفَّر secs أو كان None، فسيُستخدم الوقت الحالي من الـ RTC.تعيد دالة
gmtime()صف tuple للتاريخ والوقت بالتوقيت العالمي UTC، وتعيدlocaltime()صف tuple للتاريخ والوقت بالتوقيت المحلي.صيغة الإدخالات في صف tuple المكوّن من 8 عناصر هي:
السنة تشمل القرن (على سبيل المثال 2014).
month يكون من 1 إلى 12
mday يكون من 1 إلى 31
hour يكون من 0 إلى 23
minute يكون من 0 إلى 59
second يكون من 0 إلى 59
weekday يكون من 0 إلى 6 للأيام من الاثنين إلى الأحد
yearday يكون من 1 إلى 366
- time.mktime(date_time_tuple: Tuple[int, int, int, int, int, int, int, int]) int¶
هذه هي الدالة العكسية لـ localtime. وسيطها هو صف tuple كامل من 8 عناصر يعبّر عن وقت وفق localtime. وتعيد عدداً صحيحاً هو عدد الثواني منذ حقبة الوقت.
- time.sleep(seconds: float) None¶
ينام لعدد الثواني المعطى. قد يكون seconds رقماً ذا فاصلة عائمة، للنوم لعدد كسري من الثواني. للتأخيرات الأدق أو ذات الأعداد الصحيحة فقط استخدم الدالتين
sleep_ms()وsleep_us().استدعاء
sleep()، بما في ذلكsleep(0)، مضمون أن يستدعي دوال رد النداء المعلّقة.
- time.sleep_ms(ms: int) None¶
يؤخّر لعدد معطى من المللي ثانية، ويجب أن يكون موجباً أو 0.
ستؤخّر هذه الدالة لمدة لا تقل عن عدد المللي ثانية المعطى، لكنها قد تستغرق وقتاً أطول إذا توجّب إجراء معالجة أخرى، على سبيل المثال معالِجات المقاطعة أو خيوط أخرى. تمرير 0 لـ ms سيظل يسمح بحدوث هذه المعالجة الأخرى. استخدم
sleep_us()للتأخيرات الأدق.استدعاء
sleep_ms()، بما في ذلكsleep_ms(0)، مضمون أن يستدعي دوال رد النداء المعلّقة.
- time.sleep_us(us: int) None¶
يؤخّر لعدد معطى من الميكرو ثانية، ويجب أن يكون موجباً أو 0.
تحاول هذه الدالة توفير تأخير دقيق لا يقل عن us ميكرو ثانية، لكنها قد تستغرق وقتاً أطول إذا كان لدى النظام معالجة أخرى ذات أولوية أعلى لتنفيذها.
- time.ticks_ms() int¶
يعيد عدّاد مللي ثانية متزايداً ذا نقطة مرجعية اعتباطية، يلتفّ بعد قيمة معينة.
لا تُكشف قيمة الالتفاف صراحةً، لكننا سنشير إليها بـ TICKS_MAX لتبسيط النقاش. دورة القيم هي TICKS_PERIOD = TICKS_MAX + 1. ويُضمن أن تكون TICKS_PERIOD قوة للعدد اثنين، لكنها بخلاف ذلك قد تختلف من منفذ إلى آخر. تُستخدم قيمة الدورة نفسها لجميع دوال
ticks_ms()وticks_us()وticks_cpu()(للتبسيط). وبالتالي، ستعيد هذه الدوال قيمة في النطاق [0 .. TICKS_MAX]، شاملاً الطرفين، بإجمالي TICKS_PERIOD قيمة. لاحظ أن القيم غير السالبة فقط هي المستخدمة. في معظم الأحيان، يجب أن تتعامل مع القيم التي تعيدها هذه الدوال على أنها معتمة. العمليات الوحيدة المتاحة لها هي دالتاticks_diff()وticks_add()الموصوفتان أدناه.ملاحظة: إجراء عمليات رياضية قياسية (+، -) أو عوامل علاقية (<، <=، >، >=) مباشرة على هذه القيم سيؤدي إلى نتيجة غير صالحة. كما أن إجراء عمليات رياضية ثم تمرير نتائجها كوسائط إلى
ticks_diff()أوticks_add()سيؤدي أيضاً إلى نتائج غير صالحة من هاتين الدالتين الأخيرتين.
- time.ticks_us() int¶
تماماً مثل
ticks_ms()أعلاه، لكن بالميكرو ثانية.
- time.ticks_cpu() int¶
مشابهة لـ
ticks_ms()وticks_us()، لكن بأعلى دقة ممكنة في النظام. وهذا عادةً ساعات وحدة المعالجة المركزية، ولهذا سُمّيت الدالة بهذه الطريقة. لكن لا يلزم أن تكون ساعة وحدة معالجة مركزية، إذ يمكن استخدام مصدر توقيت آخر متاح في النظام (مثل مؤقت عالي الدقة) بدلاً من ذلك. لا تُحدَّد وحدة التوقيت الدقيقة (الدقة) لهذه الدالة على مستوى وحدةtime، لكن قد توفر وثائق منفذ معين معلومات أكثر تحديداً. تُخصَّص هذه الدالة للقياس الدقيق جداً للأداء أو لحلقات الزمن الحقيقي الضيقة جداً. تجنّب استخدامها في الكود المحمول. وهي متوفرة على جميع كاميرات OpenMV Cam.
- time.ticks_add(ticks: int, delta: int) int¶
يزيح قيمة الـ ticks بعدد معطى، يمكن أن يكون موجباً أو سالباً. بمعطى قيمة ticks، تتيح هذه الدالة حساب قيمة ticks بمقدار delta من الـ ticks قبلها أو بعدها، وفق تعريف الحساب النمطي لقيم الـ ticks (انظر
ticks_ms()أعلاه). يجب أن يكون المعامل ticks نتيجة مباشرة لاستدعاء دوالticks_ms()أوticks_us()أوticks_cpu()(أو من استدعاء سابق لـticks_add()). أما delta فيمكن أن يكون أي عدد صحيح اعتباطي أو تعبيراً عددياً. تفيدticks_add()في حساب المواعيد النهائية للأحداث/المهام. (ملاحظة: يجب استخدام دالةticks_diff()للتعامل مع المواعيد النهائية.)أمثلة:
# Find out what ticks value there was 100ms ago print(ticks_add(time.ticks_ms(), -100)) # Calculate deadline for operation and test for it deadline = ticks_add(time.ticks_ms(), 200) while ticks_diff(deadline, time.ticks_ms()) > 0: do_a_little_of_something() # Find out TICKS_MAX used by this port print(ticks_add(0, -1))
- time.ticks_diff(ticks1: int, ticks2: int) int¶
تقيس فرق الـ ticks بين القيم المعادة من دوال
ticks_ms()أوticks_us()أوticks_cpu()، كقيمة ذات إشارة قد تلتفّ.ترتيب الوسائط هو نفسه عامل الطرح، فـ
ticks_diff(ticks1, ticks2)لها نفس معنىticks1 - ticks2. لكن القيم المعادة من دوالticks_ms()وما إليها قد تلتفّ، لذا فإن استخدام الطرح مباشرة عليها سينتج نتيجة غير صحيحة. ولهذا السبب تكونticks_diff()ضرورية، فهي تنفّذ حساباً نمطياً (أو بشكل أكثر تحديداً، حساباً حلقياً) لإنتاج نتيجة صحيحة حتى لقيم الالتفاف (طالما أنها ليست متباعدة جداً فيما بينها، انظر أدناه). تعيد الدالة قيمة ذات إشارة في النطاق [-TICKS_PERIOD/2 .. TICKS_PERIOD/2-1] (وهذا تعريف نطاق نموذجي للأعداد الصحيحة الثنائية ذات الإشارة بنظام المتمم الثنائي). إذا كانت النتيجة سالبة، فهذا يعني أن ticks1 حدثت في وقت أبكر من ticks2. وإلا، فهذا يعني أن ticks1 حدثت بعد ticks2. وهذا يصحّ فقط إذا كانت ticks1 و ticks2 متباعدتين عن بعضهما بما لا يزيد عن TICKS_PERIOD/2-1 من الـ ticks. إذا لم يتحقق ذلك، فستُعاد نتيجة غير صحيحة. وعلى وجه التحديد، إذا كانت قيمتا الـ ticks متباعدتين بمقدار TICKS_PERIOD/2-1 من الـ ticks، فستعيد الدالة تلك القيمة. أما إذا مرّ TICKS_PERIOD/2 من ticks الزمن الحقيقي بينهما، فستعيد الدالة -TICKS_PERIOD/2 بدلاً من ذلك، أي أن قيمة النتيجة ستلتفّ إلى النطاق السالب من القيم الممكنة.تبرير غير رسمي للقيود أعلاه: افترض أنك محبوس في غرفة دون أي وسيلة لمراقبة مرور الوقت سوى ساعة قياسية ذات 12 علامة. عندئذٍ إذا نظرت إلى قرص الساعة الآن، ولم تنظر مجدداً لمدة 13 ساعة أخرى (مثلاً إذا غططت في نوم طويل)، فعندما تنظر أخيراً مرة أخرى، قد يبدو لك أن ساعة واحدة فقط قد مضت. لتجنب هذا الخطأ، انظر إلى الساعة بانتظام فحسب. ويجب أن يفعل تطبيقك الشيء نفسه. كما أن استعارة "النوم الطويل جداً" تنطبق مباشرة على سلوك التطبيق: لا تدع تطبيقك يشغّل أي مهمة واحدة لفترة طويلة جداً. شغّل المهام على خطوات، واحفظ الوقت بينها.
صُمّمت
ticks_diff()لاستيعاب أنماط استخدام متنوعة، من بينها:الاستقصاء مع مهلة. في هذه الحالة، يكون ترتيب الأحداث معروفاً، وستتعامل فقط مع النتائج الموجبة لـ
ticks_diff()# Wait for GPIO pin to be asserted, but at most 500us start = time.ticks_us() while pin.value() == 0: if time.ticks_diff(time.ticks_us(), start) > 500: raise TimeoutError
جدولة الأحداث. في هذه الحالة، قد تكون نتيجة
ticks_diff()سالبة إذا كان الحدث متأخراً:# This code snippet is not optimized now = time.ticks_ms() scheduled_time = task.scheduled_time() if ticks_diff(scheduled_time, now) > 0: print("Too early, let's nap") sleep_ms(ticks_diff(scheduled_time, now)) task.run() elif ticks_diff(scheduled_time, now) == 0: print("Right at time!") task.run() elif ticks_diff(scheduled_time, now) < 0: print("Oops, running late, tell task to run faster!") task.run(run_faster=true)
ملاحظة: لا تمرّر قيم
time()إلىticks_diff()، فيجب عليك استخدام العمليات الرياضية العادية عليها. لكن لاحظ أنtime()قد (وسوف) تفيض أيضاً. يُعرف هذا بـ https://en.wikipedia.org/wiki/Year_2038_problem .
- time.time() int¶
يعيد عدد الثواني، كعدد صحيح، منذ الحقبة، بافتراض أن الـ RTC الأساسي مضبوط ومُحافَظ عليه كما هو موصوف أعلاه. إذا لم يكن الـ RTC مضبوطاً، تعيد هذه الدالة عدد الثواني منذ نقطة مرجعية زمنية خاصة بالمنفذ (للوحات المضمّنة بدون RTC مدعوم ببطارية، عادةً منذ التشغيل أو إعادة التعيين). إذا أردت تطوير تطبيق MicroPython محمول، فلا ينبغي أن تعتمد على هذه الدالة لتوفير دقة أعلى من الثانية. إذا كنت تحتاج إلى دقة أعلى وطوابع زمنية مطلقة، استخدم
time_ns(). وإذا كانت الأوقات النسبية مقبولة، فاستخدم الدالتينticks_ms()وticks_us(). وإذا كنت تحتاج إلى الوقت التقويمي، فإنgmtime()أوlocaltime()دون وسيط هي خيار أفضل.الفرق عن CPython
في CPython تعيد هذه الدالة عدد الثواني منذ حقبة Unix (1970-01-01 00:00 UTC) كقيمة ذات فاصلة عائمة، عادةً بدقة الميكرو ثانية. على OpenMV Cam تعيد عدداً صحيحاً بدقة الثانية الواحدة -- إذ لا يمكن للعتاد تمثيل نطاق زمني طويل ودقة أقل من الثانية معاً في رقم عائم -- وتختلف الحقبة حسب اللوحة (انظر حقبة الوقت أعلاه). فبدون RTC مدعوم ببطارية ومضبوط، تعدّ بدلاً من ذلك الثواني منذ التشغيل/إعادة التعيين.
البنّاءات¶
- class time.clock¶
تعيد كائن ساعة.
الطرائق¶
- fps() float¶
توقف تتبّع الوقت المنقضي وتعيد معدل الإطارات الحالي FPS (الإطارات في الثانية).
استدعِ
tickدائماً أولاً قبل استدعاء هذه الدالة.