自定义游戏服务端时间 C++ 11实现
原理: 系统已运行时间是不断增长的, 用户修改系统自带的时钟, 这个值不会变. 利用这个固定值加上自定义的时间长度, 计算出当前时间.
C++ 98, windows使用 GetTickCount64()取固定时间, linux使用clock_gettime(CLOCK_MONOTONIC, &tp)取固定时间
java 可以使用函数获取虚拟机已运行时间来取个固定值.
下面这个类可以优化, 使用namespace, 不使用类, 然后时间用全局变量, 不用类成员变量. 这样用namespace::mytime 这样格式可能方便些
SetUserTime(1692844734) 可以设置个自定义时间.
也可以SetUserTime(from_string("2020-10-05 12:33:55")),
SetUserTime(0)还原成当前系统时间.
RefreshLastTime()在游戏每帧定时器里面可以调用, 定时器可以参考 定时器
TimeSystem.h
#pragma once #include <stdint.h> class TimeSystem { public: TimeSystem(); // 上一帧刷新时间增量 毫秒 int64_t DeltaTime; //当前时间戳(毫秒) int64_t NowServerMilliseconds(); //当前时间戳(秒) int64_t NowServerSeconds(); //系统当前时间戳(毫秒) int64_t SysNowServerMilliseconds(); //系统当前时间戳(秒) int64_t SysNowServerSeconds(); //当前一天的0分0秒时间戳(秒) int32_t DayZero(); // 刷新更新时间 void RefreshLastTime(); //自定义当前时间 void SetUserTime(int32_t now); private: // 操作系统已运行时间(毫秒) int64_t OperatingSystemRunTime(); private: // 上次更新时间 int64_t m_last_time; //用户增加的毫秒数 int64_t m_user_add_time; friend class GameSystem; };
TimeSystem.cpp
#include "TimeSystem.h" #include <chrono> TimeSystem::TimeSystem() { //操作系统已运行时间(毫秒) m_last_time = OperatingSystemRunTime(); //用户增加的毫秒数 m_user_add_time = SysNowServerMilliseconds() - OperatingSystemRunTime(); DeltaTime = 0; } int64_t TimeSystem::NowServerMilliseconds() { //当前时间 = 用户时间 + 操作系统运行的时间 return m_user_add_time + OperatingSystemRunTime(); } int64_t TimeSystem::NowServerSeconds() { return NowServerMilliseconds() / 1000; } int64_t TimeSystem::SysNowServerMilliseconds() { return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); } int64_t TimeSystem::SysNowServerSeconds() { return SysNowServerMilliseconds() / 1000; } int32_t TimeSystem::DayZero() { time_t now_second = NowServerSeconds(); //24*3600=86400 int32_t sec = now_second % 86400; return now_second - sec; } // 刷新更新时间 void TimeSystem::RefreshLastTime() { int64_t now_time = OperatingSystemRunTime(); DeltaTime = now_time - m_last_time; if (DeltaTime < 0) { //时间回调, DeltaTime可能为负了 DeltaTime = 0; } m_last_time = now_time; } //操作系统已运行时间(修改电脑时钟不会影响操作系统已运行时间) int64_t TimeSystem::OperatingSystemRunTime() { return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count(); } //设置自定义时间 void TimeSystem::SetUserTime(int32_t now) { if (now == 0) { //还原使用系统时间 m_user_add_time = SysNowServerMilliseconds() - OperatingSystemRunTime(); } else { m_user_add_time = now; m_user_add_time *= 1000; int64_t relative = OperatingSystemRunTime(); m_user_add_time -= relative; } }
辅助函数两个:
#include <time.h> #include <stdio.h> #define TIME_LENGTH 32 std::string to_string() { char szTime[TIME_LENGTH] = { 0 }; strftime(szTime, TIME_LENGTH, "%Y-%m-%d %H:%M:%S", &m_time); return szTime; } time_t from_string(const std::string& time_str) { tm tm_; int year, month, day, hour, minute, second; sscanf(time_str.c_str(), "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second); tm_.tm_year = year - 1900; tm_.tm_mon = month - 1; tm_.tm_mday = day; tm_.tm_hour = hour; tm_.tm_min = minute; tm_.tm_sec = second; tm_.tm_isdst = 0; time_t t_ = mktime(&tm_); return t_; }