小工具知识网

当前位置: 首页 > 行业知识 > 阿赵UE引擎C++编程学习笔记——时间日期相关

行业知识

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

2026-10-26 05:35:00 来源:互联网转载

  大家好,我是阿赵。

()

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

一、获取日期时间

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

()

获取当前的:

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);/// /// 移除已添加的监听/// /// 监听idstatic 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;};

上一篇:揭秘紫云烟价格,揭秘真相,一包究竟多少钱?

下一篇:WordPress源码深度探索,揭示强大功能与实现机制的奥秘