阿赵UE引擎C++编程学习笔记——时间日期相关,阿赵UE引擎C++编程学习笔记,时间日期功能详解

马肤
阿赵UE引擎C++编程学习笔记中,关于时间日期相关的内容,主要介绍了如何使用C++处理时间日期数据。笔记详细讲解了时间日期数据结构、时间函数的使用以及时间格式化等相关知识点。通过学习,读者可以掌握在UE引擎中使用C++进行时间日期操作的基本方法和技巧。

  大家好,我是阿赵。

阿赵UE引擎C++编程学习笔记——时间日期相关,阿赵UE引擎C++编程学习笔记,时间日期功能详解 第1张
(图片来源网络,侵删)

  这次来看看UE引擎使用C++来控制时间和日期相关的方法。

一、获取日期时间

  时间的获取基本上都是用FDateTime

阿赵UE引擎C++编程学习笔记——时间日期相关,阿赵UE引擎C++编程学习笔记,时间日期功能详解 第2张
(图片来源网络,侵删)

获取当前的:

FDateTime::Now()

显示日期时间举例:

FDateTime dt = FDateTime::Now();
UE_LOG(LogTemp, Display, TEXT("当前时间:%d年%d月%d日%d时%d分%d秒"), dt.GetYear(), dt.GetMonth(), dt.GetDay(), dt.GetHour(), dt.GetMinute(), dt.GetSecond());

二、获取时间戳

  时间戳是指从1970年1月1日凌晨开始算起到现在的秒数,或者毫秒数。

获取时间戳的方法有几种:

1、std::chrono

#include 
std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count();

  这个方法需要include ,但有个问题是会有时区问题,获取完之后还需要自己加上系统所在地的时区。

2、FDateTime时间相减

毫秒

(FDateTime::Now() - FDateTime(1970, 1, 1)).GetTotalMilliseconds();

(FDateTime::Now() - FDateTime(1970, 1, 1)).GetTotalSeconds();

这个方法暂时没发现没什么问题

3、ToUnixTimestamp

FDateTime::Now().ToUnixTimestamp();

这个方法只能获得秒级时间戳

三、时间戳转日期时间

从时间戳转FDateTime:

FDateTime dt = FDateTime::FromUnixTimestamp(int32 t);

注意这个方法接受的时间戳是秒级的。

四、计时器

自带的计时器方法使用SetTimer方法来实现

举例:

倒计时5秒:

GetWorldTimerManager().SetTimer(timerHandle, this, &OnTime, 5);

其中OnTime是回调函数,5是指5秒钟后执行

每2秒钟执行一次,首次执行延时5秒:

GetWorldTimerManager().SetTimer(timerHandle, this, &OnTime,2,true,5);

其中OnTime是回调函数,2是执行的频率,true是是否循环,5是首次执行时的延时

五、自定义时间管理类

  我一直喜欢自己定义时间管理的工具,所以写了这么一个工具类,里面包含了获取时间、时间戳、时间戳转时间、使用倒计时、Deadline、每隔多少频率执行等等方法,不是使用SetTimer来实现,而是自己控制Tick和当前时间的关系来做时间控制:

AzhaoTimeMgr.h

#pragma once
#include "CoreMinimal.h"
#include "TimeCtrlData.h"
#include "TimeEventType.h"
/**
 * 
 */
