문제

이것은 아무도 할 필요가없는 것처럼 보이지만 내장 된 시스템 (OpenWrt)을 위해 커널 모듈에서 작업하고있는 것 같습니다. time.h 하다 포함 timespec 그리고 time_t 유형과 clock_gettime 그리고 gmtime 기능하지만 그렇습니다 ~ 아니다 포함 localtime, ctime, time, 또는 비판적으로 tm 유형.

gmtime에서 내 구조물로 반환 포인터를 캐스트하려고 할 때 Segfault를 얻습니다.

그래서 나는 두 가지 방법 중 하나의 문제를 해결하기 위해 만족할 것 같아요. 누락 된 유형에 액세스하는 방법을 알아내는 것이 좋을 것입니다.

도움이 되었습니까?

해결책

이것은 정확해야합니다 (컷 다운 모방을 작성합니다. struct tm, 나의 year 1900 CE Epoch 대신 일반적인 시대를 사용합니다) :

struct xtm
{
    unsigned int year, mon, day, hour, min, sec;
};

#define YEAR_TO_DAYS(y) ((y)*365 + (y)/4 - (y)/100 + (y)/400)

void untime(unsigned long unixtime, struct xtm *tm)
{
    /* First take out the hour/minutes/seconds - this part is easy. */

    tm->sec = unixtime % 60;
    unixtime /= 60;

    tm->min = unixtime % 60;
    unixtime /= 60;

    tm->hour = unixtime % 24;
    unixtime /= 24;

    /* unixtime is now days since 01/01/1970 UTC
     * Rebaseline to the Common Era */

    unixtime += 719499;

    /* Roll forward looking for the year.  This could be done more efficiently
     * but this will do.  We have to start at 1969 because the year we calculate here
     * runs from March - so January and February 1970 will come out as 1969 here.
     */
    for (tm->year = 1969; unixtime > YEAR_TO_DAYS(tm->year + 1) + 30; tm->year++)
        ;

    /* OK we have our "year", so subtract off the days accounted for by full years. */
    unixtime -= YEAR_TO_DAYS(tm->year);

    /* unixtime is now number of days we are into the year (remembering that March 1
     * is the first day of the "year" still). */

    /* Roll forward looking for the month.  1 = March through to 12 = February. */
    for (tm->mon = 1; tm->mon < 12 && unixtime > 367*(tm->mon+1)/12; tm->mon++)
        ;

    /* Subtract off the days accounted for by full months */
    unixtime -= 367*tm->mon/12;

    /* unixtime is now number of days we are into the month */

    /* Adjust the month/year so that 1 = January, and years start where we
     * usually expect them to. */
    tm->mon += 2;
    if (tm->mon > 12)
    {
        tm->mon -= 12;
        tm->year++;
    }

    tm->day = unixtime;
}

모든 마법 숫자에 대한 사과드립니다. 367*Month/12는 달력의 30/31 일 시퀀스를 생성하는 깔끔한 트릭입니다. 계산은 3 월에 시작된 몇 년 동안 끝날 때까지 시작되며, 이는 도약의 날이 "연도"의 끝에 떨어지기 때문에 쉬운 일을 해줍니다.

다른 팁

사용자 공간에서 GLIBC는 시간 표현의 "로컬"부분을 처리하는 것과 관련하여 많은 작업을 수행합니다. 커널 내에서는 사용할 수 없습니다. 아마도 필요한 경우 사용자 공간 에서이 작업을 수행하지 말아야 할 것입니다.

time_t 1970 년 1 월 1 일 이후 UTC 이후 UTC에서 결과를 원한다면 월, 일 및 연도로 분해되는 몇 초가되지 않습니다. 이있다 사용 가능한 소스 인터넷 검색으로 "gmtime 소스". 대부분의 임베디드 시스템은 시간대 설정 및 환경에 대한 의존으로 인해 조금 더 어렵 기 때문에 현지 시간 처리를 남기지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top