C Sleep

 
#include <unistd.h> 
 
int main() {
    usleep(1000000);  // 等待1秒,因为1秒 = 1000000微秒
    sleep(3);  // 等待1秒
    return 0;
}
        
    

 

    

 

    

 

    

 


 

  

 


时间计算

时间化秒

 
1天24小时,1小时60分钟,1分钟60秒,这是定的

不定的是,1个月有多少天,1年有多少天,这要分情况讨论

一个月有多少天

 
1、3、5、7、8、10、12 每月31天,4、6、9、11为30天。

2月正常为28天,如果为闰年,则多一天为29天。
    
一三五七八十腊,三十一天永不差

什么是闰年

 
1、能被4整除,但不能被100整除;

2、能被400整除;

leap year英/ˈliːp jɪə(r)/ 美/ˈliːp jɪr/
闰年

 
#include <stdio.h> 
#define is_leap_year(year) (((year) % 400 == 0) || ((year) % 4 == 0 && (year) % 100 != 0)) ? 1:0
int main (int argc, char** argv)
{
    printf("is leap year:%d\n",is_leap_year(2013));//is leap year:0
    printf("is leap year:%d\n",is_leap_year(2000));//is leap year:1
    return 0;
}
    
C时间转时间戳

自定义C时间转时间戳

 
#include <stdio.h> 

//闰年判断 
#define is_leap_year(year) (((year) % 400 == 0) || ((year) % 4 == 0 && (year) % 100 != 0)) ? 1:0

//判断一年2月有几天
int days_byY2(int year){
    if(is_leap_year(year)){//闰年
        return 29;
    }
    return 28;
}

//获取公元1970年1月1日0时0分0到指定year的天数 
int days_byYY(int year_end ){
    int i;
    int day_sum = 0;
    for(i = 1970; i<year_end;i++){
        int day_one_year = 7*31 + 4*30 + 28;//7*31 + 4*30 + 28=365
        if(is_leap_year(i)){//闰年
            day_one_year = day_one_year + 1;
        }
        day_sum = day_sum + day_one_year;
    }
    return day_sum;
}

//判断指定年月有几天
int days_byM(int year, int month){
    int day = 0;
    switch (month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            day = 31;
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            day = 30;
            break;
        case 2:
            day = days_byY2(year);
            break;
        default:
            break;
    
    }
    return day; 
}

//从year年month月到公元1970年1月1日0时0分0的天数 
int days_byYM(int year, int month){
    //月份天计算
    int day_mon_sum = 0,m=0;
    for(m=1;m<month;m++){
        day_mon_sum= day_mon_sum + days_byM(year,m);
    }

    int day_year_sum=days_byYY(year);
    int day_all = day_year_sum + day_mon_sum;
    return day_all;
}

//从year年month月day日 到公元1970年1月1日0时0分0的天数 
int days_byYMD(int year, int month, int day){
    //-1是不包括最后一天,月的话不包括最后一天,年不包括最后一年
    int day_all = days_byYM(year,month) + day -1 ;
    return day_all;
}

//秒数,从公元1970年1月1日0时0分0秒
int sec_YmdHms(int year, int month, int day, int hour, int minute, int second ){
    int days = days_byYMD(year,month,day);
    //本人也不知道这18000是哪来的,跟Python对比,少了18000(5个小时),就加在这里
    //本人相信Python计算结果,肯定有个什么说法的
    int sec = days*24*60*60 + hour*60*60 + minute*60 + second +18000;
    return sec;
}

int main (int argc, char** argv)
{

    printf("is leap year:%d\n", is_leap_year(1792));//is leap year:1
    printf("is leap year:%d\n", is_leap_year(2000));//is leap year:1

    //判断指定年月有几天
    int day = days_byM(1971,1);
    printf("days = %d\n",day);//days = 31

    //判断指定年到1970年1月1有几天
    int day1 = days_byYY(1972);
    printf("day1 = %d\n",day1);//day1 = 730

    int day2 = days_byYM(1972,3);
    printf("day2 = %d\n",day2);//day2 = 790

    int day3 = days_byYMD(2022, 12, 21);
    printf("day3 = %d\n",day3);//day3 = 19347

    long int sec = sec_YmdHms(2022, 12, 21, 19, 10, 20);
    printf("sec=%ld\n",sec);//sec=1671667820

    long int sec2 = sec_YmdHms(2023, 11, 10, 17, 50, 20);
    printf("sec2=%ld\n",sec2);//sec2=1699656620

    return 0;
}
    

 
$ gcc b.c 
$ ./a.out 
is leap year:1
is leap year:1
days = 31
day1 = 730
day2 = 790
day3 = 19347
sec=1671667820
sec2=1699656620