class UECPPTEST_API AzhaoTimeMgr 
{
public:
	//DECLARE_DELEGATE_OneParam(TimeCompleteHandler, int);
	//DECLARE_DELEGATE_TwoParams(TimeEveryHandler, int, int);
	static void Tick();	
	/// 
	/// 获取AzhaoTimeMgr单例
	/// 
	/// 
	static AzhaoTimeMgr* GetInstance();
	/// 
	/// 获取当前时间
	/// 
	/// 
	static FDateTime GetDateTime();
	/// 
	/// 通过秒级时间戳获得当前时间
	/// 
	/// 
	/// 
	static FDateTime GetDateTimeFromTimestamp(int64 t);
	/// 
	/// 通过毫秒级时间戳获得当前时间
	/// 
	/// 
	/// 
	static FDateTime GetDateTimeFromTimestampMs(int64 t);
	/// 
	/// 获取系统毫秒级时间戳
	/// 
	/// 
	static int64 GetSystemTime();
	/// 
	/// 获取游戏秒级时间戳
	/// 
	/// 
	static int64 GetNowTime();
	/// 
	/// 获取游戏毫秒级时间戳
	/// 
	/// 
	static int64 GetNowTimeMs();
	/// 
	/// 获取当前帧的事件,单位毫秒
	/// 
	/// 
	static int64 GetFrameTime();
	/// 
	/// 设置服务器时间戳
	/// 
	/// 服务器时间戳,单位毫秒
	static void SetServerTime(int64 t);
	/// 
	/// 设置秒级deadLine
	/// 
	/// 秒级deadLine
	/// 完成回调
	/// 每秒回调
	/// 
	static int64 SetDeadLine(int64 deadLine, void (*completeHandler)(int64), void (*everyHandler)(int64,int64) = nullptr);
	/// 
	/// 设置毫秒级deadLine
	/// 
	/// 毫秒级deadLine
	/// 完成回调
	/// 每秒回调
	/// 
	static int64 SetDeadLineMs(int64 deadLine, void (*completeHandler)(int64), void (*everyHandler)(int64,int64) = nullptr);
	/// 
	/// 设置秒级倒计时
	/// 
	/// 倒计时秒数
	/// 完成时回调
	/// 每秒钟回调
	/// 
	static int64 SetCountDown(int64 t, void (*completeHandler)(int64), void (*everyHandler)(int64,int64) = nullptr);
	/// 
	/// 设置毫秒级回调
	/// 
	/// 倒计时毫秒数
	/// 完成回调
	/// 每毫秒回调
	/// 
	static int64 SetCountDownMs(int64 t, void (*completeHandler)(int64), void (*everyHandler)(int64,int64) = nullptr);
	/// 
	/// 设置每秒执行
	/// 
	/// 每秒执行的回调
	/// 相隔多少秒执行一次
	/// 
	static int64 SetEverySecond(void (*everyHandler)(int64,int64), int32 t = 1);
	/// 
	/// 设置每毫秒执行
	/// 
	/// 每毫秒执行的回调
	/// 相隔多少毫秒执行一次
	/// 
	static int64 SetEveryMs(void (*everyHandler)(int64,int64), int32 t = 1);
	/// 
	/// 设置每分钟执行
	/// 
	/// 每分钟执行的回调
	/// 相隔多少分钟执行一次
	/// 
	static int64 SetEveryMinute(void (*everyHandler)(int64,int64), int32 t = 1);
	/// 
	/// 移除已添加的监听
	/// 
	/// 监听id
	static void RemoveId(int64 id);
	/// 
	/// 清除所有监听
	/// 
	static void ClearData();
private:
	AzhaoTimeMgr();
	~AzhaoTimeMgr();
	static AzhaoTimeMgr* _instance;
	int64 frameTime;
	TMap completeHandlers;
	TMap completeTimes;
	TMap everySecondHandlers;
	TMap everyMillisecondHandlers;
	TMap everyMinuteHandlers;
	TMap everyHandlerTimesMax;
	TMap everyHandlerTimes;
	TMap addList;
	int64 timeDifference = 0;
	int64 lastTime = 0;
	int64 lastMillisecond = 0;
	int64 lastMinute = 0;
	int64 timeId;
	bool isInit = false;
	bool isSetServerTime = false;
	int64 localFrameTime = 0;
	TSet delList;
	int64 updateId = -1;
	TSet checkCompleteRemoveList;
	int64 checkCompleteCt = -1;
private:
	void OnUpdate();
	void WriteServerTime(int64 t);
	int64 GetTimeId();
	void RemoveTime(int64 id);
	void Init();
	void Add2AddList(TimeCtrlData data);
	int64 AddCountDown(int64 sec, void (*completeHandler)(int64), void (*everyHandler)(int64,int64));
	int64 AddCountDownMs(int64 sec, void (*completeHandler)(int64), void (*everyHandler)(int64,int64));
	int64 AddDeadLine(int64 deadLine, void (*completeHandler)(int64), void (*everyHandler)(int64,int64));
	int64 AddSecond(void (*everyHandler)(int64,int64),int32 t);
	int64 AddMs(void (*everyHandler)(int64,int64), int32 t);
	int64 AddMinute(void (*everyHandler)(int64,int64), int32 t);
	void AddOneTimeEvent(TimeCtrlData data);
	void AddDeadLineFun(TimeCtrlData data);
	void AddCountDownFun(TimeCtrlData data);
	void AddCountDownMsFun(TimeCtrlData data);
	void AddSecond(TimeCtrlData data);
	void AddMsFun(TimeCtrlData data);
	void AddMinuteFun(TimeCtrlData data);
	void Remove(int64 id);
	void CheckComplete(int64 t);
	void CheckSecond(int64 t, int64 lt);
	void CheckMs(int64 t, int64 lt);
	void CheckMinute(int64 t, int64 lt);
	void CheckEvery(int64 tid, void(*handle)(int64, int64), int64 leftTime, int64 addtime);
	bool CheckInDelList(int64 id);
	void CheckAdd();
	void CheckDel();
	void CheckTime();
};
AzhaoTimeMgr* AzhaoTimeMgr::_instance = nullptr;

