Study/C언어

처음하시는 분들을 위한 C언어 기초강의 시즌2 - 35 [라이브러리 함수3(날짜 및 시간, time.h)]

2019. 2. 16. 23:52

 제 35강) 라이브러리 함수3 - 날짜 및 시간

오늘은 "강의에서 다루지 않았던"의 다섯번째 시간입니다.

이번 시간에는 라이브러리 함수3인 날짜 및 시간 라이브러리에 대해서 다뤄보려고 합니다.

C언어에서 제공하는 "날짜 및 시간" 라이브러리는 time.h를 포함하면 사용이 가능합니다.

 

 자료형

time.h​ 에는 다음과 같이 4개의 자료형을 선언하고 있습니다.

 

 

 이름  자료형 원형  기능
 clock_t    Tick 수를 샐 수 있는 시계 전용 자료형(시스템 시간을 잴 때 사용)
 size_t  unsigned int  부호 없는 정수 자료형으로 바이트 단위의 크기를 나타낼 때 사용
 time_t    시간을 나타내기 위한 자료형
 struct tm    시간을 받아서 저장하는 구조체

 

여기서struct tm을 좀더 자세히 봅시다.

 

 멤버  자료형  뜻  범위
 tm_sec  int  초(seconds after the minute)  0 ~ 60
 tm_min  int  분(minutes after the hour)  0 ~ 59
 tm_hour  int  시간(hours since midnight)  0 ~ 23
 tm_mday  int  날짜(day of the month)  1 ~ 31
 tm_mon  int  달(months since January)  0 ~ 11
 tm_year  int  년도(years since 1900)  
 tm_wday  int  요일(days since Sunday)  0 ~ 6
 tm_yday  int  해당 년도의 1월부터 지금까지의 일수(days since January 1)  0 ~ 365
 tm_isdst  int  서머타임 여부(Daylight Saving Time flag)  

