1.基礎介紹
頭文件:
#include <iomanip> //io 操作,manipulator是操作的意思,英文全稱的縮寫
api:
(1)std::put_time
c++源碼:
// TEMPLATE STRUCT _Timeobj
template<class _Elem,
class _Ptr>
struct _Timeobj
{ // store reference to tm object and format
_Timeobj(_Ptr _Tptr_arg, const _Elem *_Fmt_arg)
: _Tptr(_Tptr_arg), _Fmtfirst(_Fmt_arg)
{ // construct from tm pointer and format pointer
for (_Fmtlast = _Fmtfirst; *_Fmtlast != 0; ++_Fmtlast)
; // find end of format string
}
_Ptr _Tptr; // the tm struct pointer
const _Elem *_Fmtfirst; // format string start
const _Elem *_Fmtlast; // format string end
};
// TEMPLATE FUNCTION put_time
template<class _Elem> inline
_Timeobj<_Elem, const struct tm *>
put_time(const struct tm *_Tptr_arg, const _Elem *_Fmt_arg)
{ // return a _Timeobj manipulator
return (_Timeobj<_Elem, const struct tm *>(_Tptr_arg, _Fmt_arg));
}
template<class _Elem,
class _Traits,
class _Elem2> inline
basic_ostream<_Elem, _Traits>&
operator<<(basic_ostream<_Elem, _Traits>& _Ostr,
const _Timeobj<_Elem2, const struct tm *>& _Manip)
{ // put time information to output stream
typedef basic_ostream<_Elem, _Traits> _Myos;
typedef ostreambuf_iterator<_Elem, _Traits> _Iter;
typedef time_put<_Elem2, _Iter> _Mytput;
static_assert(is_same<_Elem, _Elem2>::value,
"wrong character type for put_time");
ios_base::iostate _State = ios_base::goodbit;
const typename _Myos::sentry _Ok(_Ostr);
if (_Ok)
{ // state okay, insert monetary amount
const _Mytput& _Tput_fac = _USE(_Ostr.getloc(), _Mytput);
_TRY_IO_BEGIN
if (_Tput_fac.put(_Iter(_Ostr.rdbuf()), _Ostr, _Ostr.fill(),
_Manip._Tptr, _Manip._Fmtfirst, _Manip._Fmtlast).failed())
_State |= ios_base::badbit;
_CATCH_IO_(_Ostr)
}
_Ostr.setstate(_State);
return (_Ostr);
}
由源碼可知std::put_time第一個形參是tm,第二個形參是輸出格式,返回值是_Timeobj,而c++重載了"<<"支持_Timeobj,所以c++可直接輸入類似於std::cout << std::put_time()...這樣的操作
(2)std::get_time
c++源碼:
template<class _Elem,
class _Ptr>
struct _Timeobj
{ // store reference to tm object and format
_Timeobj(_Ptr _Tptr_arg, const _Elem *_Fmt_arg)
: _Tptr(_Tptr_arg), _Fmtfirst(_Fmt_arg)
{ // construct from tm pointer and format pointer
for (_Fmtlast = _Fmtfirst; *_Fmtlast != 0; ++_Fmtlast)
; // find end of format string
}
_Ptr _Tptr; // the tm struct pointer
const _Elem *_Fmtfirst; // format string start
const _Elem *_Fmtlast; // format string end
};
// TEMPLATE FUNCTION get_time
template<class _Elem> inline
_Timeobj<_Elem, struct tm *>
get_time(struct tm *_Tptr_arg, const _Elem *_Fmt_arg)
{ // return a _Timeobj manipulator
return (_Timeobj<_Elem, struct tm *>(_Tptr_arg, _Fmt_arg));
}
template<class _Elem,
class _Traits,
class _Elem2> inline
basic_istream<_Elem, _Traits>&
operator>>(basic_istream<_Elem, _Traits>& _Istr,
const _Timeobj<_Elem2, struct tm *>& _Manip)
{ // get time information from input stream
typedef basic_istream<_Elem, _Traits> _Myis;
typedef istreambuf_iterator<_Elem, _Traits> _Iter;
typedef time_get<_Elem2, _Iter> _Mytget;
static_assert(is_same<_Elem, _Elem2>::value,
"wrong character type for get_time");
ios_base::iostate _State = ios_base::goodbit;
const typename _Myis::sentry _Ok(_Istr);
if (_Ok)
{ // state okay, extract time amounts
const _Mytget& _Tget_fac = _USE(_Istr.getloc(), _Mytget);
_TRY_IO_BEGIN
_Tget_fac.get(_Iter(_Istr.rdbuf()), _Iter(0), _Istr, _State,
_Manip._Tptr, _Manip._Fmtfirst, _Manip._Fmtlast);
_CATCH_IO_(_Istr)
}
_Istr.setstate(_State);
return (_Istr);
}
由源碼可知std::get_time第一個參數是tm,第二個同樣是輸入格式,返回值是_Timeobj,而c++也重載了">>"支持_Timeobj,所以
c++可直接輸入類似std::cin >> std::get_time()...這樣的操作
2.例子
#include <iostream>
#include <sstream>
#include <ctime> //對應c語言time.h
#include <iomanip>//io操作
#include <process.h>
int main()
{
//顯示1例子
time_t rawtime;
struct tm info;
char buffer[80];
time(&rawtime);
//localtime_s(&info, &rawtime); //將time_t轉爲tm
//std::localtime非線程安全,使用localtime_r函數代替
localtime_s(&info, &rawtime);//將time_t轉爲tm
//ctime是非線程安全的,C標準也建議使用strftime,不要使用ctime、ctime_s
strftime(buffer, 80, "%Y-%m-%d %H:%M:%S", &info);
printf("格式化的日期 & 時間 : |%s|\n", buffer);
//轉換例子
time_t dd = std::mktime(&info);//將tm轉爲time_t
//顯示2例子:使用std::put_time,std::get_time
std::cout << std::put_time(&info, "%Y-%m-%d %H:%M:%S");
//std::cout << std::put_time(&info, "%F %T\n");
//get_time例子
std::stringstream ss;
ss << std::put_time(&info, "%Y-%m-%d %H:%M:%S");
struct tm info2;
ss >> std::get_time(&info2, "%Y-%m-%d %H:%M:%S");
system("pause");
return 0;
}
注意:
(1)time(null)單位是s
(2)std::put_time、std::get_time中格式與strftime中格式是一致的,格式介紹如下:
strftime(buffer, 80, "%Y-%m-%d %H:%M:%S", &info);
std::cout << std::put_time(&info, "%Y-%m-%d %H:%M:%S");
ss >> std::get_time(&info2, "%Y-%m-%d %H:%M:%S");
=>
%Y-%m-%d %H:%M:%S
%Y --年
%m --月
%d --日
%H --時
%M --分
%S --秒
更高級:
%F 等價於 %Y-%m-%d,
%T 等價於 %H:%M:%S
所以也可以寫爲
strftime(buffer, 80, "%F %T", &info);
std::cout << std::put_time(&info, "%F %T");
ss >> std::get_time(&info2, "%F %T");
更多格式詳細介紹:https://zh.cppreference.com/w/cpp/io/manip/put_time