آموزش اسکریپت نویسی

آموزش اسکریپت نویسی پوسته گنو-لینوکس

آموزش اسکریپت نویسی

آموزش اسکریپت نویسی پوسته گنو-لینوکس

پرسش و پاسخ شماره ۷۰

پرسش و پاسخ شماره ۷۰

چطور می‌توانم زمان یونیکس(epoch) را به مقادیر قابل خواندن انسانی تبدیل نمایم؟

تنها روش سالم مدیریت مقادیر زمان در داخل یک برنامه، تبدیل آنها به مقیاس خطی است. شما نمی‌توانید ‎"January 17, 2005 at 5:37 PM"‎ را در متغیری ذخیره کنید و انتظار انجام کاری را با آن داشته باشید....

بنابراین، هر برنامه کارآمد از نشانه‌های زمان با معانی از قبیل «تعداد ثانیه‌های از نقطه X» استفاده می‌کند . اینها را نشانه‌ها زمان epoch می‌نامند. اگر epoch نیمه شب اول ژانویه 1970 بر اساس UTC زیرنویس 1 باشد، آنوقت "Unix timestamp" نیز نامیده می‌شود، زیرا این روشی است که یونیکس تمام زمانها(ازقبیل زمان ویرایش فایل) را ذخیره می‌کند.

یونیکس استاندارد، متأسفانه ابزاری برای کار کردن با نشانه‌های زمان یونیکس ندارد. فرمان date گنو و اخیراً BSD، دارای یک الحاقیه ‎%s‎ برای تولید خروجی در قالب نشانه زمان یونیکس می‌باشند:

   # GNU/BSD date
   date +%s    #  1358612347 زمان فعلی را با قالب یونیکس چاپ می‌کند به عنوان مثال

موقعی که نیاز به فاصله زمانی بین دو رویداد باشد، این گزینه به طور رایج در اسکریپت‌ها به کار می‌رود:

   # POSIX shell, with GNU/BSD date
   start=$(date +%s)
   ...
   end=$(date +%s)
   echo "Operation took $(($end - $start)) seconds."

حال، برای تبدیل آن نشانه‌های زمان یونیکس به مقادیر قابل خواندن انسانی، استفاده از یک برنامه خارجی لازم است. یک شیوه، به کار بردن ترفندی با استفاده از date گنو است:

   # GNU date
   date -d "1970-01-01 UTC + 1358612347 seconds"
   # .را نسبت به وقت محلی تهران چاپ می‌کند Sat Jan 19 19:49:07 IRST 2013.

خواندن ‎info date‎ بخش ‎(GNU coreutils:Date input formats)‎ روشن می‌کند که این فرمان نشانه‌های زمانِ یونیکسِ پیشوند شده با '@' را می‌پذیرد، اینطور:

   # recent GNU date
   $ date -d "@1164128484"
   # .را نسبت به وقت منطقه اروپای مرکزی چاپ می‌کند "Tue Nov 21 18:01:24 CET 2006" 

به هر حال، این ویژگی فقط با نگارشهای جدیدتر date گنو کار می‌کند -- ‎coreutils 5.3.0‎ و بالاتر.

اگر شما date گنو را در دسترس ندارید، می‌توانید از پرل استفاده کنید:

   perl -le "print scalar localtime 1358612347"
   # را چاپ می‌کند Sat Jan 19 19:49:07 2013

من در این مثالها نقل‌قول دوگانه را به کار بردم به طوری که زمان ثابت می‌توانست با یک متغیر مرجع تعویض گردد. برای اطلاعات بیشتر در خصوص تغییر قالب خروجی، مستندات ‎date(1)‎ و پرل را ببینید.

نگارشهای جدیدتر Tcl (همچون 8.5) پشتیبانی مناسبی از توابع تاریخ و ساعت دارند. صفحه ‎man tclsh‎ را برای جزئیات نحوه کاربرد آن ملاحظه نمایید. برای مثال:

   echo 'puts [clock format [clock scan "today"]]' | tclsh
   # (تنظیم شودclock format تاریخ امروز را چاپ می‌کند(قالب می‌تواند با پارامترها در
   
   echo 'puts [clock format [clock scan "fortnight"]]' | tclsh
   # .تاریخ دو هفته قبل را چاپ می‌کند
   
   echo 'puts [clock format [clock scan "5 years + 6 months ago"]]' | tclsh
   # ‏۵/۵ سال قبل با احتساب سال کبیسه و زمان روشنایی روز

یک روش مناسب برای محاسبه ثانیه‌های سپری شده از ‎'YYYY MM DD HH MM SS'‎ استفاده از awk می‌باشد.

   echo "2008 02 27 18 50 23" | awk '{print systime() - mktime($0)}'
   # استفاده می‌کند epoch برای باز گرداندن زمان فعلی در شکل systime() این کُد از ‎ 
   # آن اجرا می‌کند epoch را روی رشته ورودی برای به دست آوردن زمان mktime() سپس

برای آنکه خواندن آن توسط انسان خواناتر گردد، می‌توان از awk گنو (gawk) استفاده نمود: قالب‌بندی رشته در آن مشابه با date است، و به طور دقیق در توابع زمان در gawk نشان داده شده است

 echo "YYYY MM DD HH MM SS" | gawk '{print strftime("%M Minutes, %S Seconds",systime() - mktime($0))}'
 # تفاضل را به یک شکل قابل خواندن انسانی تبدیل می‌کند ،gawk مخصوص strftime() تابع 

پرسش و پاسخ 70 (آخرین ویرایش ‎2013-04-10 21:27:34‎ توسط geirha)


  1. مترجم: ‎UTC برگرفته از Universal Time Coordinated‎ است که روش مدرن و دقیقتر از GMT(وقت گرینویچ) برای محاسبه یکنواخت زمان در تمام نقاط جهان است و ساعت اتمی بین‌المللی نیز گفته می‌شود. (1)