DateTranslator源码解析

class DateTranslator
{
    public:

        // this updates the DateBuffer to be the current date / time.
        // If you wish to set the DateBuffer to a particular date, pass in that date.
        // Dates should be in the OS.h compliant format
        static void UpdateDateBuffer(DateBuffer* inDateBuffer, const SInt64& inDate, time_t gmtoffset = 0);

        //Given an HTTP/1.1 compliant date string (in one of the three 1.1 formats)
        //this returns an OS.h compliant date/time value.
        static SInt64   ParseDate(StrPtrLen* inDateString);

    private:

        static UInt32 ConvertCharToMonthTableIndex(int inChar)
        {
            return (UInt32)(toupper(inChar) - 'A'); // Convert to a value between 0 - 25
        }
};

void DateTranslator::UpdateDateBuffer(DateBuffer* inDateBuffer, const SInt64& inDate, time_t gmtoffset)
{
    if (inDateBuffer == NULL)
        return;

    struct tm* gmt = NULL;
    struct tm  timeResult;

    if (inDate == 0)
    {
        time_t calendarTime = ::time(NULL) + gmtoffset;
        gmt = ::qtss_gmtime(&calendarTime, &timeResult);
    }
    else
    {
        time_t convertedTime = (time_t)(inDate / (SInt64)1000) + gmtoffset ; // Convert from msec to sec
        gmt = ::qtss_gmtime(&convertedTime, &timeResult);
    }

    Assert(gmt != NULL); //is it safe to assert this?
    size_t size  = 0;
    if (0 == gmtoffset)
        size = qtss_strftime(   inDateBuffer->fDateBuffer, sizeof(inDateBuffer->fDateBuffer),
                            "%a, %d %b %Y %H:%M:%S GMT", gmt);

    Assert(size == DateBuffer::kDateBufferLen);
}

this updates the DateBuffer to be the current date / time.
If you wish to set the DateBuffer to a particular date, pass in that date.
Dates should be in the OS.h compliant format.
inData为msecs的形式,OS.h中定义了兼容的格式。time_t(NULL)返回从1970.01.01 01:00:00开始到当前UTC时间的秒数(UTC时间标准)。

File: time.h
struct tm {
        int tm_sec;     /* seconds after the minute - [0,59] */
        int tm_min;     /* minutes after the hour - [0,59] */
        int tm_hour;    /* hours since midnight - [0,23] */
        int tm_mday;    /* day of the month - [1,31] */
        int tm_mon;     /* months since January - [0,11] */
        int tm_year;    /* years since 1900 */
        int tm_wday;    /* days since Sunday - [0,6] */
        int tm_yday;    /* days since January 1 - [0,365] */
        int tm_isdst;   /* daylight savings time flag */
        };

struct tm *qtss_gmtime(const time_t *timep, struct tm *result)
{
    OSMutexLocker locker(OS::GetStdLibMutex());
    struct tm *time_result = ::gmtime(timep);
    *result = *time_result;

    return result;
}
File: time.inl
_CRT_INSECURE_DEPRECATE(gmtime_s) static __inline struct tm * __CRTDECL gmtime(const time_t * _Time)
{
#pragma warning( push )
#pragma warning( disable : 4996 )
    return _gmtime64(_Time); // time.h中的函数
#pragma warning( pop )
}

