مقدمه
همانطور که می دانید، پیدا کردن تابعی دقیق برای تبدیل تاریخ های مختلف به یکدیگر دشوار است. با توجه به اهمیت تاریخ در برخی مدارات الکترونیکی به خصوص کنترلی، همچنین میلادی بودن تاریخ های پیش فرض سخت افزارهایی مانند آی سی های RTC نظیر DS1307 و ضرورت وجود تاریخ های دیگر در کنار تاریخ میلادی، کتابخانه ای جهت سهولت تبدیل سه نوع تاریخ مهم و اساسی «میلادی»، «شمسی» و «قمری» برنامه نویسی شد و در ادامه در اختیار مخاطبان قرار خواهد گرفت.
آموزش استفاده از کتابخانه در نرم افزار کدویژن CodeVision AVR
در نرم افزارهای برنامه نویسی مبنی بر زبان سی C مانند CodeVision یا ATMEL Studio، کافیست فایل با پسوند lib را داخل پوشه پروژه قرار داده و سپس در ابتدای کد پروژه خود عبارت زیر را درج کنید:
#include "DateConverter.lib"
حال می توانید طبق حالت کلی تابع، تاریخ موردنظر خود را تبدیل کنید:
dateConvert(char FROM, char TO, float Year, float Month, float Day, int* year, char* month, char* day)
پارامتر FROM
نوع تاریخ ورودی و پارامتر TO
نوع تاریخ خروجی را مشخص می کند. این پارامترها توسط کاراکترهای g – p – i برنامه ریزی می شود. g حرف اول Gregorian یا میلادی، p حرف اول Persian یا فارسی (هجری شمسی) و i حرف اول Islamic یا اسلامی (هجری قمری) می باشد. پارامتر Year
سال ورودی، Month
ماه ورودی، Day
روز ورودی، year
سال خروجی، month
ماه خروجی و day
روز خروجی می باشد. توجه داشته باشید که سه پارامتر خروجی از نوع اشاره گر یا Pointer می باشد که شما جهت خروجی گرفتن از آن بایستی متغیرهای دلخواه خود را به هنگام فراخوانی تابع، در مکان این پارامترها قرار دهید تا مقادیر خروجی تابع در آن ها ریخته شوند.
برای آشنایی و درک بهتر، به قطعه کد زیر توجه کنید:
مثال) می خواهیم تاریخ میلادی اکنون را از آی سی DS1307 دریافت و در خط اول LCD کاراکتری نمایش داده و در خط دوم، تاریخ شمسی اکنون را نمایش دهیم؛ همچنین روز هفته را توسط تاریخ شمسی تبدیل شده بدست آورده و در انتهای خط اول نمایش دهیم:
شکل کلی تابع بالا به صورت زیر در برنامه اصلی ظاهر خواهد شد:
dateConvert('g', 'p', gYear, gMonth, gDay, &pYear, &pMonth, &pDay); // Converting Gregorian to Persian Date
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#include <i2c.h> #include <ds1307.h> #include <alcd.h> #include <stdio.h> #include <delay.h> #include "DateConverter.lib" void mainLoop(void) { char rtcYear, rtcMonth, rtcDay, rtcWeekday = 0; int gYear, pYear = 0; char gMonth, gDay, pMonth, pDay, Weekday = 0; char lcdBuffer[16]; while(1) { rtc_get_date(&rtcWeekday, &rtcDay, &rtcMonth, &rtcYear); gYear = rtcYear + 2000; gMonth = rtcMonth; gDay = rtcDay; // Converting Gregorian Date to Persian Date: FROM = 'g' & TO = 'p' dateConvert('g', 'p', gYear, gMonth, gDay, &pYear, &pMonth, &pDay); sprintf(lcdBuffer, "%04i/%02i/%02i\n%04i/%02i/%02i", gYear, gMonth, gDay, pYear, pMonth, pDay); lcd_gotoxy(0, 0); lcd_puts(lcdBuffer); Weekday = getWeekday(pYear, pMonth, pDay, 'p'); lcd_gotoxy(13, 0); switch(Weekday) { case 0: lcd_puts("SUN"); break; case 1: lcd_puts("MON"); break; case 2: lcd_puts("TUE"); break; case 3: lcd_puts("WED"); break; case 4: lcd_puts("THU"); break; case 5: lcd_puts("FRI"); break; case 6: lcd_puts("SAT"); break; } delay_ms(5000); } } |
برای مشاهده و دانلود کد کامل و شبیه سازی پروژه مثال، به بخش دانلود مراجعه فرمایید.
توابع دیگر
1. تابع تشخیص سال های کبیسه میلادی، شمسی و قمری که به صورت زیر قابل استفاده می باشد:
isLeap(int year, char TYPE);
پارامتر year
سال ورودی و TYPE
نوع تاریخ است که قبلا توضیح داده شد.
برای مثال) کبیسه بودن سال 1398 شمسی را بررسی می کنیم:
isLeap(1398, 'p');
2. تابع محاسبه روز هفته از تاریخ ورودی؛ که به صورت زیر تعریف شده و مورد استفاده قرار می گیرد:
getWeekday(float year, float month, float day, char TYPE)
خروجی این تابع، اعداد در بازه صفر الی 6 می باشد. صفر مربوط به شماره روز یکشنبه، … و 6 مربوط به روز شنبه است.
آموزش استفاده از کتابخانه در نرم افزار بسکام Bascom
در نرم افزارهای برنامه نویسی مبنی بر زبان بیسیک مانند Bascom یا mikroBasic، فایل های Header.inc و Footer.inc را داخل پوشه پروژه قرار داده و سپس در ابتدای کد پروژه خود، درست بعد از پیکره بندی سخت افزار و نرم افزار و تعریف متغیرهای عمومی Global، عبارت زیر را درج کنید:
$include "Header.inc"
سپس کد زیر را در انتهای کد پروژه خود اضافه نمایید:
$include "Footer.inc"
حال می توانید طبق حالت کلی تابع، تاریخ موردنظر خود را تبدیل کنید:
Convert(ByVal From_ As String * 1, ByVal To_ As String * 1, ByVal Year As Long, ByVal Month As Long, ByVal Day As Long, _
ByRef _year As Long, ByRef _month As Long, ByRef _day As Long)
مثال) می خواهیم مثالی که در بخش قبل گفته شد را برای نرم افزار Bascom تکرار کنیم:
شکل کلی تابع بالا به صورت زیر استفاده می شود:
Call Convert("g", "p", Gyear, Gmonth, Gday, Pyear, Pmonth, Pday)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
Main: Do Gosub Get_rtc Dim T1 As String * 8 , T2 As String * 2 , T3 As String * 2 Dim T4 As String * 8 , T5 As String * 2 , T6 As String * 2 Gyear = Rtc_year : Gmonth = Rtc_month : Gday = Rtc_day Call Convert( "g" , "p" , Gyear , Gmonth , Gday , Pyear , Pmonth , Pday) T1 = Str(gyear) : T2 = Str(gmonth) : T3 = Str(gday) T4 = Str(pyear) : T5 = Str(pmonth) : T6 = Str(pday) Weekday = Get_weekday(pyear , Pmonth , Pday , "p") Locate 1 , 1 Lcd Format(t1 , "0000") ; "/" ; Format(t2 , "00") ; "/" ; Format(t3 , "00") Locate 2 , 1 Lcd Format(t4 , "0000") ; "/" ; Format(t5 , "00") ; "/" ; Format(t6 , "00") Locate 1 , 14 Select Case Weekday Case 0 : Lcd "SUN" Case 1 : Lcd "MON" Case 2 : Lcd "TUE" Case 3 : Lcd "WED" Case 4 : Lcd "THU" Case 5 : Lcd "FRI" Case 6 : Lcd "SAT" End Select Wait 5 Loop Return |
توابع دیگر
1. تابع تشخیص سال های کبیسه میلادی، شمسی و قمری که به صورت زیر قابل استفاده می باشد:
Leap(ByVal Year As Double, ByVal Type_ As String * 1) As Byte
پارامتر Year
سال ورودی و Type
نوع تاریخ است که قبلا توضیح داده شد.
برای مثال) می خواهیم کبیسه بودن سال 2019 میلادی را بررسی کنیم:
Leap(2019, "g")
2. تابع محاسبه روز هفته از تاریخ ورودی؛ که به صورت زیر تعریف شده و مورد استفاده قرار می گیرد:
Get_Weekday(ByVal Year_ As Long, ByVal Month_ As Long, ByVal Day_ As Long, ByVal Type_ As String * 1) As Long
خروجی این تابع، اعداد در بازه صفر الی 6 می باشد. صفر مربوط به شماره روز یکشنبه، … و 6 مربوط به روز شنبه است.
توضیحاتی در خصوص کتابخانه
1. توجه داشته باشید ممکن است در تاریخ اسلامی (هجری قمری) اختلاف یک روزه پیش آید.
2. در کتابخانه به زبان بیسیک، به دلیل مشکلات موجود در تبدیل متغیرها به یکدیگر و عدم سازگاری، برای متغیرهای اعشاری از Double و برای متغیرهای صحیح از Long استفاده شده است (نه Single یا Byte و Integer).
3. با توجه به حجم تقریبا بالای کتابخانه در زبان بیسیک، پیشنهاد می شود از میکروکنترلرهای با حافظه Flash بالای 10 کیلوبایت استفاده شود؛ مانند: ATmega168 – ATmega32.
بخش دانلود
شامل موارد زیر:
- فایل های کتابخانه و توابع به زبان سی (کدویژن CodeVision) و بیسیک (بسکام Bascom)
- فایل شبیه سازی پروژه مثال Proteus 8.9
- سورس کد کامل پروژه مثال
- کد هگز مخصوص پروگرام کردن میکروکنترلر
توجهات:
چرا قبل از دانلود نمیگین که سورس فایل بسکام رو نمیزارین؟
همه دنبال روش تبدیل هستن نه صرفا لقمه جویده شده شما!
حداقل سورس اصلی و کامل رو بزارین و در مقابل هزینشو بگیرین نه اینکه ملت رو سرکار بزارین
درود؛
دوست گرامی؛
در فایل دانلودی، هم فایل مثال و هم فایل سورس اصلی موجود هست. در پوشه ی “# ONLY LIBRARY #” نیز قرار داده شده است. نحوه استفاده از توابع در Bascom و CodeVision نیز در توضیحات این پست قرار گرفته است.
اگر به عنوان این پست دقت فرمایید، کتابخانه هست نه صرفا آموزش اینکه چطور تاریخ ها تبدیل می شود. جهت اطلاع، در اکثر کتابخانه هایی که Open Source است – برای مثال، کدها و توابع آماده ای که در GitHub موجود است – تنها روش استفاده از آن توسط Developer ارایه می شود؛ نه توضیح خط به خط سورس کد. مابقی عملیات بر عهده خودِ کاربر است.
موفق باشید.