对比Python时间戳

 
import datetime,time
import pandas as pd 
dt = datetime.datetime(2022, 11, 19, 19, 10, 20)

# 转struct_time
tt = dt.timetuple()

# struct_time 转秒数
seconds = time.mktime(tt)

seconds
1668903020.0

对比pandas时间戳

 
import pandas as pd 
data = pd.DataFrame(["2022-11-19 19:10:20"],columns=["tim"])

# 增加一个新的时间列,将时间转换为以秒为单位的整数
data["tim_num"] = data["tim"].apply(lambda x:time.mktime(time.strptime(x,'%Y-%m-%d %H:%M:%S')))

data.astype("string")

                    tim 	tim_num
0 	2022-11-19 19:10:20 	1668903020.0

经对比,结果完全一致,毕竟Pandas是做数据处理的,跟它一样,至少正确性上暂时没啥问题

 
int main (int argc, char** argv)
{
    //2022-11-19 19:10:20 	
    long int sec = sec_YmdHms(2022, 11, 19, 19, 10, 20);
    printf("sec=%ld\n",sec);//sec=1668903020
    return 0;
}

mktime

 
mktime可以将时间转化为时间戳,但个人使用过程中出了点小问题,导致不敢用,才写了前面的代码
问题如下,先记录一下

 
#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
#include <time.h> 

//start:索引位置
//count:取多少个字符
void str_get(char** res, char* s1,int start,int count){
    *res = (char*)malloc((count+1)*sizeof(char));
    int s_size = strlen(s1);
    int i;
    if(count>s_size){
        count = s_size;
    }
    int end = start+count;
    // printf("start:%d,end:%d\n",start,end);

    int index=0;
    for(i=start;i<end;i++){
        // printf("c=%c\n",s1[i]);
        (*res)[index++] = s1[i];
    }
}
/*
    *  struct tm 
    *      { 
    *      int tm_sec;     // seconds after the minute - [0, 59]  
    *      int tm_min;     // minutes after the hour   - [0, 59]  
    *      int tm_hour;    // hours after midnight     - [0, 23]  
    *      int tm_mday;    // day of the month         - [1, 31]  
    *      int tm_mon;     // months since January     - [0, 11]  
    *      int tm_year;    // years since 1900  
    *      int tm_wday;    // days since Sunday        - [0, 6]   
    *      int tm_yday;    // days since January 1     - [0, 365] 
    *      int tm_isdst;   // Daylight Saving Time flag  
    *      }; 
*/
int strtotime(char t_str[],time_t *t){
    
    char arr_str[20];
    strcpy(arr_str,t_str);
    time_t timeSec=time (NULL); //获取1970.1.1至当前秒数time_t

    char* year_str;
    char* month_str;
    char* day_str;

    char* hour_str;
    char* minute_str;
    char* second_str;

    str_get(&year_str,t_str,0,4);
    str_get(&month_str,t_str,5,2);
    str_get(&day_str,t_str,8,2);

    str_get(&hour_str,t_str,11,2);
    str_get(&minute_str,t_str,14,2);
    str_get(&second_str,t_str,17,2);
    
    printf("%s年%s月%s日 %s时%s分%s秒\n",year_str,month_str,day_str,hour_str,minute_str,second_str);

    int year,month,day,hour,minute,second;
    sscanf(year_str,"%d",&year);
    sscanf(month_str,"%d",&month);
    sscanf(day_str,"%d",&day);
    sscanf(hour_str,"%d",&hour);
    sscanf(minute_str,"%d",&minute);
    sscanf(second_str,"%d",&second);

    printf("%d年%02d月%02d日 %02d时%02d分%02d秒\n",year,month,day,hour,minute,second);
    free(year_str);
    free(month_str);
    free(day_str);
    free(hour_str);
    free(minute_str);
    free(second_str);

    //时间转秒数
    //定义函数  time_t mktime(strcut tm * timeptr);
    //函数说明  mktime()用来将参数timeptr所指的tm结构数据转换成从公元1970年1月1日0时0分0 秒算起至今的UTC时间所经过的秒数。
    struct tm tt;
    tt.tm_sec = second;
    tt.tm_min = minute;
    tt.tm_hour = hour;
    tt.tm_mday = day;
    tt.tm_mon = month-1;
    tt.tm_year = year - 1900;
    *t = mktime(&tt);
    return 0;
}