主要是将time_t类型的_Time的时间转换为UTC时间标准的格式(wiki:https://en.wikipedia.org/wiki/Coordinated_Universal_Time),即GMT时间,返回类型为struct tm,会填充里面的年月日时分秒等等,具体UTC和GMT有何不同可以看上面维基链接。(UTC为时间标准,而GMT为时区,一般来说被视为等同的)
这里写图片描述
#define qtss_strftime strftime
strftime => http://www.cplusplus.com/reference/ctime/strftime/?kw=strftime
这里写图片描述
获取并显示当前时间的GMT表示形式

SInt64  DateTranslator::ParseDate(StrPtrLen* inDateString)
{
    //SEE RFC 1123 for details on the date string format
    //ex: Mon, 04 Nov 1996 21:42:17 GMT

    // Parse the date buffer, filling out a tm struct
    struct tm theDateStruct;
    ::memset(&theDateStruct, 0, sizeof(theDateStruct));

    // All RFC 1123 dates are the same length.
    if (inDateString->Len != DateBuffer::kDateBufferLen)
        return 0;

    StringParser theDateParser(inDateString);

    // the day of the week is redundant... we can skip it!
    theDateParser.ConsumeLength(NULL, 5);

    // We are at the date now.
    theDateStruct.tm_mday = theDateParser.ConsumeInteger(NULL);
    theDateParser.ConsumeWhitespace();

    // We are at the month now. Use our hand-crafted perfect hash table
    // to get the right value to place in the tm struct
    if (theDateParser.GetDataRemaining() < 4)
        return 0;

    UInt32 theIndex =   ConvertCharToMonthTableIndex(theDateParser.GetCurrentPosition()[0]) +
                        ConvertCharToMonthTableIndex(theDateParser.GetCurrentPosition()[1]) +
                        ConvertCharToMonthTableIndex(theDateParser.GetCurrentPosition()[2]);

    if (theIndex > kMonthHashTableSize)
        return 0;

    theDateStruct.tm_mon = kMonthHashTable[theIndex];

    // If the month is illegal, return an error
    if (theDateStruct.tm_mon >= 12)
        return 0;

    // Skip over the date
    theDateParser.ConsumeLength(NULL, 4);   

    // Grab the year (years since 1900 is what the tm struct wants)
    theDateStruct.tm_year = theDateParser.ConsumeInteger(NULL) - 1900;
    theDateParser.ConsumeWhitespace();

    // Now just grab hour, minute, second
    theDateStruct.tm_hour = theDateParser.ConsumeInteger(NULL);
    theDateStruct.tm_hour += OS::GetGMTOffset();

    theDateParser.ConsumeLength(NULL, 1); //skip over ':'   

    theDateStruct.tm_min = theDateParser.ConsumeInteger(NULL);
    theDateParser.ConsumeLength(NULL, 1); //skip over ':'   

    theDateStruct.tm_sec = theDateParser.ConsumeInteger(NULL);

    // Ok, we've filled out the tm struct completely, now convert it to a time_t
    time_t theTime = ::mktime(&theDateStruct);
    return (SInt64)theTime * 1000; // convert to a time value in our timebase.
}

主要是将GMT格式(等同于UTC格式)的时间字符串解析转换为struct tm类型,再将struct tm类型的数据转换为Local time(本地区时间),最后将struct tm类型的GMT数据转换为secs(从1970年1月1日1点开始)秒数(SInt64)返回。

比较有趣的是在解析GMT格式字串的月份时,采用的是哈希表的方式来获取月份的数值(tm.tm_mon 0~11 => Jan~Dec).
这里写图片描述
可以简单算一下:Jan => ‘J’ - ‘A’ == 9, ‘A’ - ‘A’ == 0, ‘N’ - ‘A’ == 13 => 9 + 0 + 13 = 22 => theIndex = 22 => kMonthHashTable[22] == 0 => 即为tm_mon中的0,一月的表示
需要注意的是:tm.tm_year是从1900开始的。
将struct tm类型的数据转换为Local time(本地区时间)需要通过调用函数OS::GetGMTOffset()来获取Local time 与 UTC时间的差值;
这里写图片描述
可以看到,这里用到了::GetTimeZoneInformation(&tzInfo)函数 => https://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx
我们主要说明Bias结构,Bias表示的是分钟,即当地时间与UTC时间相差的分钟的差值 => bias = UTC - local time
这里写图片描述
而根据已上公式(UTC = local time + bias)可以很容易计算出本地时间:local time = UTC - bias,因此这就是为什么要乘以-1的原因了。

File: time.inl
static __inline time_t __CRTDECL mktime(struct tm * _Tm)
{
    return _mktime64(_Tm);
}

将struct tm类型的变量转换为time_t的时间格式(只含秒数)。


刚刚开始接触DSS,希望能共同提高,如果有分析不到位的地方,希望批评指正。:)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
未来社区的建设背景和需求分析指出,随着智能经济、大数据、人工智能、物联网、区块链、云计算等技术的发展,社区服务正朝着数字化、智能化转型。社区服务渠道由分散向统一融合转变,服务内容由通用庞杂向个性化、服务导向转变。未来社区将构建数字化生态,实现数据在线、组织在线、服务在线、产品智能和决策智能,赋能企业创新,同时注重人才培养和科研平台建设。 规划设计方面,未来社区将基于居民需求,打造以服务为中心的社区管理模式。通过统一的服务平台和应用,实现服务内容的整合和优化,提供灵活多样的服务方式,如推送式、订阅式、热点式等。社区将构建数据与应用的良性循环,提高服务效率,同时注重生态优美、绿色低碳、社会和谐,以实现幸福民生和产业发展。 建设运营上,未来社区强调科学规划、以人为本,创新引领、重点突破,统筹推进、整体提升。通过实施院落+社团自治工程,转变政府职能,深化社区自治法制化、信息化,解决社区治理中的重点问题。目标是培养有活力的社会组织,提高社区居民参与度和满意度,实现社区治理服务的制度机制创新。 未来社区的数字化解决方案包括信息发布系统、服务系统和管理系统。信息发布系统涵盖公共服务类和社会化服务类信息,提供政策宣传、家政服务、健康医疗咨询等功能。服务系统功能需求包括办事指南、公共服务、社区工作参与互动等,旨在提高社区服务能力。管理系统功能需求则涉及院落管理、社团管理、社工队伍管理等,以实现社区治理的现代化。 最后,未来社区建设注重整合政府、社会组织、企业等多方资源,以提高社区服务的效率和质量。通过建立社区管理服务综合信息平台,提供社区公共服务、社区社会组织管理服务和社区便民服务,实现管理精简、高效、透明,服务快速、便捷。同时,通过培育和发展社区协会、社团等组织,激发社会化组织活力,为居民提供综合性的咨询和服务,促进社区的和谐发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值