How to convert from UTC to local time in C?

前端 未结 10 1699
无人共我
无人共我 2020-12-05 20:44

It\'s a simple question, but the solution appears to be far from simple. I would like to know how to convert from UTC to local time. I am looking for a solution in C that\'s

10条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-05 21:30

    I found that the solution the OP gave did not work in cases when DST applies. For example, in my case, at the current time, DST was not in effect, but if I set the initial date which should convert to local time with DST, then it would not work, i.e. today's date is 3/1/2018 and DST is not in effect, but if I set the date for conversion to, say, 8/1/2018 0:00:00 when DST is in effect, then the solution given would convert to local time, but would not take DST into account. I found that initializing e0 to the date and hour of the initial date/time string and its member tm_isdst to -1 solved the problem. I then created the following program with complementary functions which you can include in your code. The initial format of the date and time is the same that MySQL uses, because I needed it for such purposes.

    #include 
    #include 
    #include 
    
    long long diff_tm(struct tm *a, struct tm *b) {
     return a->tm_sec - b->tm_sec
          + 60LL * (a->tm_min - b->tm_min)
          + 3600LL * (a->tm_hour - b->tm_hour)
          + 86400LL * (a->tm_yday - b->tm_yday)
          + (a->tm_year - 70) * 31536000LL
          - (a->tm_year - 69) / 4 * 86400LL
          + (a->tm_year - 1) / 100 * 86400LL
          - (a->tm_year + 299) / 400 * 86400LL
          - (b->tm_year - 70) * 31536000LL
          + (b->tm_year - 69) / 4 * 86400LL
          - (b->tm_year - 1) / 100 * 86400LL
          + (b->tm_year + 299) /400 * 86400LL;
    }
    
    void localToUTC(char *buf, const char *localTime) {
     struct tm tp;
     strptime(localTime, "%Y-%m-%d %H:%M:%S", &tp);
     tp.tm_isdst = -1;
     time_t utc = mktime(&tp);
     struct tm res = *gmtime(&utc);
     strftime(buf, 20, "%Y-%m-%d %H:%M:%S", &res);
    }
    
    void utcToLocal(char *buf, const char *utcTime) {
     struct tm tp;
     strptime(utcTime, "%Y-%m-%d %H:%M:%S", &tp);
     tp.tm_isdst = -1;
     time_t utc = mktime(&tp);
     struct tm e0 = { .tm_year = tp.tm_year, .tm_mday = tp.tm_mday, .tm_mon = tp.tm_mon, .tm_hour = tp.tm_hour, .tm_isdst = -1 };
     time_t pseudo = mktime(&e0);
     struct tm e1 = *gmtime(&pseudo);
     e0.tm_sec += utc - diff_tm(&e1, &e0);
     time_t local = e0.tm_sec;
     struct tm localt = *localtime(&local);
     strftime(buf, 20, "%Y-%m-%d %H:%M:%S", &localt);
    }
    
    int main(void) {
     char mytime_1[20] = "2018-02-28 13:00:00";
     char utctime_1[20], back_1[20];
     localToUTC(utctime_1, mytime_1);
     utcToLocal(back_1, utctime_1);
     printf("My time: %s\n", mytime_1);
     printf("UTC time: %s\n", utctime_1);
     printf("Back: %s\n", back_1);
    
     printf("-------------------------------------------\n");
    
     char mytime_2[20] = "2018-07-28 17:00:00";
     char utctime_2[20], back_2[20];
     localToUTC(utctime_2, mytime_2);
     utcToLocal(back_2, utctime_2);
     printf("My time: %s\n", mytime_2);
     printf("UTC time: %s\n", utctime_2);
     printf("Back: %s\n", back_2);
    
     printf("-------------------------------------------\n");
    
     return 0;
    }
    

提交回复
热议问题