int main() {
    time_t t;
    char t_str[20] = "2022-12-21 19:10:20";
    if (strtotime(t_str,&t) == 0) {
        printf("t: %lld\n", t);
    } else {
        printf("时间字符串转换Unix时间戳失败\n");
    }

    return 0;
}
/*不知为何在两个时间上跳动 ,1671667820-1671664220 = 3600,相差1小时整 
(base) [xt@kl test]$ gcc t.c 
(base) [xt@kl test]$ ./a.out 
2022年12月21日 19时10分20秒
2022年12月21日 19时10分20秒
t: 1671664220
(base) [xt@kl test]$ 
(base) [xt@kl test]$ 
(base) [xt@kl test]$ ./a.out 
2022年12月21日 19时10分20秒
2022年12月21日 19时10分20秒
t: 1671667820
(base) [xt@kl test]$ ./a.out 
2022年12月21日 19时10分20秒
2022年12月21日 19时10分20秒
t: 1671664220
(base) [xt@kl test]$ ./a.out 
2022年12月21日 19时10分20秒
2022年12月21日 19时10分20秒
t: 1671664220
(base) [xt@kl test]$ ./a.out 
2022年12月21日 19时10分20秒
2022年12月21日 19时10分20秒
t: 1671664220
(base) [xt@kl test]$ ./a.out 
2022年12月21日 19时10分20秒
2022年12月21日 19时10分20秒
t: 1671664220
(base) [xt@kl test]$ ./a.out 
2022年12月21日 19时10分20秒
2022年12月21日 19时10分20秒
t: 1671667820

*/
        
C时间转时间戳结果

 
#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
#include <time.h> 

//闰年判断 
#define is_leap_year(year) (((year) % 400 == 0) || ((year) % 4 == 0 && (year) % 100 != 0)) ? 1:0

//判断一年2月有几天
int days_byY2(int year){
    if(is_leap_year(year)){//闰年
        return 29;
    }
    return 28;
}

//获取公元1970年1月1日0时0分0到指定year的天数 
int days_byYY(int year_end ){
    int i;
    int day_sum = 0;
    for(i = 1970; i < year_end;i++){
        int day_one_year = 7*31 + 4*30 + 28;//7*31 + 4*30 + 28=365
        if(is_leap_year(i)){//闰年
            day_one_year = day_one_year + 1;
        }
        day_sum = day_sum + day_one_year;
    }
    return day_sum;
}

//判断指定年月有几天
int days_byM(int year, int month){
    int day = 0;
    switch (month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            day = 31;
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            day = 30;
            break;
        case 2:
            day = days_byY2(year);
            break;
        default:
            break;
    
    }
    return day; 
}

//从year年month月到公元1970年1月1日0时0分0的天数 
int days_byYM(int year, int month){
    //月份天计算
    int day_mon_sum = 0,m=0;
    for(m=1;m < month;m++){
        day_mon_sum= day_mon_sum + days_byM(year,m);
    }

    int day_year_sum=days_byYY(year);
    int day_all = day_year_sum + day_mon_sum;
    return day_all;
}

//从year年month月day日 到公元1970年1月1日0时0分0的天数 
int days_byYMD(int year, int month, int day){
    //-1是不包括最后一天,月的话不包括最后一天,年不包括最后一年
    int day_all = days_byYM(year,month) + day -1 ;
    return day_all;
}

//秒数,从公元1970年1月1日0时0分0秒
int sec_YmdHms(int year, int month, int day, int hour, int minute, int second ){
    int days = days_byYMD(year,month,day);
    //本人也不知道这18000是哪来的,跟Python对比,少了18000(5个小时),就加在这里
    //本人相信Python计算结果,肯定有个什么说法的
    int sec = days*24*60*60 + hour*60*60 + minute*60 + second +18000;
    return sec;
}