AzhaoTimeMgr.cpp

#include "Tools/TimeMgr/AzhaoTimeMgr.h"
AzhaoTimeMgr::AzhaoTimeMgr()
{
	frameTime = GetSystemTime();
}
AzhaoTimeMgr::~AzhaoTimeMgr()
{
}
#pragma region 静态方法
AzhaoTimeMgr* AzhaoTimeMgr::GetInstance()
{
	if (_instance == nullptr)
	{
		_instance = new AzhaoTimeMgr();
	}
	return _instance;
}
void AzhaoTimeMgr::Tick()
{
	AzhaoTimeMgr::GetInstance()->OnUpdate();
}
FDateTime AzhaoTimeMgr::GetDateTime()
{
	return FDateTime::Now();
}
int64 AzhaoTimeMgr::GetSystemTime()
{	
	return (FDateTime::Now() - FDateTime(1970, 1, 1)).GetTotalMilliseconds();
	//return FDateTime::Now().ToUnixTimestamp();
}
int64 AzhaoTimeMgr::GetNowTime()
{
	int64 t = GetSystemTime();
	t = (t + GetInstance()->timeDifference) / 1000;
	return t;
}
FDateTime AzhaoTimeMgr::GetDateTimeFromTimestamp(int64 t)
{
	return FDateTime::FromUnixTimestamp(t);
}
FDateTime AzhaoTimeMgr::GetDateTimeFromTimestampMs(int64 t)
{
	return FDateTime::FromUnixTimestamp(t/1000);
}
int64 AzhaoTimeMgr::GetNowTimeMs()
{
	int64 t = GetSystemTime();
	t = t + GetInstance()-> timeDifference;
	return t;
}
int64 AzhaoTimeMgr::GetFrameTime()
{
	return GetInstance()->frameTime;
}
void AzhaoTimeMgr::SetServerTime(int64 t)
{
	GetInstance()->WriteServerTime(t);
}
int64 AzhaoTimeMgr::SetDeadLine(int64 deadLine, void (*completeHandler)(int64), void (*everyHandler)(int64,int64))
{
	return GetInstance()->AddDeadLine(deadLine * 1000, completeHandler, everyHandler);
}
int64 AzhaoTimeMgr::SetDeadLineMs(int64 deadLine, void (*completeHandler)(int64), void (*everyHandler)(int64,int64))
{
	return GetInstance()->AddDeadLine(deadLine , completeHandler, everyHandler);
}
int64 AzhaoTimeMgr::SetCountDown(int64 t, void (*completeHandler)(int64), void (*everyHandler)(int64,int64))
{
	return GetInstance()->AddCountDown(t, completeHandler, everyHandler);
}
int64 AzhaoTimeMgr::SetCountDownMs(int64 t, void (*completeHandler)(int64), void (*everyHandler)(int64,int64))
{
	return GetInstance()->AddCountDownMs(t, completeHandler, everyHandler);
}
int64 AzhaoTimeMgr::SetEverySecond(void (*everyHandler)(int64,int64), int32 t)
{
	return GetInstance()->AddSecond(everyHandler, t);
}
int64 AzhaoTimeMgr::SetEveryMs(void (*everyHandler)(int64,int64), int32 t)
{
	return GetInstance()->AddMs(everyHandler, t);
}
int64 AzhaoTimeMgr::SetEveryMinute(void (*everyHandler)(int64,int64), int32 t)
{
	return GetInstance()->AddMinute(everyHandler, t);
}
void AzhaoTimeMgr::RemoveId(int64 id)
{
	GetInstance()->RemoveTime(id);
}
void AzhaoTimeMgr::ClearData()
{
	GetInstance()->Init();
}
#pragma endregion 静态方法
void AzhaoTimeMgr::OnUpdate()
{
	CheckAdd();
	CheckDel();
	CheckTime();
}
void AzhaoTimeMgr::WriteServerTime(int64 t)
{
	if (isSetServerTime != true)
	{
		lastTime = 0;
		lastMinute = 0;
		lastMillisecond = 0;
		isSetServerTime = true;
	}
	int64 now = AzhaoTimeMgr::GetSystemTime();
	timeDifference = t - now;
	frameTime = AzhaoTimeMgr::GetNowTimeMs();
}
int64 AzhaoTimeMgr::GetTimeId()
{
	timeId++;
	return timeId;
}
void AzhaoTimeMgr::RemoveTime(int64 id)
{
	delList.Add(id);
}
void AzhaoTimeMgr::Init()
{
	completeHandlers.Empty();
	completeTimes.Empty();
	everySecondHandlers.Empty();
	everyMillisecondHandlers.Empty();
	everyMinuteHandlers.Empty();
	everyHandlerTimesMax.Empty();
	everyHandlerTimes.Empty();
	delList.Empty();
	timeDifference = 0;
	lastTime = 0;
	lastMillisecond = 0;
	lastMinute = 0;
	timeId = 0;
	isSetServerTime = false;
	frameTime = AzhaoTimeMgr::GetNowTimeMs();
	localFrameTime = AzhaoTimeMgr::GetSystemTime();
	addList.Empty();
	delList.Empty();
	checkCompleteRemoveList.Empty();
	checkCompleteCt = -1;
}
void AzhaoTimeMgr::Add2AddList(TimeCtrlData data)
{
	addList.Add(data.id, data);
}
int64 AzhaoTimeMgr::AddCountDown(int64 sec, void (*completeHandler)(int64), void (*everyHandler)(int64,int64))
{
	if (completeHandler == nullptr)
	{
		return -1;
	}
	int64 tid = GetTimeId();
	int64 now = frameTime;
	int64 deadline = now + sec * 1000;
	TimeCtrlData data;
	data.id = tid;
	data.type = TimeEventType::countDown;
	data.deadLine = deadline;
	data.completeHandler = completeHandler;
	if (everyHandler != nullptr)
	{
		data.everyHandler = everyHandler;
	}
	Add2AddList(data);
	return tid;
}
int64 AzhaoTimeMgr::AddCountDownMs(int64 sec, void (*completeHandler)(int64), void (*everyHandler)(int64,int64))
{
	if (completeHandler == nullptr)
	{
		return -1;
	}
	int64 tid = GetTimeId();
	int64 now = frameTime;
	int64 deadline = now + sec;
	TimeCtrlData data;
	data.id = tid;
	data.type = TimeEventType::countDownMs;
	data.deadLine = deadline;
	data.completeHandler = completeHandler;
	if (everyHandler != nullptr)
	{
		data.everyHandler = everyHandler;
	}
	Add2AddList(data);
	return tid;
}
int64 AzhaoTimeMgr::AddSecond(void (*everyHandler)(int64,int64),int32 t)
{
	if (everyHandler == nullptr)
	{
		return -1;
	}
	int64 tid = GetTimeId();
	TimeCtrlData data;
	data.id = tid;
	data.type = TimeEventType::sec;
	data.everyHandler = everyHandler;
	data.t = t;
	Add2AddList(data);
	return tid;
}
int64 AzhaoTimeMgr::AddMs(void (*everyHandler)(int64,int64), int32 t)
{
	if (everyHandler == nullptr)
	{
		return -1;
	}
	int64 tid = GetTimeId();
	TimeCtrlData data;
	data.id = tid;
	data.type = TimeEventType::ms;
	data.everyHandler = everyHandler;
	data.t = t;
	Add2AddList(data);
	return tid;
}
int64 AzhaoTimeMgr::AddMinute(void (*everyHandler)(int64,int64), int32 t)
{
	if (everyHandler == nullptr)
	{
		return -1;
	}
	int64 tid = GetTimeId();
	TimeCtrlData data;
	data.id = tid;
	data.type = TimeEventType::minute;
	data.everyHandler = everyHandler;
	data.t = t;
	Add2AddList(data);
	return tid;
}
int64 AzhaoTimeMgr::AddDeadLine(int64 deadLine, void (*completeHandler)(int64), void (*everyHandler)(int64,int64) = nullptr)
{
	if (deadLine  0)
		{
			for (auto& item2 : checkCompleteRemoveList)
			{
				delList.Add(item2);
				//Remove(item2);
			}
		}
	}
}
void AzhaoTimeMgr::CheckSecond(int64 t, int64 lt)
{
	if (everySecondHandlers.Num() == 0)
	{
		return;
	}
	int64 passTime = lt - lastTime;
	if (passTime > 1000)
	{
		int64 leftTime = -1;
		for (auto& item : everySecondHandlers)
		{
			int64 key = item.Key;
			if (CheckInDelList(key) == true)
			{
				continue;
			}
			leftTime = 0;
			if (completeTimes.Contains(key) == true)
			{
				leftTime = (*completeTimes.Find(key)-t)/1000;
			}
			CheckEvery(item.Key, item.Value, leftTime, passTime / 1000);
		}
		lastTime = lt;
	}
}
void AzhaoTimeMgr::CheckMs(int64 t, int64 lt)
{
	if (everyMillisecondHandlers.Num() == 0)
	{
		return;
	}
	int64 PassTime = lt - lastMillisecond;
	if (PassTime > 0)
	{
		int64 leftTime = 0;
		for (auto& item : everyMillisecondHandlers)
		{
			int64 key = item.Key;
			if (CheckInDelList(key))
			{
				continue;
			}
			leftTime = 0;
			if (completeTimes.Contains(key))
			{
				leftTime = (*completeTimes.Find(key)) - t;
			}
			CheckEvery(item.Key, item.Value, leftTime, PassTime);
		}
		lastMillisecond = lt;
	}
}
void AzhaoTimeMgr::CheckMinute(int64 t, int64 lt)
{
	if (everyMinuteHandlers.Num() == 0)
	{
		return;
	}
	int64 passTime = lt - lastMinute;
	if (passTime >= 60000)
	{
		int64 leftTime = 0;
		for (auto& item : everyMinuteHandlers)
		{
			int64 key = item.Key;
			if (CheckInDelList(key))
			{
				continue;
			}
			leftTime = 0;
			if (completeTimes.Contains(key))
			{
				leftTime = (*completeTimes.Find(key) - t) / 60000;
			}
			CheckEvery(item.Key, item.Value, leftTime, passTime / 60000);
		}
		lastMinute = lt;
	}
}
void AzhaoTimeMgr::CheckEvery(int64 tid, void(*handle)(int64, int64), int64 leftTime, int64 addtime)
{
	int64 tInd = 0;
	if (everyHandlerTimes.Contains(tid))
	{
		tInd = *everyHandlerTimes.Find(tid);
	}
	int64 tMax = 1;
	if (everyHandlerTimesMax.Contains(tid))
	{
		tMax = *everyHandlerTimesMax.Find(tid);
	}		
	tInd = tInd + addtime;;
	if (tInd >= tMax)
	{
		if (everyHandlerTimes.Contains(tid))
		{
			everyHandlerTimes.Remove(tid);
		}
		handle(tid, leftTime);
	}
	else
	{
		everyHandlerTimes.Emplace(tid, tInd);
	}
	
}
bool AzhaoTimeMgr::CheckInDelList(int64 id)
{
	if (delList.Num() == 0)
	{
		return false;
	}
	if (delList.Contains(id))
	{
		return true;
	}
	else
	{
		return false;
	}
}
void AzhaoTimeMgr::CheckAdd()
{
	int32 num = addList.Num();
	if (num == 0)
	{
		return;
	}
	for (auto& item : addList)
	{
		AddOneTimeEvent(item.Value);
	}
	addList.Empty();
}
void AzhaoTimeMgr::CheckDel()
{
	if (delList.Num() == 0)
	{
		return;
	}
	for (auto& item : delList)
	{
		Remove(item);
	}
	delList.Empty();
}
void AzhaoTimeMgr::CheckTime()
{
	frameTime = AzhaoTimeMgr::GetNowTimeMs();
	localFrameTime = AzhaoTimeMgr::GetSystemTime();
	if (lastTime == 0)
	{
		lastTime = localFrameTime;
	}
	if (lastMillisecond == 0)
	{
		lastMillisecond = localFrameTime;
	}
	if (lastMinute == 0)
	{
		lastMinute = localFrameTime;
	}
	CheckComplete(frameTime);
	CheckSecond(frameTime, localFrameTime);
	CheckMs(frameTime, localFrameTime);
	CheckMinute(frameTime, localFrameTime);
}
TimeCtrlData.h
#pragma once
#include "CoreMinimal.h"
/**
 * 
 */
class UECPPTEST_API TimeCtrlData
{
public:
	TimeCtrlData();
	~TimeCtrlData();
	int32 type;
	int64 deadLine;
	void(*completeHandler)(int64) = nullptr;
	void (*everyHandler)(int64,int64) = nullptr;
	int64 id;
	int32 t;
};
TimeEventType.h
#pragma once
#include "CoreMinimal.h"
/**
 * 
 */
class UECPPTEST_API TimeEventType
{
public:
	TimeEventType();
	~TimeEventType();
	static const int32 deadLine = 0;
	static const int32 countDown = 1;
	static const int32 countDownMs = 2;
	static const int32 sec = 3;
	static const int32 ms = 4;
	static const int32 minute = 5;
};

0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码