C言語のデータ型は主に、文字・数値・判定・時間・ポインタである。
今回はその中で、"時間"についての扱い方を紹介する。
time_t型
#include <time.h>
で呼べるグリニッチ標準時(GMT)で1970/1/1 00:00:00
から現在までの経過"秒数"を返す型。返し値は秒[sec]単位であり、エラー時は-1を返し、1970年1月1日以前の時間はエラーとなり-1を返すことに注意。
struct tm構造体
#include <time.h>
の中で宣言され、time_tの変数を年・月・日・時・分・秒に分けることができる。
struct tm {
int tm_sec; /* 秒 [0-61] 最大2秒までのうるう秒を考慮 */
int tm_min; /* 分 [0-59] */
int tm_hour; /* 時 [0-23] */
int tm_mday; /* 日 [1-31] */
int tm_mon; /* 月 [0-11] 0から始まることに注意 */
int tm_year; /* 年 [1900からの経過年数] */
int tm_wday; /* 曜日 [0:日 1:月 ... 6:土] */
int tm_yday; /* 年内の通し日数 [0-365] 0から始まることに注意*/
int tm_isdst; /* 夏時間が無効であれば 0 */
long tm_gmtoff; /*グリニッジ時刻からのオフセット*/
char *tm_zone; /*タイムゾーン*/
};
使い方は以下のようにtime_t変数をlocaltime64で構造体に変換して変数に渡す。
struct tm when;
time_t tme = time(NULL);
when = *localtime64(&tme);
strftime~struct tm構造体からstring型へ変換~
#include <time.h>
で宣言されるstrftimeで、string型に任意の形式で変換できる。
strftime(datetime,sizeof(datetime),"%Y/%m/%d %H:%I:%S",&when);
_mktime64~struct tm構造体からtime_t型変数へ変換~
#include <time.h>
で宣言される_mktime64で、struct tm構造体を受け取りtime_t型を返す。
time_t new_t = _mktime64(&when)
std::put_time~time_t型変数からstring型へ変換~
std::put_timeを使い、time_tをstringに変換したのち、ostringstream()で一度文字列ストリームへ受け渡し、string型変数へ渡している。
std::string longdate = static_cast<ostringstream&&>(ostringstream() << std::put_time(localtime(&t), "%Y/%m/%d %H:%M:%S")).str();
string型からtime_t型への変換
ファイルを読み込んだ時、いろいろな書き方で日付を指定しているので、複数の場合分けをしてstruct tm構造体へ渡したのち、time_t型へ変換している。
time_t string_to_time_t(string s)
{
int yy, mm, dd, hour, min, sec;
struct tm when;
time_t tme;
size_t len = s.size();
if (s[len-6] == ':' ) {
memset(&when, 0, sizeof(struct tm));
sscanf(s.c_str(), "%d/%d/%d %d:%d:%d", &yy, &mm, &dd, &hour, &min, &sec);
time(&tme);
when = *_localtime64(&tme);
when.tm_year = yy-1900;
when.tm_mon = mm-1;
when.tm_mday = dd;
when.tm_hour = hour;
when.tm_min = min;
when.tm_sec = sec;
return _mktime64(&when);
} else if (s[len-3] == ':' ) {
memset(&when, 0, sizeof(struct tm));
sscanf(s.c_str(), "%d/%d/%d %d:%d", &yy, &mm, &dd, &hour, &min);
time(&tme);
when = *_localtime64(&tme);
when.tm_year = yy-1900;
when.tm_mon = mm-1;
when.tm_mday = dd;
when.tm_hour = hour;
when.tm_min = min;
when.tm_sec = 0;
return _mktime64(&when);
} else if (s[len-3] == ' ' ) {
memset(&when, 0, sizeof(struct tm));
sscanf(s.c_str(), "%d/%d/%d %d", &yy, &mm, &dd, &hour);
time(&tme);
when = *_localtime64(&tme);
when.tm_year = yy-1900;
when.tm_mon = mm-1;
when.tm_mday = dd;
when.tm_hour = hour;
when.tm_min = 0;
when.tm_sec = 0;
return _mktime64(&when);
}else {
memset(&when, 0, sizeof(struct tm));
sscanf(s.c_str(), "%d/%d/%d", &yy, &mm, &dd);
time(&tme);
when = *_localtime64(&tme);
when.tm_year = yy-1900;
when.tm_mon = mm-1;
when.tm_mday = dd;
when.tm_hour = 0;
when.tm_min = 0;
when.tm_sec = 0;
return _mktime64(&when);
}
}
基準時刻の変更
std::cout.imbue(std::locale("ja_JP.utf8"));
std::cout.imbue(std::locale("en_US.utf8"));/*英語 アメリカ*/
std::cout.imbue(std::locale("ar_EG.UTF-8"));/*アラビア語 エジプト*/
std::cout.imbue(std::locale("as_IN.UTF-8")); /*アッサム語 インド*/
std::cout.imbue(std::locale("de_DE.UTF-8"));/*ドイツ語 ドイツ*/
std::cout.imbue(std::locale("en_GB.UTF-8"));/*英語 イギリス*/
std::cout.imbue(std::locale("es_ES.UTF-8"));/*スペイン語 スペイン*/
std::cout.imbue(std::locale("fr_FR.UTF-8"));/*フランス語 フランス*/
std::cout.imbue(std::locale("it_IT.UTF-8"));/*イタリア語 イタリア*/
std::cout.imbue(std::locale("ko_KR.UTF-8"));/*韓国語*/
std::cout.imbue(std::locale("zh_CN.UTF-8"));/*中国語*/
まとめ
今回はCにおける時間・日付の取り扱いについて紹介した。