مهدی خانزادی
۷ تیر ۱۴۰۵
استاندارد پکیج time رو بررسی میکنیم و با بخش هایی از پکیج time که بیشتر مورد استفاده قرار میگیرد آشنا میشویم.
پکیج time در Go قابلیتهایی برای اندازهگیری و نمایش زمان فراهم میکند. محاسبات تقویمی همیشه بر اساس تقویم میلادی (Gregorian calendar) انجام میشوند و هیچ leap second (ثانیه کبیسه) ای در نظر گرفته نمیشود.
سیستمعاملها معمولاً دو نوع ساعت ارائه میدهند:
ساعت دیواری یا Wall Clock, زمان واقعی دنیا را نشان میدهد و به طور معمول آن را روی سیستم عامل یا گوشی موبایل میبینیم. این نوع ساعت, ممکن است بهدلیل همگامسازی زمان تغییر کند. مثلا در زمستان ها و تابستان ها یکساعت به جلو یا عقب کشیده شود و یا اینکه ما آن را تغییر دهیم.
ساعت مونوتونیک یا Monotonic Clock, مثل یک کرنومتر داخلی برای سیستم عامل عمل میکند, به صورت یکنواخت افزایش مییابد و تنها رو به جلو حرکت میکند. با استفاده از ساعت مونوتونیک میتوان میزان زمان سپری شده را محاسبه کرد.
در گولنگ اگر زمان را از استاندارد پکیج دریافت کنیم, درون مقداری که دریافت کرده ایم, زمان بر حسب هر دو نوع ساعت دیواری و مونوتونیک موجود خواهد بود:
خروجی کد بالا چیزی مانند زیر خواهد بود:
مقدار m=+0.000123456 همان ساعت مونوتونیک است. برای محاسبه ی اختلافِ زمان معمولا از ساعت مونوتونیک استفاده میشود.
چه مواقعی درون مقدار برگشت داده شده, ساعت مونوتونیک وجود نخواهد داشت؟
Date , Parse یا Unix بدست بیاوریم, درون مقدار برگشت داده شده ساعت مونوتونیک وجود نخواهد داشت.UTC) ساعت مونوتونیک از مقدار برگشت داده شده حذف خواهد شد.به مثال زیر دقت کنید:
در خروجی کد بالا تنها در اولین خط مقدار m= نمایش داده میشود که نمایانگر ساعت مونوتونیک است و در دیگر مقادیر این مقدار وجود نخواهد داشت.
در حالتی که ساعت مونوتونیک در مقدار مورد نظر موجود نباشد, گولنگ از ساعت دیواری برای محاسبه ی اختلاف زمان استفاده میکند. در چنین حالتی اگر ساعت سیستم عامل دچار تغییر شود, این تغییر بر روی مقدار محاسبه شده اثر خواهد گذاشت.
مثلا اگر ساعت سیستم عامل را دو ساعت به جلو یا عقب ببریم, میزانِ اختلافِ زمان, دو ساعت بیشتر یا کمتر محاسبه میشود.
دو روش برای مقایسه ی برابر بودن زمان ها در گولنگ وجود دارد:
== اگر ساعت مونوتونیک مهم باشدEqual اگر تنها ساعت دیواری اهمیت داشته باشد.در گولنگ دو زمان (time.Time) باهم برابر هستند اگر شرایط زیر برقرار باشد:
اگر حداقل یکی دارای مونوتونیک کلاک باشند, باید مونوتونیک کلاک آنها نیز برابر باشد. (در صورتی که هردو دارای مونوتونیک کلاک نباشد, از مقایسه ی مونوتونیک کلاک ها چشم پوشی میشود.)
در گولنگ برای مقایسه ی بزرگتر و کوچکتر بودن زمان ها نیز همانند مقایسه ی مساوی بودن (==) میتوان از یکی از حالت های زیر استفاده کرد:
>= و <= استفاده میکنیم.Before و After میتوان استفاده کرد.در گولنگ برای تعریف بازه های زمانی نوع time.Duration در نظر گرفته شده است و نتیجه ی حاصل از محاسبه ی اختلاف زمان ها یک time.Duration خواهد بود.
برای محاسبه ی اختلاف زمانی دو متغیر از نوع time.Time میتوان از متد Sub استفاده کرد:
اگر بخواهیم اختلاف زمانی, زمان فعلی با زمانی در گذشته را حساب کنیم, میتوانیم از متد Since به صورت زیر استفاده کنیم:
در پکیج time چند روش مختلف برای اجرای زمانبندیشده (Scheduling) وجود دارد. هر کدام برای سناریوی خاصی طراحی شدهاند.
time.Sleepساده ترین روش برای ایجاد تاخیر در اجرای کدها, استفاده از time.Sleep است.
time.Afterیکی از راههای ارسال سیگنال زمانبندی شده بر روی چنلها, استفاده از تابع time.After است. این تابع یک چنل برمیگرداند که بعد از زمان مشخص (time.Duration) شده, مقداری را بر روی آن چنل مینویسید.
برای ارسال کنترل شده ی سیگنال میتوان از تایمر استفاده کرد. تایمر این قابلیت را به ما میدهد تا مقدار زمانی که برای ارسال شدن سیگنال سپری شده یا مانده را تغییر دهیم و یا حتی از ارسال شدن سیگنال جلوگیری کنیم. برای ایجاد تایمر میتوان از تابع time.NewTimer استفاده کرد.
با استفاده از متد Stop میتوان تایمر را متوقف و با استفاده از متد Reset مقدار تایمر را دوباره تنظیم کرد. در مثال بالا ابتدا تایمر را بر روی ۱ ثانیه تنظیم کردیم و سپس بعد از ۲۰۰ میلی ثانیه, آن را بر روی ۲ ثانیه تنظیم کردیم.
time.AfterFuncبا استفاده از time.AfterFunc میتوان یک تابع را بعد از زمان مشخص شده اجرا کرد.
time.Tickبا استفاده از time.Tick میتوانیم به صورت متناوب هر مدت زمان مشخص مقداری را بر روی یک چنل ارسال کنیم.
نکته: Tick قابل توقف نیست و برای جاهایی مناسب است که نیاز دارید کاری را تا انتهای اجرای برنامه به صورت متناوب انجام دهید.
در مثال بالا با استفاده از break از حلقه خارج شدیم اما Ticker که درون متغیر tick قرار دارد همچنان مقداری را درون چنل داخلی خود قرار میدهد و متوقف نخواهد شد!
time.NewTicker برای ایجاد زمانبندی متناوبِ قابل کنترلبا استفاده از تابع time.NewTicker میتوان Ticker قابل کنترل ایجاد کرد. تیکر یا Ticker به صورت ساده یک struct دارای فیلد C از نوع چنل و دو متد Stop و Reset است.
متد Stop باعث متوقف شدن Ticker میشود و با استفاده از متد Reset میتوان زمانبندی Ticker را تغییر داد.