手动计算 GMT 到纪元

Manually Calculate GMT to Epoch

我是新来的,有什么不对的地方还请多多包涵

我正在尝试将 GMT 格式的时间转换为 Unix 纪元(从 1970 年开始)。

我遵循的程序是,迭代从 1970 年到给定日期的年份,找出闰年和正常年份的数量,并相应地乘以天数。

然后加上一个月过去的天数,加上tm结构中的天值和时分秒,如下代码所示。

代码没有按预期运行,我似乎在计算一些东西,我不明白它是什么。

以下是我正在尝试的输入,此处提供了预期和实际输出。

正常年份:
输入:1 月 20 日 19:00:01 2019 GMT
预期输出:1548010801
实际输出:1548097201(即 1 月 21 日 19:00:01 2019 GMT,相差 1 天)

闰年:
输入:12 月 27 日 14:52:30 2020 GMT
预期输出:1609080750
实际输出:1609253550(12 月 29 日 14:52:30 2020 GMT,相差 2 天)

我请求帮助查找问题。

我有两个悬而未决的问题 1) 我不确定是否需要担心夏令时,因为我正在以 GMT 格式输入时间。
2)有没有更好的方法使用一些公式表达式来计算纪元,而不是迭代和手动 正在计算。

已经有一个 相同 但它正在使用 mktimedifftime.

我想知道我的代码有什么问题,以及在公式表达式中有什么更好的方法。

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

#define BASE_YEAR 1970

void print_time_readable_format(struct tm tm);
int convert_gmt_date_time_to_tm_format(char* gmt_time_fmt);
int check_year_is_leap_or_normal(int year);
int get_number_of_leap_years_from_base_year(int start_year, int end_year);
int convert_gmt_to_epoch(struct tm tm);

int main()
{
    int epoch = 0;
    //char gmt_time_fmt[] = "Jan 20 19:00:01 2019 GMT";
    char gmt_time_fmt[] = "Dec 27 14:52:30 2020 GMT";
    //char gmt_time_fmt[] = "Jan 01 00:00:01 1970 GMT";
    epoch = convert_gmt_date_time_to_tm_format(gmt_time_fmt);
    printf("time in GMT = %s and epoch is %d\n", gmt_time_fmt, epoch);
    
    return 0;
}

int convert_gmt_date_time_to_tm_format(char* gmt_time_fmt)
{
    struct tm tm;
    char tm_time_fmt[255];

    //set tm struture to 0
    memset(&tm, 0, sizeof(struct tm));
    // convert gmt_time_fmt to format required by 'tm' structure
    strptime(gmt_time_fmt, "%B %d %H:%M:%S %Y GMT", &tm);

    strftime(tm_time_fmt, sizeof(tm_time_fmt), "%s", &tm);
    printf("tm_time_fmt = %s\n", tm_time_fmt);

    print_time_readable_format(tm);
    
    return convert_gmt_to_epoch(tm);
    
    return 0;
}

int convert_gmt_to_epoch(struct tm tm)
{
    int days_by_month [2][12] = {
        /* normal years */
        { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
        /* leap years */
        { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
    };

    int current_year = tm.tm_year+1900;
    
    printf("current_year =%d\n", current_year);
    
    int total_years_passed = current_year - BASE_YEAR;
    
    printf("total_years_passed =%d\n", total_years_passed);
    
    int nleap_years_passed = get_number_of_leap_years_from_base_year(BASE_YEAR, current_year);
    
    int normal_years = total_years_passed - nleap_years_passed;
    
    printf("normal_years =%d\n", normal_years);
    
    int total_days_passed = (normal_years*365 + nleap_years_passed*366 );
    
    printf("total_days_passed =%d\n", total_days_passed);
    
    total_days_passed += days_by_month[check_year_is_leap_or_normal(current_year)][tm.tm_mon];
    
    printf("total_days_passed after adding month =%d\n", total_days_passed);
    
    total_days_passed += tm.tm_mday;
    
    printf("total_days_passed after adding day =%d\n", total_days_passed);
    
    total_days_passed  = total_days_passed*24 + tm.tm_hour;
    total_days_passed  = total_days_passed*60 + tm.tm_min;
    total_days_passed  = total_days_passed*60 + tm.tm_sec;
    
    printf("total_days_passed final =%d\n", total_days_passed);

    return total_days_passed;

}

int get_number_of_leap_years_from_base_year(int start_year, int end_year)
{
    int leap_year_count = 0;
    int year = start_year;
    
    while( year <= end_year)
    {
        if(check_year_is_leap_or_normal(year))
            leap_year_count++;
        year++;
    }
    
    printf("leap_year_count = %d\n", leap_year_count);
    
    return leap_year_count;
}

int check_year_is_leap_or_normal(int year)
{
    if( ( year%4 == 0 ) && ( ( year%400 == 0 ) || ( year%100 != 0)))
         return 1;
    else
        return 0;
}

void print_time_readable_format(struct tm tm)
{
    printf("tm.tm_year = %d ", tm.tm_year);
    printf("tm.tm_mon = %d ", tm.tm_mon);
    printf("tm.tm_mday = %d ",tm.tm_mday);
    printf("tm.tm_hour = %d ", tm.tm_hour); 
    printf("tm.tm_min = %d ", tm.tm_min );
    printf("tm.tm_sec = %d\n", tm.tm_sec );
}

两个计算错误:

  1. 闰年是怎么算的,必须排除最后一年。正确的应该是:
    int nleap_years_passed = get_number_of_leap_years_from_base_year(BASE_YEAR, current_year - 1);
  2. 过去的总天数还必须不包括结束日期。修改后的公式:
    total_days_passed += (tm.tm_mday - 1);

以上两个公式导致epoch各偏移1天