﻿#include "Dateformat.h"




Dateformat::Dateformat()
{
# if false
#include <minwindef.h>
#include <sysinfoapi.h>
	FILETIME ft;
	GetSystemTimePreciseAsFileTime(&ft);
	ULARGE_INTEGER uli;
	uli.LowPart = ft.dwLowDateTime;
	uli.HighPart = ft.dwHighDateTime;
	// 将微秒级时间戳转换为毫秒级时间戳 单位：100ns
	this->timestamp =(unsigned long long)uli.QuadPart / 10;
#else
	timeb t;
	ftime(&t);
	this->timestamp = t.time * 1000 + t.millitm;
#endif
}

Dateformat::Dateformat(uint64_t ts)
{
	this->timestamp = ts;
}

string Dateformat::currentTimeString()
{
	Dateformat df;
	return df.toString("yyyy-MM-dd HH:mm:ss.SSS");
}

string Dateformat::currentTimeString(string format)
{
	Dateformat df;
	return df.toString(format);
}
uint64_t Dateformat::getTimestamp()
{
	return this->timestamp;
}

uint64_t Dateformat::fromString(string timeString, string format)
{
	format_vec_t tempVec[100] = { 0 };
	int segNum = format_parse(format, tempVec);
	int msec = 0;
	time_t rawtime = 0;
	struct tm* p = localtime(&rawtime); int index = 0;
	for (int i = 0; i < segNum; i++) {
		string tempString = timeString.substr(index, tempVec[i].count);

		switch (tempVec[i].character)
		{
		case 'y': {
			p->tm_year = atoi(tempString.c_str()) - 1900;
			break;
		}
		case 'M': {
			p->tm_mon = atoi(tempString.c_str()) - 1;
			break;
		}
		case 'd': {
			p->tm_mday = atoi(tempString.c_str());
			break;
		}
		case 'h': {
			p->tm_hour = atoi(tempString.c_str());
			break;
		}
		case 'H': {
			p->tm_hour = atoi(tempString.c_str());
			break;
		}

		case 'm': {
			p->tm_min = atoi(tempString.c_str());
			break;
		}
		case 's': {
			p->tm_sec = atoi(tempString.c_str());
			break;
		}
		case 'S': {
			msec = atoi(tempString.c_str());
			break;
		}

		default:
			break;
		}
		index += tempVec[i].count;
	}

	return mktime(p) * 1000 + msec;
}

uint64_t Dateformat::now()
{
	timeb t;
	ftime(&t);
	return t.time * 1000 + t.millitm;
}

string Dateformat::duration(uint64_t ts, string format)
{
	uint32_t msec = ts % 1000;
	int sec = (ts - msec) / 1000 % 60;
	int min = (ts - msec - 1000 * sec) / 1000 / 60 % 60;
	int hour = (ts - msec - 1000 * sec - 60 * 1000 * min) / 1000 / 60 / 60 % 24;
	int day = (int)(ts - msec - 1000 * sec - 60 * 1000 * min - 60 * 60 * 1000 * hour) / 1000 / 60 / 60 / 24;

	format_vec_t tempVec[100] = { 0 };
	int segNum = format_parse(format, tempVec);

	string result;
	for (int i = 0; i < segNum; i++) {
		char tempBuff[32] = { 0 };
		switch (tempVec[i].character)
		{
		case 'y': {
			result.append("0");
			break;
		}
		case 'M': {
			result.append("0");
			break;
		}
		case 'd': {
			sprintf(tempBuff, "%02d", day);
			result.append(tempBuff);
			break;
		}
		case 'H': {
			sprintf(tempBuff, "%02d", hour);
			result.append(tempBuff);
			break;
		}
		case 'm': {
			sprintf(tempBuff, "%02d", min);
			result.append(tempBuff);
			break;
		}
		case 's': {
			sprintf(tempBuff, "%02d", sec % 60);
			result.append(tempBuff);
			break;
		}
		case 'S': {
			sprintf(tempBuff, "%03d", msec);
			result.append(tempBuff);
			break;
		}
		default:
			string temp = "*";
			temp[0] = tempVec[i].character;
			result.append(temp);
			break;
		}
	}
	return string(result);
}

int Dateformat::format_parse(string format, format_vec_t* vecBuff) {
	int i = 0, j = 0, k = 0;
	for (i = 0; i < format.length(); k++)
	{
		string tempString = format.substr(i, 1);
		for (j = 0; j < 10; j++)
		{
			if (format.substr(i + j, 1)._Equal(tempString.c_str())) {
				continue;
			}
			else {
				break;
			}
		}
		vecBuff[k].character = tempString.c_str()[0];
		vecBuff[k].count = j;
		i = i + j;
	}
	return k;
}

string Dateformat::toString(string format)
{
	time_t sec = this->timestamp / 1000;
	uint32_t msec = this->timestamp % 1000;
	struct tm* p = localtime(&sec);

	format_vec_t tempVec[100] = { 0 };
	int segNum = format_parse(format, tempVec);

	string result;
	for (int i = 0; i < segNum; i++) {
		char tempBuff[32] = { 0 };
		switch (tempVec[i].character)
		{
		case 'y': {
			sprintf(tempBuff, "%04d", 1900 + p->tm_year);
			result.append(tempBuff);
			break;
		}
		case 'M': {
			sprintf(tempBuff, "%02d", 1 + p->tm_mon);
			result.append(tempBuff);
			break;
		}
		case 'd': {
			sprintf(tempBuff, "%02d", p->tm_mday);
			result.append(tempBuff);
			break;
		}
		case 'h': {
			sprintf(tempBuff, "%02d", p->tm_hour % 12);
			result.append(tempBuff);
			break;
		}
		case 'H': {
			sprintf(tempBuff, "%02d", p->tm_hour);
			result.append(tempBuff);
			break;
		}
		case 'a': {
			if (p->tm_hour > 12) {
				result.append("PM");
			}
			else {
				result.append("AM");
			}
			break;
		}
		case 'm': {
			sprintf(tempBuff, "%02d", p->tm_min);
			result.append(tempBuff);
			break;
		}
		case 's': {
			sprintf(tempBuff, "%02d", p->tm_sec);
			result.append(tempBuff);
			break;
		}
		case 'S': {
			sprintf(tempBuff, "%03d", msec);
			result.append(tempBuff);
			break;
		}
		default:
			string temp = "*";
			temp[0] = tempVec[i].character;
			result.append(temp);
			break;
		}
	}
	return string(result);
}