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

(图片来源网络,侵删)
这次来看看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); /// /// 移除已添加的监听 /// /// 监听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; };
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。
还没有评论,来说两句吧...