Locale: 时间格式化.

在了解时间格式化之前我们需要对C语言的一个时间库有些了解:

在C++中需要: #include<ctime>

std::clock_t:   在vs2015中其实是: typedef long clock_t; 其实是用来表示CPU在一段时间内trick的次数.

CLOCKS_PER_SEC: 这个类型是定义的CPU在每秒trick的次数.

                                          vs2015中定义为: #define CLOCKS_PER_SEC  ((clock_t)1000). 也就是说CPU每秒trick 1000次.

std::time_t: 在vs2015中的定义为 int64_t; 用来表示从一个epoch(起始点: 一般情况下都为1970/1/1 00:00)到某一个时间点经过了多少秒.

 

struct tm:  这是一个struct类型:

struct tm{
  
int tm_ses; //seconds after the minute – [0, 61](until C++11) / [0, 60] (since C++11)[note 1]

int tm_min; //minutes after the hour – [0, 59]

int tm_hour; //hours since midnight – [0, 23]

int tm_mday; //day of the month – [1, 31]

int tm_mon; //months since January – [0, 11]

int tm_year; //years since 1900

int tm_wday; //days since Sunday – [0, 6]

int tm_yday; //days since January 1 – [0, 365]

int tm_isdst; //Daylight Saving Time flag. The value is positive if DST is in effect, zero if not and negative if no information is available 
};

 

std::clock( std::time_t* arg ): 这是一个函数用于返回从程序开始运行开始 CPU trick了多少次(在传递一个nullptr作为指针参数的情况下).返回类型为 std::time_t;

Demo:

#include <ctime>
#include <iostream>
 
int main()
{
    std::time_t result = std::time(nullptr);
    std::cout << std::asctime(std::localtime(&result))
              << result << " seconds since the Epoch\n";
}

 

double difftime( std::time_t time_end, std::time_t time_beg ) :

返回time_beg - time_end的值,返回类型为double.

 

std::tm* localtime(const std::time_t*  arg):

转换 arg 为 std::tm类型考虑时区.

 

std::tm* gmtime(const std::time_t* arg):

转换 arg 为 std::tm类型不考虑时区.

 

 char* asctime(const std::tm* arg):

转换std::tm类型为标准日历时间字符串.

 

std::size_t strftime(char* str, std::size_t count, const char* fmt, const std::tm* time):

转换time 为用户自定义的日历时间字符串,

Demo:

#include <ctime>
#include <iostream>
#include <locale>
 
int main()
{
    std::locale::global(std::locale("ja_JP.utf8"));
    std::time_t t = std::time(NULL);
    char mbstr[100];
    if (std::strftime(mbstr, sizeof(mbstr), "%A %c", std::localtime(&t))) {
        std::cout << mbstr << '\n';
    }
}

 

char* ctime(const std::time_t* time);

转换time为字符串类型并且考虑时区。相当于: std::asctime(std::localtime(t));

 

 

之后再来让我们看一下用cpp实现的一个大demo:

//formattime.h

#include <iostream>
#include <locale>
#include <string>
#include <chrono>
#include <utility>
#include <sstream>
#include <ctime>


namespace TT {

	class Date {
	public:
		Date(const std::locale& loc_ = std::locale::classic()) :loc(loc_) {};

		Date(const Date& other);

		Date& operator=(const Date& other);

		~Date() = default;

		//获取当前系统时间. 默认为:false(不考虑时区).
		std::basic_string<char>& currentTime(bool isSpecifyLocale = false)noexcept;

		//通过给定的fmt,来解析给定的时间string.
		std::tm& parseStr(const std::basic_string<char>& str, const std::basic_string<char>& strFmt);

		//刚刚解析过出来的时间都被存放在了std::tm中,这里呢我们可以通过制定fmt获取我们想要的年月日...
		std::basic_string<char> formatStr(const std::basic_string<char>& fmt);

	private:
		std::tm tm{};
		std::locale loc;
		std::basic_string<char> unFormatStr;
		//std::basic_string<char> formatedStr;
	};

}
//formattime.cpp

#include "formattime.h"

namespace TT {
	Date::Date(const Date& other)
		:tm(other.tm),
		loc(other.loc),
		unFormatStr(other.unFormatStr)
	{
		//constructor
	}

	TT::Date& Date::operator=(const Date& other)
	{
		this->tm = other.tm;
		this->loc = other.loc;
		this->unFormatStr = other.unFormatStr;

		return *this;
	}

	std::basic_string<char>& Date::currentTime(bool isSpecifyLocale)noexcept
	{
		std::chrono::system_clock::time_point timeP = std::chrono::system_clock::now();
		std::time_t  timeT = std::chrono::system_clock::to_time_t(timeP);

		if (isSpecifyLocale == true) {
			this->unFormatStr = std::asctime(std::gmtime(&timeT)); //考虑时区

		}
		else {
			this->unFormatStr = std::ctime(&timeT); //不考虑时区.
			int size = (this->unFormatStr).size();
			(this->unFormatStr).resize(size - 1);
		}

		return (this->unFormatStr);
	}


	std::tm& Date::parseStr(const std::basic_string<char>& str, const std::basic_string<char>& strFmt)
	{
		if (strFmt.empty()) {
			throw std::runtime_error("Parse error");
		}

		this->unFormatStr = str;

		std::basic_istringstream<char> inStream{ str };
		inStream.imbue(this->loc);
		std::istreambuf_iterator<char> inBuf{inStream};

		const std::time_get<char>& timeGet = std::use_facet<std::time_get<char>>(this->loc);

		std::ios::iostate state = std::ios::goodbit;

		timeGet.get(inBuf, std::istreambuf_iterator<char>{}, inStream, state, &(this->tm), &strFmt[0], &strFmt[0] + strFmt.size());

		return (this->tm);
	}

	std::basic_string<char> Date::formatStr(const std::basic_string<char>& fmt)
	{
		std::basic_ostringstream<char> outStream{};
		outStream.imbue(this->loc);

		std::ostreambuf_iterator<char> outBuf{outStream};

		const std::time_put<char>& timePut = std::use_facet<std::time_put<char>>(this->loc);

		timePut.put(outStream, outStream, '//', &(this->tm), &fmt[0], &fmt[0] + fmt.size());

		return (outStream.str());
	}
}

 

转载于:https://my.oschina.net/SHIHUAMarryMe/blog/769806

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值