2017-02-14 7 views
1

Скажите, что я хочу получить дни, прошедшие с 1 января, вернет ли это правильное значение для високосных лет?Строка tm-> tm_yday дает правильное значение для високосного года?

struct tm *now_tm; 
struct timeval tv; 
time_t currtime; 

gettimeofday(&tv, NULL); 
currtime=tv.tv_sec; 
now_tm = localtime(&currtime); 
int day = now_tm->tm_yday; 

ссылка тм http://www.cplusplus.com/reference/ctime/tm/

ответ

2

Да это было бы, если инициализировать currtime к текущему времени, вместо того, чтобы оставить его неинициализированным:

time_t currtime = time(0); 

Лучше ссылка будет (наверное) можно найти на ваша машина как man localtime. Или вы можете прочитать его here.

Обратите внимание, что поле документировано как имеющее значения 0-365 (включительно), а не 0-364, поэтому оно имеет 366 возможных значений.

+0

@schwern: он гарантированно работает, если у вас есть правильное объявление функции 'time' (что также требует порядка получения правильного типа возвращаемого значения). – rici

+0

Моя ошибка, константа 0 - нулевой указатель. Я смешался с обнуляющей памятью, как 'calloc'. – Schwern

0

Да - он вернется 365. 1 января возвратит 0, 31 декабря будет возвращать 364 для невисокосных лет и 365 високосных лет

0

Да, и вы можете проверить его. Вам лучше сделать это с gmtime, потому что localtime включает часовые пояса, а часовые пояса могут отбрасывать день на день, и нам это не нужно.

2000 год был високосным, и сложный, поэтому он делает хороший тест. Unix эпоха для полуночи 1 января 2000 UTC - 946684800 (30 лет + 7 дней с 1 января 1970 года). Таким образом, мы продвигаемся вперед 31 + 28 дней до 29 февраля. Мы можем использовать gmtime, чтобы получить день года, и asctime, чтобы убедиться, что у нас есть правильная дата.

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

int main() { 
    struct tm *date; 
    const int secs_per_day = 24 * 60 * 60; 

    /* Jan 1st, 2000 midnight UTC in Unix epoch. 
     30 years since Jan 1st, 1970. 
     Plus 7 leap days between Jan 1, 1970 and Jan 1, 2000. 
     Feb 29th 1972, 76, 82, 86, 92, and 96 
    */ 
    int days = (30 * 365) + 7; 
    time_t time = days * secs_per_day; 

    date = gmtime(&time); 
    printf("%d == %s", date->tm_yday, asctime(date)); 

    /* Jump ahead to Feb 29th */ 
    time += (31 + 28) * secs_per_day; 

    date = gmtime(&time); 
    printf("%d == %s", date->tm_yday, asctime(date)); 
} 

И мы можем видеть, что это работает, 29 февраля 2000 является 59-м (считая от 0) дня года.

0 == Sat Jan 1 00:00:00 2000 
59 == Tue Feb 29 00:00:00 2000