【c++實例總結】 時間time_t轉爲字符串輸出2(std::put_time與std::get_time)

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

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章