부제 : 아오 미네랄 써글넘의 localtime()

localtime() 함수는 struct tm * 형을 리턴하는데
다르게 말하면, glibc나 library 내의 변수의 포인터를 리턴하는 식이 되는지라 매번 할당해서 돌려주는게 아니라는 의미.
즉, 연속으로 localtime을 사용해서 포인터로 받는다면, 당연히 동일 주소 동일 내용이 되므로
조건식 비교에서 항상 참이 될 수 밖에 없다 -_-

struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);

POSIX.1-2001 says: "The asctime(), ctime(), gmtime(), and localtime() functions shall return values in one of two static objects: a broken-down time structure and an array of type char. Execution of any of the functions may overwrite the information returned in either of these objects by any of the other functions." This can occur in the glibc implementation.

[링크 : http://linux.die.net/man/3/localtime ]   


그런 이유로 아래와 같이 복사하거나, 처음부터 포인터가 아닌 값으로 받아 변수에 넣도록 해주는 것도 방법인데
오홍.. 아래 방법은 당연한 문법이지만 왜이리 생소해 보일까? ㅋㅋ

struct tm stTempTime;
pstCurTime = localtime(&lCurTime);
memcpy(&stTempTime, pstCurTime, sizeof(struct tm));

는 간단하게
struct tm stTempTime = *localtime(&lCurTime);

[링크 : http://kldp.org/node/71959 ]  

신고
Posted by 구차니

댓글을 달아 주세요

  1. 포인터를 반화하는 함수를 사용할 때 매우 유의해야할 내용을 정확히 적어 주셨네요. ^^

    2012.06.12 14:32 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 일하기 싫어병에 걸려서 이 단순한(?) 버그를
      일주일째 못 잡고 있다가 문득 생각나서 찾아봤더니 이거네요 ㅠ.ㅠ

      2012.06.12 14:52 신고 [ ADDR : EDIT/ DEL ]

Linux2012.03.27 14:46

mktime()을 사용하기 전에 1970을 빼고 값을 넣어준다면

localtime()으로 struct tm 형으로 받을 때에는 ts->tm_year + 1970 으로 출력을 해주어야 한다.

다른 시스템과의 혼용을 하지 않은다면은 1970을 빼지 않고 사용해도 되지만

유닉스 / 리눅스 시스템과 시간을 같이 사용하기 위해서는 1970 epoch를 계산해주어야 한다.


#include "stdio.h"
#include "time.h"

int main(void)
{
    time_t     now;
    struct tm  tmtm;
    struct tm  *ts;
    char       buf[80];

    /* Get the current time */
    //now = time(NULL);
    time(&now);

    /* Format and print the time, "ddd yyyy-mm-dd hh:mm:ss zzz" */
    ts = localtime(&now);
    strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
    printf("%s\n", buf);
    printf("%d\n",ts->tm_year);

    return 0;
}


2009/12/09 - [Linux] - 시간관련 함수/구조체 - time API on linux

---

혹시나 해서 찾아봤는데 시스템에 따라서는 epoch가 1900일수도 있다고 한다.

유닉스 계열은 1970 / NTP에서는 1900을 epoch로 사용한다.


[링크 : http://en.wikipedia.org/wiki/Epoch_(reference_date)]

신고

'Linux' 카테고리의 다른 글

리눅스를 위한 아이튠스 서버 만들기  (0) 2012.07.08
G840 cpuinfo  (0) 2012.04.14
localtime() 과 mktime()을 이용하기  (0) 2012.03.27
partitionless disk  (2) 2012.01.06
sudo와 selinux  (0) 2011.12.25
조이스틱 / 조이패드 on ubuntu  (2) 2011.12.23
Posted by 구차니

댓글을 달아 주세요

Linux2009.12.09 17:15

#include <time.h>

time_t time(time_t *t);
size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);

char *asctime(const struct tm *tm);
char *asctime_r(const struct tm *tm, char *buf);
char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);
struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);
struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);
time_t mktime(struct tm *tm);

struct tm
{
    int tm_hour;//     hour (0 - 23)
    int tm_isdst;//     Daylight saving time enabled (> 0), disabled (= 0), or unknown (< 0)
    int tm_mday;//     day of the month (1 - 31)
    int tm_min;//     minutes (0 - 59)
    int tm_mon;//     month (0 - 11, 0 = January)
    int tm_sec;//     seconds (0 - 59)
    int tm_wday;//     day of the week (0 - 6, 0 = Sunday)
    int tm_yday;//     day of the year (0 - 365)
    int tm_year;//     year since 1900
}

[링크 : http://en.wikipedia.org/wiki/Time.h] Time_t 구조체 내용
[링크 : http://en.wikipedia.org/wiki/Time_t]  Time_t 구조체 사용방법

[링크 : http://linux.die.net/man/3/strftime]
[링크 : http://linux.die.net/man/3/localtime]
[링크 : http://linux.die.net/man/3/mktime]

struct tm과 time_t 라는 타입은 시간에 사용된다.
mktime() 은 struct tm의 값으로 timt_t 형의 시간을 만들어 주고, time()은 현재의 시간을 반환해준다.(time_t *t = NULL)
localtime() 으로 time_t 형의 값으로 변환해준다.
strftime()은 sprintf와 비슷하게 time_t 형의 값을 받아 문자열로 시간을 나타내준다.

복잡하게 보이지만, 간단하게 예를 들자면,
int main(void)
{
    time_t     now;
    struct tm  tmtm;
    struct tm  *ts;
    char       buf[80];

    /* Get the current time */
    //now = time(NULL);
    tmtm.tm_year = 102;
    tmtm.tm_mon = 1;
    tmtm.tm_mday = 23;
    tmtm.tm_hour = 10;
    tmtm.tm_min = 12;
    tmtm.tm_sec = 51;
    now = mktime(&tmtm);

    /* Format and print the time, "ddd yyyy-mm-dd hh:mm:ss zzz" */
    ts = localtime(&now);
    strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
    printf("%s\n", buf);

    return 0;
}
결과는 아래와 같다.
 Sat 2002-02-23 10:12:51 KST
mktime()으로 원하는 시간과 날자를 넣고, (만약 주석된 time()을 풀면 현재 시간이 나온다)
localtime()을 통해서 time_t 형으로 변환하고
strftime()을 통해서 문자열로 출력을 한다.
만약에 요일이 궁금하다면 날자를 넣고, localtime() 한뒤 리턴되는 struct tm 의 값중 tm_wday 을 읽으면 된다.

[링크 : http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/3/mktime]
신고
Posted by 구차니

댓글을 달아 주세요