(표 내용 출처: http://www.cplusplus.com/reference/ctime/tm/)

이렇습니다.

이때 tm_year는 1900년도 이후로 측정되기 때문에 2018년은 118년으로 매깁니다. 그렇기 때문에 1900을 항상 더해주어서 출력해야합니다.

tm_mon는 1월은 0, 12월은 11로 나타내기 때문에1을 더해주어서 표현해야 합니다.

 

 

 함수

time.h​ 에서 자주쓰이는 함수들에 대해서 알아봅시다.

 

먼저 time 함수와 localtime 함수입니다.

#include <time.h>
 
time_t time (time_t* timer);
 -> 현재 시간을 time_t 자료형태로 반환 또는 timer에 저장한다.
 
struct tm* localtime (const time_t* timer);
 -> timer의 내용을 struct tm의 형태로 변환하여 저장한다.

여기서 time 함수는 2가지 형태로 자료를 저장할 수 있는데요.

time_t now_t;
 
now_t = time(0);
time(&now_t);

이렇게 사용합니다만 4번줄 방식이 3번줄 방식보다 더 많이 사용됩니다.

 

예제를 바로 봅시다.

#include <stdio.h>
#include <time.h>
 
int main()
{
    struct tm* now;
    time_t now_t;
    
    // now_t = time(0) 과 같은 뜻입니다.
    time(&now_t);                // 현재 시간을 now_t에 time_t 형태로 저장
    
    now = localtime(&now_t);     // time_t 형태의 자료를 struct tm 형태로 
    
    printf("[현재의 날짜와 시간]\n");
    printf("%d년 ", now->tm_year + 1900);
    printf("%d월 ", now->tm_mon + 1);
    printf("%d일 ", now->tm_mday);
    printf("%d시 ", now->tm_hour);
    printf("%d분 ", now->tm_min);
    printf("%d초\n", now->tm_sec);
 
    return 0;
}

현재 시간을 받아서 localtime 함수를 이용하여 struct tm형식의 자료형에 저장하여 출력합니다.

 

 

다음은 mktime 함수와 acstime 함수, ctime 함수 입니다.

#include <time.h>
 
time_t mktime (struct tm* timeptr);
-> struct tm 형태의 시간을 time_t 형태로 반환한다. (localtime의 반대)
 
 
char* asctime (const struct tm* timeptr);
-> struct tm 형태의 시간을 문자열로 나타내어줍니다.
-> 이때 출력되는 포멧은 "Www Mmm dd hh:mm:ss yyyy" 입니다.
 
 
char* ctime (const time_t* timer);
-> time_t 형태의 시간을 문자열로 나타태어줍니다.
-> 이때 출력되는 포멧은 "Www Mmm dd hh:mm:ss yyyy" 입니다.

여기서 mktime은 localtime과는 반대의 성격을 띕니다.

하지만 이때 기존의 timeptr은 입력되어 있는 값을 기준으로 재계산이 들어가게 됩니다.

timeptr의 tm_year, tm_mon, tm_mday만 입력되어 있었다고 한다면 mktime이 실행되면 나머지 인자들이 저절로 계산되어 값이 들어가게 됩니다.

이렇게 계산되어진 timeptr을 가지고 time_t로 변환을 하게 되는 것이죠.

asctime과 ctime의 기능은 같으나 asctime은 struct tm형을, ctime은 time_t형을 인자로 받습니다.

 

#include <stdio.h>
#include <time.h>
 
int main()
{
    struct tm* now;
    time_t now_t;
    
    time(&now_t);   // now_t = time(0) 과 같은 뜻입니다.
    now = localtime(&now_t);
    
    printf("[현재의 날짜와 시간]\n");
    printf("asctime: %s \n", asctime(now));
    printf("ctime: %s \n", ctime(&now_t));
 
    return 0;
}

위의 예제는 asctime과 ctime 예제입니다.

 

mktime은 예제가 조금은 복잡합니다.

/* 출처: http://www.cplusplus.com/reference/ctime/mktime/ */
/* mktime example: weekday calculator */
#include <stdio.h>      /* printf, scanf */
#include <time.h>       /* time_t, struct tm, time, mktime */
 
int main ()
{
  time_t rawtime;
  struct tm * timeinfo;
  int year, month ,day;
  const char * weekday[] = { "Sunday", "Monday",
                             "Tuesday", "Wednesday",
                             "Thursday", "Friday", "Saturday"};
 
  /* prompt user for date */
  printf ("Enter year: "); fflush(stdout); scanf ("%d",&year);
  printf ("Enter month: "); fflush(stdout); scanf ("%d",&month);
  printf ("Enter day: "); fflush(stdout); scanf ("%d",&day);
 
  /* get current timeinfo and modify it to the user's choice */
  time ( &rawtime );
  timeinfo = localtime ( &rawtime );
  timeinfo->tm_year = year - 1900;
  timeinfo->tm_mon = month - 1;
  timeinfo->tm_mday = day;
 
  /* mktime 계산하기 전 */    
  printf("Before: That day is a %s.\n", weekday[timeinfo->tm_wday]);
 
  /* call mktime: timeinfo->tm_wday will be set */
  mktime(timeinfo);
 
  /* mktime 계산한 후 */
  printf("After: That day is a %s.\n", weekday[timeinfo->tm_wday]);
  return 0;
}

직접 날짜를 입력받습니다. (16 ~ 18줄)

그렇게 입력받은 날짜를 timeinfo에 저장합니다.(21 ~ 25)

입력받은 3가지 인자를 토대로 mktime을 실행하게 되면 나머지 인자들도 자동 계산되어집니다.

여기서 기존의 날짜에 새롭게 입혀진 tm_year, tm_mon, tm_mday를 기반으로 다시 계산되어서 tm_wday가 새롭게 해당날짜에 맞게 바뀌게 됩니다.

 

그렇기 때문에 28번줄의 tm_wday(오늘 기준)와 34번줄의 tm_wday(입력된 값 기준)는 다르게 됩니다.

그렇죠?

 

 

이제 우리가 직접 출력 형식을 지정해줄 수 있는 함수인 strftime 함수를 봅시다.

#include <time.h>
 
size_t strftime (char* ptr, size_t maxsize, const char* format, const struct tm* timeptr);
-> ptr에 maxsize만큼 format 형식으로 timeptr을 문자열로 저장합니다.

여기서 format에서 사용할 수 있는 형식 지정자들을 확인하여봅시다.

 

 형식  설명  예
 %a  축약 형식의 요일
(Abbreviated weekday name)
 Sun
 %A  요일
(Full weekday name)
 Sunday
 %b  축약 형식의 월
(Abbreviated month name)
 Jan
 %B  월
(Full month name)
 January
 %c  날짜와 시간
(Date and time representation)
 Sun Jan 10 11:11:11 2018
 %C  세기로 나타냄
(Year divided by 100 and truncated to integer (00-99)
 21
 %d  일
(Day of the month, zero-padded (01-31))
 22
 %D  MM/DD/YY로 나타냄, %m/%d/%y와 같음
 (Short MM/DD/YY date, equivalent to %m/%d/%y)
 08/23/01
 %e  %d와 같으나 일 한자리 일수 앞에 공백이 붙음(  1-30)
 (Day of the month, space-padded ( 1-31))
 23
 %F  YYYY-MM-DD로 나타냄, %Y-%m-%d와 같음
(Short YYYY-MM-DD date, equivalent to %Y-%m-%d)
 2018-01-01
 %g  주 날짜의 두자리 연도
(Week-based year, last two digits (00-99))
 18
 %G  주 날짜의 네자리 연도
(Week-based year)
 
 %h  %b와 같음
(Abbreviated month name * (same as %b))
 
 %H  시(24시간)
(Hour in 24h format (00-23))
 13
 %I  시(12시간)
(Hour in 12h format (01-12))
 8
 %j  이번 년도의 일
(Day of the year (001-366))
 256
 %m  월
(Month as a decimal number (01-12))
 12
 %M  분
(Minute (00-59))
 52
 %n  개행
(New-line character ('\n'))
 
 %p  AM 또는 PM
(AM or PM designation)
 PM
 %r  12시간 기반의 시간
(12-hour clock time)
 02:55:02 PM
 %R  24시간 기반의 HH:MM 시간, %H:%M과 같음
(24-hour HH:MM time, equivalent to %H:%M)
 22:00
 %S  초
(Second (00-61))
 12
 %t  탭
(Horizontal-tab character ('\t'))
 
 %T  24시간 기반의 HH:MM:SS 시간, %H:%M:%S와 같음
(time format (HH:MM:SS), equivalent to %H:%M:%S)
 13:55:02
 %u  요일(월요일 : 1)
(weekday as number with Monday as 1 (1-7)) 
 5
 %U  연도의 해당 주 번호(첫번째 요일은 일요일)
(Week number with the first Sunday as the first day of week one (00-53))
 25
 %V  연도의 해당 주 번호
(week number (01-53))
 52
 %w  요일(일요일 : 0)
(Weekday as a decimal number with Sunday as 0 (0-6))
 4
 %W  연도의 해당 주 번호(첫번째 요일은 월요일)
(Week number with the first Monday as the first day of week one (00-53))
 17
 %x  로케일 기반의 날짜
(Date representation)
 08/23/01
 %X  로케일 기반의 시간
(Time representation)
 14:55:02
 %y  두자리 연도
(Year, last two digits (00-99))
 18
 %Y  연도
(Year)
 2018
 %z  UTC 오프셋, +는 GMT 동쪽, -GMT 서쪽, 1분 = 1, 1시간 = 100)
(offset from UTC in timezone (1 minute=1, 1 hour=100)
If timezone cannot be determined, no characters)
 +100
 %Z  로케일 기반 시간대 이름
(Timezone name or abbreviation, If timezone cannot be determined, no characters)
 CDT
 %%  %문자  

(표 출처: http://www.cplusplus.com/reference/ctime/strftime/)

문자가 정말정말 많죠?

 

 

필요할때마다 보면서 사용하면 되지만 대다수의 프로그래밍 언어의 시간관련 형식 지정자가 같으니 몇 번 쓰다보면 몇몇가지는 자연스레 외워집니다.

 

#include <stdio.h>     
#include <time.h>     
 
#define MAX 100
 
int main ()
{
  struct tm* now;
  time_t now_t;
  char str1[MAX] = { 0, };
  char str2[MAX] = { 0, };
  
  time(&now_t);
  now = localtime(&now_t);
  
  strftime(str1, MAX, "오늘은 %F %A 입니다.", now);
  strftime(str2, MAX, "지금 시간은 %p %I시 %M분 %S초 입니다.", now);
  
  printf("%s\n", str1);
  printf("%s\n", str2);
  
  return 0;
}

가장 간단한 몇가지 지정자를 이용한 예제입니다.

 

 

마지막으로 시간을 계산할 때 쓰이는 함수인 difftime 함수와 clock 함수입니다.

#include <time.h>
 
double difftime (time_t end, time_t beginning);
-> beginning시간 부터 end시간까지의 차를 구하여 걸린 시간을 구함
 
clock_t clock(void);
-> 프로그램이 시작한 이후부터 clock()함수를 호출할 때 까지의 시간을 구함

간단하게 예제를 봅시다.

 

#include <stdio.h>     
#include <time.h>     
 
int main ()
{
    int total = 0;
    time_t start, end;
    double timer1;
    clock_t timer2;
 
    time(&start);
    for (int i = 1; i <= 100000000; i++)
        total += i;
    time(&end);
    timer1 = difftime(end, start);
    timer2 = clock();
 
 
    printf("for문이 걸린 시간(difftime): %f초\n", timer1);
    printf("프로그램 수행 시간(clock): %f초\n", timer2 / CLOCKS_PER_SEC);
  
    return 0;
}

clock 함수의 경우에는 CLOCKS_PER_SEC으로 나누어줘야 초(Seconds)로 바뀝니다.

 

 

 

 다음 시간에는

이로서 기본적인 라이브러리 함수는 끝이 났습니다.

다음시간부터는 아주아주 기본적인 "알고리즘"을 보도록 하겠습니다.

저작자표시 비영리 변경금지 (새창열림)

'Study > C언어' 카테고리의 다른 글

처음하시는 분들을 위한 C언어 기초강의 시즌2 - 37 [정렬 알고리즘(선택 정렬)]  (0) 2020.01.29
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 38 [정렬 알고리즘(삽입 정렬)]  (0) 2020.01.29
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 34 [라이브러리 함수2(문자, 수학)]  (0) 2019.02.16
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 33 [라이브러리 함수1(변환, 랜덤)]  (0) 2019.02.16
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 32 [다루지 않았던2(Call by ~)]  (0) 2018.10.28
'Study/C언어' 카테고리의 다른 글
  • 처음하시는 분들을 위한 C언어 기초강의 시즌2 - 37 [정렬 알고리즘(선택 정렬)]
  • 처음하시는 분들을 위한 C언어 기초강의 시즌2 - 38 [정렬 알고리즘(삽입 정렬)]
  • 처음하시는 분들을 위한 C언어 기초강의 시즌2 - 34 [라이브러리 함수2(문자, 수학)]
  • 처음하시는 분들을 위한 C언어 기초강의 시즌2 - 33 [라이브러리 함수1(변환, 랜덤)]
Eskeptor
Eskeptor
Eskeptor
Hello World
Eskeptor
전체
오늘
어제
  • 분류 전체보기 (138)
    • Computer (5)
      • Linux (1)
      • Hardware (2)
      • Software (0)
      • Tips (1)
      • Website (0)
    • Mobile (1)
      • Application (1)
    • Study (108)
      • Android (9)
      • C언어 (45)
      • C++ (17)
      • Unity 5(유니티5) (11)
      • Qt 프로그래밍 (2)
      • MFC (12)
      • C#, Winform (12)
    • My World (24)
      • OpenPad(Android) (12)
      • 한글 패치 (1)
      • C#으로 만든 귀요미들 (5)
      • MFC로 만든 귀요미들 (6)
    • Life Goes On (0)
      • Hip Hop (0)

블로그 메뉴

  • 홈
  • 태그
  • 미디어로그
  • 위치로그
  • 방명록

공지사항

인기 글

태그

  • 유니티
  • 슈팅게임
  • 안드로이드
  • Unity
  • 메모장
  • 배열
  • 자바
  • 비행기
  • C++
  • Tetris
  • C#
  • 기초
  • Android
  • 포인터
  • 왕초보
  • C언어
  • openpad
  • 기본
  • 강좌
  • 오픈패드
  • 자료구조
  • MFC
  • 프로그래밍
  • 만들기
  • 초보
  • 알고리즘
  • 강의
  • c++11
  • Java
  • 테트리스

최근 댓글

최근 글

hELLO · Designed By 정상우.
Eskeptor
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 35 [라이브러리 함수3(날짜 및 시간, time.h)]
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.