rdate, 時間格式化,在unix系統實現類似linux系統的date命令
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <math.h>
void Func_help() //幫助函式
{
printf("NAME:\n");
printf(" rdate --display date and time\n");
printf("SYNOPSIS:\n");
printf(" rdate [-f] [time format] [-c] [colculation format] \n");
printf("DESCRIPTION:\n");
printf(" \n");
printf(" -c: value is day/month/year,plus +/-,plus a number which is number to colculate\n");
printf(" \n");
printf(" -f:\n");
printf(" \n");
printf(" %%A is replaced by national representation of the full weekday name.\n");
printf(" %%a is replaced by national representation of the abbreviated weekday name.\n");
printf(" %%B is replaced by national representation of the full month name.\n");
printf(" %%b is replaced by national representation of the abbreviated month name.\n");
printf(" %%C is replaced by (year / 100) as decimal number; single digits are preceded by a zero.\n");
printf(" %%c is replaced by national representation of time and date.\n");
printf(" %%D is equivalent to ``%%m/%%d/%%y''.\n");
printf(" %%d is replaced by the day of the month as a decimal number (01-31).\n");
printf(" %%E* %%O*\n");
printf(" POSIX locale extensions. The sequences %%Ec %%EC %%Ex %%EX %%Ey %%EY %%Od %%Oe %%OH %%OI %%Om %%OM %%OS %%Ou %%OU %%OV %%Ow %%OW %%Oy are supposed to provide alternate\n");
printf(" representations.\n");
printf(" Additionally %%OB implemented to represent alternative months names (used standalone, without day mentioned).\n");
printf(" %%e is replaced by the day of the month as a decimal number (1-31); single digits are preceded by a blank.\n");
printf(" %%F is equivalent to ``%%Y-%%m-%%d''.\n");
printf(" %%G is replaced by a year as a decimal number with century. This year is the one that contains the greater part of the week (Monday as the first day of\n");
printf(" the week).\n");
printf(" %%g is replaced by the same year as in ``%%G'', but as a decimal number without century (00-99).\n");
printf(" %%H is replaced by the hour (24-hour clock) as a decimal number (00-23).\n");
printf(" %%h the same as %%b.\n");
printf(" %%I is replaced by the hour (12-hour clock) as a decimal number (01-12).\n");
printf(" %%j is replaced by the day of the year as a decimal number (001-366).\n");
printf(" %%k is replaced by the hour (24-hour clock) as a decimal number (0-23); single digits are preceded by a blank.\n");
printf(" %%l is replaced by the hour (12-hour clock) as a decimal number (1-12); single digits are preceded by a blank.\n");
printf(" %%M is replaced by the minute as a decimal number (00-59).\n");
printf(" %%m is replaced by the month as a decimal number (01-12).\n");
printf(" %%n is replaced by a newline.\n");
printf(" %%O* the same as %%E*.\n");
printf(" %%p is replaced by national representation of either ante meridiem (a.m.) or post meridiem (p.m.) as appropriate.\n");
printf(" %%R is equivalent to ``%%H:%%M''.\n");
printf(" %%r is equivalent to ``%%I:%%M:%%S %%p''.\n");
printf(" %%S is replaced by the second as a decimal number (00-60).\n");
printf(" %%s is replaced by the number of seconds since the Epoch, UTC (see mktime(3)).\n");
printf(" %%T is equivalent to ``%%H:%%M:%%S''.\n");
printf(" %%t is replaced by a tab.\n");
printf(" %%U is replaced by the week number of the year (Sunday as the first day of the week) as a decimal number (00-53).\n");
printf(" %%u is replaced by the weekday (Monday as the first day of the week) as a decimal number (1-7).\n");
printf(" %%V is replaced by the week number of the year (Monday as the first day of the week) as a decimal number (01-53). If the week containing January 1 has\n");
printf(" four or more days in the new year, then it is week 1; otherwise it is the last week of the previous year, and the next week is week 1.\n");
printf(" %%v is equivalent to ``%%e-%%b-%%Y''.\n");
printf(" %%W is replaced by the week number of the year (Monday as the first day of the week) as a decimal number (00-53).\n");
printf(" %%w is replaced by the weekday (Sunday as the first day of the week) as a decimal number (0-6).\n");
printf(" %%X is replaced by national representation of the time.\n");
printf(" %%x is replaced by national representation of the date.\n");
printf(" %%Y is replaced by the year with century as a decimal number.\n");
printf(" %%y is replaced by the year without century as a decimal number (00-99).\n");
printf(" %%Z is replaced by the time zone name.\n");
printf(" %%z is replaced by the time zone offset from UTC; a leading plus sign stands for east of UTC, a minus sign for west of UTC, hours and minutes follow with\n");
printf(" two digits each and no delimiter between them (common form for RFC 822 date headers).\n");
printf(" %%+ is replaced by national representation of the date and time (the format is similar to that produced by date(1)).\n");
printf(" %%-* GNU libc extension. Do not do any padding when performing numerical outputs.\n");
printf(" %%_* GNU libc extension. Explicitly specify space for padding.\n");
printf(" %%0* GNU libc extension. Explicitly specify zero for padding.\n");
printf(" %%%% is replaced by `%%'.\n");
printf(" \n");
printf("EXAMPLE:\n");
printf(" rdate --2017-10-23 11:04:51 Monday\n");
printf(" rdate -f \"%%Y-%%m_%%d\" --2017-10-23\n");
printf(" rdate -f \"%%Y-%%m_%%d\" -c \"day-3\" --2017-10-20\n");
printf(" rdate -f \"%%Y-%%m_%%d\" -c \"day+3\" --2017-10-26\n");
printf(" rdate -f \"%%Y-%%m_%%d\" -c \"month+3\" --2017-7-23\n");
printf(" rdate -f \"%%Y-%%m_%%d\" -c \"year+3\" --2020-7-23\n");
printf(" \n");
printf(" \n");
printf(" \n");
}
int LeapYear(int year) //判斷閏年
{
int ret = 0;
if ((year%4==0 && year%100!=0) || year%400 == 0) {
ret = 0;
return ret;
}
else
{
ret =1;
return ret;
}
}
struct tm * DayAdd(int dayNUm) //dayNum 單位:天 0代表獲取當前時間,整整數代表獲取以後的時間,負數代表向前的時間
{
time_t tt,timetmp;
struct tm * p = NULL;
time(&tt);
if (tt == -1) {
perror("time");
return p;
}
timetmp = 24*60*60 * dayNUm;
if (dayNUm > 0) {
tt = tt + timetmp;
}
else if (dayNUm < 0){
tt = tt + timetmp;
}
p = localtime(&tt);
if (p == NULL) {
return
p;
}
return p;
}
struct tm * MonthAdd(int monthNum,struct tm * inTm) //inTm為null表示當前時間
{
time_t tt;
struct tm * tmTmp;
int yearCount = 0;
if (inTm == NULL) { //判斷時候獲取當前時間戳
time (&tt);
tmTmp = localtime(&tt);
}
else{
tmTmp = inTm;
}
if (monthNum < 0) { //負數代表
while (1) {
if (abs(monthNum) >= 12) {
monthNum+=12;
yearCount--;
continue;
}
else
{
break;
}
}
if (abs(monthNum) >= (tmTmp->tm_mon+1)) { //判斷傳入的月數是否大於當前的月份,所以tmTmp->tm_mon+1,因為tm_mon從0開始算
tmTmp->tm_mon = 12 - (abs(monthNum) - (tmTmp->tm_mon));
yearCount--;
// if (monthNum + (tmTmp->tm_mon+1) <= 0) { //判斷是否向前數一年,如果向前一年必須year減一
// tmTmp->tm_mon = 12 - (abs(monthNum) - (tmTmp->tm_mon));
// yearCount--;
// }else
// {
// tmTmp->tm_mon += monthNum+1;
// }
}
else{
tmTmp->tm_mon+= monthNum;
}
}
else
{
while (1) { //判斷傳入的引數是否大於12,把大於12的數換算成年,12個月為一年
if (monthNum >= 12) {
monthNum -=12;
yearCount++;
continue;
}
else
{
break;
}
}
if (monthNum + (tmTmp->tm_mon+1) > 12) { //判斷是否需要跨越當前年,如果跨越當前年則年計數器加1
tmTmp->tm_mon = abs((monthNum + (tmTmp->tm_mon))-12);
yearCount++;
}
else
{
tmTmp->tm_mon+= monthNum;
}
}
tmTmp->tm_year+= yearCount;
return tmTmp;
}
struct tm * LastDayOfMonth(int monthNum,struct tm * inTm) //inTm為null表示當前時間
{
int month12[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
time_t tt;
struct tm * tmTmp;
int yearCount = 0;
if (inTm == NULL) { //判斷時候獲取當前時間戳
time(&tt);
tmTmp = localtime(&tt);
}
else
{
tmTmp = inTm;
}
if (monthNum < 0) { //負數代表
while (1) {
if (abs(monthNum) >= 12) {
monthNum+=12;
yearCount--;
continue;
}
else
{
break;
}
}
if (abs(monthNum) >= (tmTmp->tm_mon+1)) { //判斷傳入的月數是否大於當前的月份,所以tmTmp->tm_mon+1,因為tm_mon從0開始算
tmTmp->tm_mon = 12 - (abs(monthNum) - (tmTmp->tm_mon));
yearCount--;
// if (monthNum + (tmTmp->tm_mon+1) <= 0) { //判斷是否向前數一年,如果向前一年必須year減一
// tmTmp->tm_mon = 12 - (abs(monthNum) - (tmTmp->tm_mon));
// yearCount--;
// }else
// {
// tmTmp->tm_mon += monthNum+1;
// }
}
else
{
tmTmp->tm_mon += monthNum;
}
}
else
{
while (1) { //判斷傳入的引數是否大於12,把大於12的數換算成年,12個月為一年
if (monthNum >= 12) {
monthNum -= 12;
yearCount++;
continue;
}
else
{
break;
}
}
if (monthNum + (tmTmp->tm_mon+1) > 12) { //判斷是否需要跨越當前年,如果跨越當前年則年計數器加1
tmTmp->tm_mon = abs((monthNum + (tmTmp->tm_mon))-12);
yearCount++;
}
else
{
tmTmp->tm_mon += monthNum;
}
}
tmTmp->tm_year += yearCount;
if(LeapYear(tmTmp->tm_year+1900) == 1) //不是閏年
{
tmTmp->tm_mday = month12[tmTmp->tm_mon];
}
else
{
if (tmTmp->tm_mon == 1) {
tmTmp->tm_mday = month12[tmTmp->tm_mon]+1;
}
else
{
tmTmp->tm_mday = month12[tmTmp->tm_mon];
}
}
return tmTmp;
}
struct tm * YearAdd(int yearNum,struct tm * inTm) //inTm為null表示當前時間
{
return MonthAdd(yearNum*12, inTm);
}
struct tm * WeekAdd(int weekNum) //inTm為null表示當前時間
{
return DayAdd(weekNum*7);
}
int ToDigit(char * tmp_str) //獲取需要計算的數字
{
int ret = 0,num = 0,isMultiSpace = 0,i=0;
char tmp_array[128];
for (i=1; i <strlen(tmp_str); i++) {
if (isdigit(tmp_str[i]) != 0) {
tmp_array[num]=tmp_str[i];
num++;
ret=0;//判斷以獲取到數字,
continue;
}else if (tmp_str[i] == ' ')//判斷是否存在空格,允許空格存在,但不允許多個數字引數傳入
{
if (ret == 0) { //ret為0表示獲取到數字
isMultiSpace++;//判斷字串內是否有多個數字
}
ret = 1;//如果獲取到空格,則把ret設定成1,表示已經過去過空格
continue;
}
else{//存在除了單個+/-以外的字元
printf("The value of parameter(-c) include a invalid characcter.");
exit(4);
}
}
if (isMultiSpace >= 2 && ret==0) { //如果空格超過2並且是剛剛獲取過數字,表示數字超過2個。
printf("Please enter right format number!!\n");
printf("If you don't kown what values is avalable,please use -h to get help!\n");
exit(2);
}
ret = atoi(tmp_array);
return ret;
}
struct tm * Colculation(char * ColStr) //計算函式
{
int ColNum=0;
struct tm * tmp_tm = NULL;
char * tmp_char = calloc(128, sizeof(char));
if (strcasestr(ColStr, "day") != NULL ){//判斷是否是在日期(天)需要加減
if (strchr(ColStr, '-') != NULL && strchr(ColStr, '+') != NULL) {//判斷引數內是否同時含有+ -符號
printf("Please enter right format symbol!!\n");
printf("If you don't kown what values is avalable,please use -h to get help!\n");
exit(3);
}else if (strchr(ColStr, '-') != NULL) {//判斷計算是+或-
strcpy(tmp_char, strchr(ColStr, '-')); //把-號(含-)後面的內容複製到指定的字串
ColNum=0-ToDigit(tmp_char);//獲取需要計算的數字
}else if (strchr(ColStr, '+') != NULL){
strcpy(tmp_char, strchr(ColStr, '+'));//把+號(含+)後面的內容複製到指定的字串
ColNum=0+ToDigit(tmp_char);//獲取需要計算的數字
}
if (tmp_tm != NULL) {
free(tmp_tm);
tmp_tm = NULL;
}
tmp_tm = DayAdd(ColNum);//日期(天)計算
}else if (strcasestr(ColStr, "month") != NULL){//判斷是否是在日期(月)需要加減
if ((strchr(ColStr, '-') != NULL && strchr(ColStr, '+') != NULL) || strchr(strchr(ColStr, '-')+1,'-') != NULL || strchr(strchr(ColStr, '+')+1,'+') != NULL) {
printf("Please enter right format symbol!!\n");
printf("If you don't kown what values is avalable,please use -h to get help!\n");
exit(3);
}else if (strchr(ColStr, '-') != NULL) {
strcpy(tmp_char, strchr(ColStr, '-'));
ColNum=0-ToDigit(tmp_char);
}else if (strchr(ColStr, '+') != NULL){
strcpy(tmp_char, strchr(ColStr, '+'));
ColNum=0+ToDigit(tmp_char);
}
if (tmp_tm != NULL) {
free(tmp_tm);
tmp_tm = NULL;
}
tmp_tm = MonthAdd(ColNum, NULL);
}else if (strcasestr(ColStr, "year") != NULL){//判斷是否是在日期(年)需要加減
if ((strchr(ColStr, '-') != NULL && strchr(ColStr, '+') != NULL) || strchr(strchr(ColStr, '-')+1,'-') != NULL || strchr(strchr(ColStr, '+')+1,'+') != NULL) {
printf("Please enter right format symbol!!\n");
printf("If you don't kown what values is avalable,please use -h to get help!\n");
exit(3);
}else if (strchr(ColStr, '-') != NULL) {
strcpy(tmp_char, strchr(ColStr, '-'));
ColNum=0-ToDigit(tmp_char);
}else if (strchr(ColStr, '+') != NULL){
strcpy(tmp_char, strchr(ColStr, '+'));
ColNum=0+ToDigit(tmp_char);
}
if (tmp_tm != NULL) {
free(tmp_tm);
tmp_tm = NULL;
}
tmp_tm = YearAdd(ColNum, NULL);
}else{//如果沒有關鍵字(day,month,year)出現,執行這個出口
printf("Please enter right value of colculation,-c\n");
printf("If you don't kown what values is avalable,please use -h to get help!\n");
exit(1);
}
if (tmp_char != NULL) {
free(tmp_char);
tmp_char = NULL;
}
return tmp_tm;
}
int main(int argc, const char * argv[]) {
time_t tt;
struct tm * temp_tm = NULL;
char * str = calloc(1024, sizeof(char));
int format_num=0,i=0,ret=0;
time(&tt);
if(argc < 2){//判斷輸入的但是,不帶引數,執行這裡
temp_tm=localtime(&tt);
strftime(str, 1024, "%Y-%m-%d %H:%M:%S %A", temp_tm);
printf("%s\n",str);
}
else
{
for (i=1; i < argc; i++) {//獲取引數
if ( strcasecmp(argv[i], "-h") == 0 ) {
Func_help();
// break;
goto End;
}else if (strcasecmp(argv[i], "-f") == 0){//-f 表示format,輸出的時間的格式
i++;
if (argv[i] == NULL || strcasecmp(argv[i], "-c") == 0) {
printf("The value of -f must be specified!!!\n");
exit(4);
}
format_num = i;//獲取時間格式化的引數的下標位置
continue;
}else if (strcasecmp(argv[i], "-c") == 0){//-c 表示colculation,計算的格式,如:day-1
i++;
if (argv[i] == NULL || strcasecmp(argv[i], "-f") == 0) {
printf("The value of -c must be specified!!!\n");
exit(4);
}
temp_tm = Colculation(argv[i]);//執行計算函式,獲取最後需要輸出的struct tm
continue;
}else{
printf("You must enter right parametr.\n");
printf("If you don't kown what values is avalable,please use -h to get help!\n");
ret=1;
goto End;
}
}
if (temp_tm == NULL) {//如果temp_tm為空,則表示使用當前時間
temp_tm=localtime(&tt);
}
if (format_num == 0) {//如果沒有獲取時間格式的下標,則使用預設時間輸出格式
strftime(str, 1024, "%Y-%m-%d %H:%M:%S %A", temp_tm);
printf("%s\n",str);
}else{//使用獲取的時間輸出格式的下標,按照時間格式,給str賦值
strftime(str, 1024, argv[format_num], temp_tm);
printf("%s\n",str);
}
}
End:
if (str != NULL) {
free(str);
str=NULL;
}
if(temp_tm != NULL){
free(temp_tm);
temp_tm = NULL;
}
return ret;
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28572479/viewspace-2146213/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- python實現時間的加減,類似linux的date命令PythonLinux
- 《Linux系統 date、cal、hwclock時間命令的用法》Linux
- 直播系統程式碼,linux date修改系統時間Linux
- Linux命令之date - 顯示、修改系統日期時間Linux
- Linux命令date 日期時間和Unix時間戳互轉Linux時間戳
- SerenityOS:類似Unix的圖形化桌面作業系統作業系統
- unix系統命令大全
- unix常用系統命令
- Unix檔案系統和pwd命令實現詳解
- UNIX系統操作命令(轉)
- 獲取系統時間的DOS命令
- 修改linux系統時間Linux
- linux同步系統時間Linux
- linux修改系統時間Linux
- linux 修改系統時間Linux
- CentOS命令修改系統時間同步CentOS
- 在 UNIX中用sar命令進行系統維護
- 類unix系統下常用工具及命令(轉)
- AIX系統的History命令增加時間戳AI時間戳
- UNIX 系統上實現撥號(轉)
- Linux 系統時間和硬體時間Linux
- UNIX作業系統中常用的命令作業系統
- linux系統時間設定Linux
- Linux設定系統時間Linux
- Linux系統時間同步方法。Linux
- linux時間子系統(三)Linux
- linux調整系統時間Linux
- 時間同步 - rdate
- QT實現動態顯示系統時間QT
- Linux系統命令與Solaris系統命令的對比Linux
- Linux系統如何更改時間時區Linux
- 【實驗】Linux調整系統時間和時區的方法Linux
- Qt實時顯示系統時間QT
- 採用scp命令在Linux系統之間copy檔案Linux
- 講一下Linux 或Unix下怎樣修改系統時間(轉)Linux
- unix系統下常用的解壓縮命令
- linux下的系統時間、硬體時間設定Linux
- 5 個在 Linux 中管理檔案型別和系統時間的有用命令Linux型別