//start:索引位置
//count:取多少个字符
void str_get(char** res, char* s1,int start,int count){
    *res = (char*)calloc((count+1),sizeof(char));
    int s_size = strlen(s1);
    int i;
    if(count>s_size){
        count = s_size;
    }
    int end = start+count;
    // printf("start:%d,end:%d\n",start,end);

    int index=0;
    for(i=start;i < end;i++){
        // printf("c=%c\n",s1[i]);
        (*res)[index++] = s1[i];
    }
}

int str_sec(char* t_str){
    char arr_str[20];
    strcpy(arr_str,t_str);

    char* year_str;
    char* month_str;
    char* day_str;

    char* hour_str;
    char* minute_str;
    char* second_str;

    str_get(&year_str,t_str,0,4);
    str_get(&month_str,t_str,5,2);
    str_get(&day_str,t_str,8,2);

    str_get(&hour_str,t_str,11,2);
    str_get(&minute_str,t_str,14,2);
    str_get(&second_str,t_str,17,2);
    
    // printf("%s年%s月%s日 %s时%s分%s秒\n",year_str,month_str,day_str,hour_str,minute_str,second_str);

    int year,month,day,hour,minute,second;
    sscanf(year_str,"%d",&year);
    sscanf(month_str,"%d",&month);
    sscanf(day_str,"%d",&day);
    sscanf(hour_str,"%d",&hour);
    sscanf(minute_str,"%d",&minute);
    sscanf(second_str,"%d",&second);

    // printf("%d年%02d月%02d日 %02d时%02d分%02d秒\n",year,month,day,hour,minute,second);
    free(year_str);
    free(month_str);
    free(day_str);
    free(hour_str);
    free(minute_str);
    free(second_str);

    int sec = sec_YmdHms(year, month, day, hour, minute, second);
    return sec;
}

int main() {

    char s2[20] = "2022-12-21 19:10:20";
    int sec2 = str_sec(s2);
    printf("sec2=%d\n",sec2);//sec=1668903020


    char* s1 = "2022-12-21 19:10:20";
    int sec1 = str_sec(s1);
    printf("sec1=%d\n",sec1);//sec=1668903020

    return 0;
}
        
gettimeofday

判断自1970-01-01 00:00:00以来的秒数

 
#include <sys/time.h> 
#include <stdio.h> 

int main (int argc, char** argv)
{
    struct timeval tv = {};
    int retVal = gettimeofday(&tv, NULL);
    if (0 == retVal) {
        printf("sec:%ld,usec:%ld since 1970-01-01 00:00:00 UTC\n", tv.tv_sec, tv.tv_usec);
    }
    return 0;
}
    

 
$ gcc b.c 
$ ./a.out 
sec:1699596938,usec:66739 since 1970-01-01 00:00:00 UTC

自1970-01-01 00:00:00 +0000 (UTC)以来的秒数和微秒数。

 
这个微秒数指两个秒数之间的增量 

#include <sys/time.h> 
int gettimeofday(struct timeval *tv, struct timezone *tz);

struct timeval {
    time_t      tv_sec;     /* seconds */
    suseconds_t tv_usec;    /* microseconds */
};


struct timezone {
    int tz_minuteswest;     /* minutes west of Greenwich */
    int tz_dsttime;         /* type of DST correction */
};


tz:表示时区和夏令时信息。已废弃,设置为NULL。
int retVal = gettimeofday(&tv, NULL);

判断代码运行时间,毫秒级

 
#include <sys/time.h> 
#include <stdio.h> 

int main (int argc, char** argv)
{
    struct timeval tv = {};
    int retVal = gettimeofday(&tv, NULL);
    if (0 == retVal) {
        printf("sec:%ld,usec:%ld since 1970-01-01 00:00:00 UTC\n", tv.tv_sec, tv.tv_usec);
    }

    struct timeval start,end;  

    gettimeofday(&start, NULL );  

    //个人代码 

    gettimeofday(&end, NULL );  

    double timeuse = ( end.tv_sec - start.tv_sec )*1000 + (end.tv_usec - start.tv_usec)/1000.0;  
    printf("毫秒 : %f\n",timeuse);  

    return 0;
}
    

 
$ gcc b.c 
$ ./a.out 
sec:1699596789,usec:406460 since 1970-01-01 00:00:00 UTC
毫秒 : 0.000000

参考文章