ctime, ctime_s

ctime, ctime_s

에포크(epoch) 이후의 time_t 값을 "몇 시 몇 분" 같은 사람이 읽을 수 있는 문자열로 바로 바꾸고 싶을 때 쓰는 함수가 ctime이에요. 내부적으로 asctime(localtime(timer))을 호출하는 셈이에요. 정적 버퍼와 정적 tm을 쓰고 스레드에 안전하지 않아서, C23부터는 폐기됐어요. <time.h>에 정의돼 있어요.

출처: cppreference

본문

ctime()은 에포크 이후의 시간을 로컬 달력 시간으로 바꾼 뒤, 다시 텍스트 표현으로 변환해요. asctime(localtime(timer))(C23부터는 asctime(localtime_r(timer, &(struct tm){0})))을 호출한 것과 같아요. C23부터 이 함수는 폐기되어 새 코드에서 쓰면 안 돼요.

char*                ctime( const time_t* timer );   // (1) until C23
[[deprecated]] char* ctime( const time_t* timer );   // (1) since C23
errno_t ctime_s( char *buf, rsize_t bufsz, const time_t* timer ); // (2) since C11

(2)번 ctime_s는 (1)과 같지만 asctime_s(buf, bufsz, localtime_s(timer, &(struct tm){0}))와 동등하며, 다음 오류를 런타임에 감지하면 설치된 제약 처리 함수를 호출해요.

  • buf 또는 timer가 널 포인터
  • bufsz가 26보다 작거나 RSIZE_MAX보다 큼

대부분의 경계 검사 함수처럼, ctime_s는 구현이 __STDC_LIB_EXT1__을 정의하고 사용자가 <time.h>를 포함하기 전에 __STDC_WANT_LIB_EXT1__을 정수 상수 1로 정의했을 때만 쓸 수 있어요.

결과 문자열의 형식은 다음과 같아요.

Www Mmm dd hh:mm:ss yyyy\n
  • Www — 요일 (Mon~Sun 중 하나)
  • Mmm — 달 (Jan~Dec 중 하나)
  • dd — 일
  • hh — 시
  • mm — 분
  • ss — 초
  • yyyy — 연도

이 함수는 지역화(localization)를 지원하지 않아요.

매개변수

매개변수 설명
timer 출력할 시간을 담은 time_t 객체를 가리키는 포인터
buf 크기가 최소 bufszchar 배열의 첫 요소를 가리키는 포인터
bufsz 출력할 최대 바이트 수. 보통 buf가 가리키는 버퍼의 크기

반환값

  1. 날짜·시간의 텍스트 표현을 담은 정적 null 종결 문자열을 가리키는 포인터. 이 문자열은 asctimectime이 공유할 수 있고, 두 함수 중 하나가 호출될 때마다 덮어써질 수 있어요.

  2. 성공 시 0(시간 표현이 buf에 쓰임). 실패 시 0이 아닌 값. 실패하면 buf[0]에 종결 null이 항상 쓰여요(buf가 널이거나 bufsz가 0 또는 RSIZE_MAX보다 큰 경우 제외).

주의

  • ctime은 정적 데이터를 가리키는 포인터를 돌려주고 스레드에 안전하지 않아요. 게다가 gmtime·localtime과 공유할 수 있는 정적 tm 객체도 수정해요. POSIX도 이 함수를 쓸모없어졌다(obsolete)고 보고 strftime 사용을 권장해요. C 표준도 strftime이 더 유연하고 로케일을 고려하므로 ctimectime_s 대신 strftime을 권장해요.
  • time_t의 값이 문자열을 25자보다 길게 만들면(예: 연도 10000) ctime의 동작은 정의되지 않아요.

예시

현재 시간을 ctime으로 바로 출력하는 흐름이에요. printf%s 때문에 개행이 한 번 더 붙는다는 점을 주의하세요.

#define __STDC_WANT_LIB_EXT1__ 1
#include <time.h>
#include <stdio.h>

int main(void)
{
    time_t result = time(NULL);
    printf("%s", ctime(&result));

#ifdef __STDC_LIB_EXT1__
    char str[26];
    ctime_s(str,sizeof str,&result);
    printf("%s", str);
#endif
}

가능한 출력(예시):

Tue May 26 21:51:03 2015
Tue May 26 21:51:03 2015

더 알아보기

  • tm 객체를 문자열로 바꾸는 함수는 asctime/asctime_s를 봐요.
  • 더 유연하고 로케일을 고려하는 형식 변환은 strftime을 봐요.
  • cppreference의 ctime 원문을 참고해요.