天天看點

C語言實作了crontab表達式執行時間

公司有個嵌入式低功耗項目,項目需求中有一項是仿照Linux cron task的定時設定,作為裝置定時喚醒時間。于是就自己琢磨寫了C語言的Crontab表達式執行時間,各種調試結果與crontab執行時間線上工具一緻。用到了基姆拉爾森計算公式計算星期,Linux源碼中的Crond.c檔案的ParseField函數。希望能對同行有幫助。

crontab表達式的知識請自行百度。

先講講實作思路:

1、參考Linux源碼中的Crond.c檔案的static char *ParseField(char *user, char *ary, int modvalue, int off,const char *const *names, char *ptr);函數,将crontab表達式解析成結構體CronLine中的分鐘數組,小時數組,日期數組,月份數組和星期數組,并對其對應項指派為1.

typedef struct CronLine 
{
	char cl_Mins[60];	/* 0-59                                 */
	char cl_Hrs[24];	/* 0-23                                 */
	char cl_Days[32];	/* 0-31                                 */
	char cl_Mons[12];	/* 0-11                                 */
	char cl_Dow[7];		/* 0-6, beginning sunday                */
} CronLine;
static char *ParseField(char *user, char *ary, int modvalue, int off,const char *const *names, char *ptr);
           

2、寫一個函數,函數功能:調用一次,時間加1分鐘。

3、從目前時間(先輸入設定時間,當然可以改成擷取系統時間)向後一分鐘一分鐘的周遊,滿足條件後把滿足條件的時間列印出來。

//尋找滿足crond條件的時間點
	uint8_t GetWakeUpTimePoint(CronLine *pline,struct data_time_str *p_data)
	{
		if((pline->cl_Mins[p_data->min] == 1)
			&& (pline->cl_Hrs[p_data->hour] == 1)
			&& (pline->cl_Days[p_data->day] == 1)
			&& (pline->cl_Mons[p_data->month] == 1)
			&& (pline->cl_Dow[p_data->week] == 1))
		{
			printf("%04d年%02d月%02d日  %02d:%02d:00   星期%d\r\n",
					p_data->year,p_data->month,p_data->day,
					p_data->hour,p_data->min,p_data->week);
			return 1;
		}
		return 0;
	}
		
	int main()
	{
		CronLine line = {0};
		char *ptr;
		/*buf:Crontab表達式*/
		char buf[] = "0 0 1,20 * * "; //0 18 * * * //10 5 */5 * *
		ptr = ParseField("Mins", line.cl_Mins, 60, 0, NULL, buf);
		ptr = ParseField("Hrs", line.cl_Hrs, 24, 0, NULL, ptr);
		ptr = ParseField("Days", line.cl_Days, 32, 0, NULL, ptr);
		ptr = ParseField("Mons", line.cl_Mons, 12, -1, MonAry, ptr);
		ptr = ParseField("Week", line.cl_Dow, 7, 0, DowAry, ptr);
		if (ptr == NULL) 
		{
			printf("It's over\r\n");
		}
		
		/*
		uint8_t min;
		uint8_t hour;
		uint8_t day;
		uint8_t month;
		uint16_t year;
		*/
		//先定義個時間初始值
		//struct data_time_str CalcDataTime = {34,9,30,8,2019,4}; 
		//擷取目前時間
		SYSTEMTIME st;
		GetLocalTime(&st);
		struct data_time_str CalcDataTime = {0};
		CalcDataTime.year = st.wYear;
		CalcDataTime.month = st.wMonth;
		CalcDataTime.day = st.wDay;
		CalcDataTime.hour = st.wHour;
		CalcDataTime.min = st.wMinute;
	
		uint32_t cnt = 0; //做個循環限制 
		uint8_t getcnt = 0; //記錄找到喚醒時間的次數 
		while((cnt < 0xFFFFFFFF) && (getcnt <= 10))
		{
			cnt++;
			UpdateTimeBuf(&CalcDataTime);
			if(GetWakeUpTimePoint(&line,&CalcDataTime))
			{
				getcnt++;
			}			
		}
		
	    system("pause");
	    return 0;
	}
           

有任何問題聯系低調奢華猿QQ:2573507779

源碼:https://download.csdn.net/download/qq_33901011/11643934

工程用VS2010打開直接編譯運作就可以,也可以用DevC++直接打開main,cpp編譯運作看結果。

繼續閱讀