是否有人为MSP430的IAR嵌入式工作台实现__getzone()? [英] Has anyone implemented __getzone() for IAR Embedded Workbench for MSP430?

查看:310
本文介绍了是否有人为MSP430的IAR嵌入式工作台实现__getzone()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在我的应用程序中处理一些时间转换。我想坚持使用尽可能多的标准库函数。现在,我正在使用time_t结构作为系统时基。但是,某些设备可以将时间同步到我的设备,该时间可能是UTC,也可能不是UTC。另外,我的设备会将时间同步到另一台设备,并且该时间将始终是UTC。

I am having to deal with some time conversions in my application. I would like to stick to using standard library functions as much as possible. Right now I am using a time_t structure as my system time base. However, some devices can sync time to my device, and that time may or may not be UTC. Also, my device will sync time to another device and that time WILL always be UTC.

无论如何,我可以问用户该时间所在的时区是同步到我的设备,以及他们是否使用DST。当我的设备获得时间同步时,我可以使用mktime直接生成我的时间戳(我的设备系统时间需要与它们为时间戳记而同步的时间相匹配,否则我必须不断进行转换),然后我可以如果我知道我的时间同步来自非UTC来源,请使用gmtime()获取UTC时间。问题是默认情况下localtime()和gmtime()将返回相同的值,因为默认情况下库将认为它是直接的UTC时间,并且没有DST或时区偏移。

Anyway, I can ask the user what the time zone is of the time that is being synced to my device and whether or not they use DST. When my device gets a time sync I can use mktime to directly generate my time stamp (my device system time needs to match the time they are syncing for time stamping purposes, otherwise I have to constantly do conversions), and then from that I can use gmtime() to get the UTC time if I know my time sync came from a non-UTC source. The trouble is by default localtime() and gmtime() are going to return the same value because the library is going to by default think it is in straight UTC time and there are not DST or timezone offsets.

因此,我认为处理此问题的方法是实现并覆盖__getzone函数库。

So, I think the way to deal with this is to implement and overwrite the library __getzone function.

来自EW430_CompilerReference.pdf的第106页

From page 106 of EW430_CompilerReference.pdf


要使__time32,__ time64和date函数正常工作,必须实现
函数clock,__time32,__ time64和__getzone。是否使用__time32
或__time64取决于您用于time_t的接口,请参见time.h,第304页。

To make the __time32, __time64, and date functions work, you must implement the functions clock, __time32, __time64, and __getzone. Whether you use __time32 or __time64 depends on which interface you use for time_t, see time.h, page 304.

...

默认的__getzone实现将UTC(世界标准
时间)指定为时区。

The default implementation of __getzone specifies UTC (Coordinated Universal Time) as the time zone.

问题1:我的推理是否正确,执行我想要的最佳方法是实现此__getzone函数?

Q1: Am I on the right track in my reasoning, that the best way to do what I want is to implement this __getzone function?

我的原因之所以感到沮丧,是因为__getzone返回的值是带有以下格式的奇数字符串:

The reason I am balking is because the value returned by __getzone is an oddball string w/ formatting like this:


:[XXX [:YYY [:NNN [:DST [:DST ...]]]]]]

:[XXX[:YYY[:NNN[:DST[:DST ...]]]]]

其中XXX是标准时区名称(例如,GMT-5用于EST),YYY是夏令时时区名称(例如EST的GMT-4),NNN是相对于UTC的数字偏移量,格式为HHMM(可能带有-符号)。然后DST为夏令时指定一串选项具有节省时间格式的节省时间规则。

Where XXX is the standard timezone name (e.g. GMT-5 for EST), YYY is the daylight savings timezone name (e.g. GMT-4 for EST), NNN is a numeric offset from UTC in the form HHMM (and could have a - symbol)., and then DST specifies a string of options for daylight savings time rules that has its own irritating formatting.

无论如何,现在对我来说这应该很简单,因为我只担心加拿大和美国的DST规则相同。

Anyway, this should be pretty straight forward for me right now because I am only worried about Canada and the US who have the same DST rules.

Q2:有人有没有形成该字符串的示例代码,所以我可以检查一下我的理解?

Q2: Does anyone have any sample code for forming that string so I can check my understanding of this?

推荐答案

这是我的__getzone()的实现。所以现在我的系统时基将是UTC。当用户配置我的系统时,如果时间源未提供UTC,我会询问他们当地时间。然后,当他们向我的系统提供时间同步时,他们提供的时间将通过调用MKTIME转换为UTC(这将考虑DST规则)。然后,当时间返回给用户时,将通过调用localtime()来完成。

Here is my implementation of __getzone(). So now my system time base will be UTC. When the user configures my system I ask them what their local time if the time source is NOT providing UTC. Then when they supply a time sync to my system, the time they supply will get converted to UTC by a call to MKTIME (which will take into account DST rules). Then when the time is rendered back to the user it will be done through a call to localtime().

在实现此过程的过程中,我们了解到的另一件事是IAR MKTIME()的实现将调用__getzone(),但是除非将tm_isdst设置为 -1,否则不会考虑DST规则。 -1使对MKTIME()的调用可以确定是否基于规则应用DST。

Another thing we learned in the process of implementing this is that IAR's implementation of MKTIME() will call __getzone(), but the DST rules will not be considered unless you set tm_isdst to '-1'. -1 makes the call to MKTIME() figure out whether to apply DST based on the rule.

/*!
* \brief Overrides default library function __getzone to support different time
* zones and DST rules.
* \returns Pointer to a const string containing the timezone + dst rules
*
* This function supports all time zones and DST rules for the U.S. and Canada.
*
* \par IAR Notes
* The return value should be a string on the following form:
* \code
* :[XXX[:YYY[:NNN[:DST[:DST ...]]]]]
* \endcode
* \par
* Where \b XXX is the standard time-zone name, \b YYY is the daylight
* savings time-zone name, \b NNN is the time zone offset, and the DSTs
* are the daylight savings time rules. Daylight savings time will add
* one hour to the normal time.
* \par
* The time zone offset \b NNN is specified as a number relative to UTC,
* possibly negative (east is positive), on the format HHMM, where HH
* is hours and MM is minutes.
* \par
* The DSTs specifes a set of rules for how daylight savings time is
* applied. The rules must be sorted in increasing date order starting
* from the earliest date. The first rule for a specific year will
* enable DST, the next will disable it, and so on. Each rule is on
* the following form:
* \code
*   [(YYYY)]MMDD[HH][-W|+W]
* \endcode
*
* * \b (YYYY) is the first year the daylight savings rule was applied.
*      It is optional. If not specified it will default to the same
*      year as the previous rule or zero if no previous rule.
* * \b MM is the month number (1-12).
* * \b DD is the day of the month (1-31).
* * \b HH is the hour number in a 24-hour day (optional, defaults to 0).
* * \b +/-W specifies the day of the week the rule takes effect (where
*      Sunday = 0, Monday = 1, etc). +W means that the rule applies
*      to the first such day on or after the specified date and -W
*      strictly before the date. If this is not specified, the rule
*      will take effect on the exact date, regardless of the day of
*      the week.
*
* \par Example
* U.S. Eastern Standard time is UTC -5. Eastern Daylight time is UTC -4.
* Daylight time goes into affect on the second sunday of March at 2:00AM local
* time. Daylight time ends on the first sunday of November at 2:00AM local
* time. The law that defines this went into affect in 2007.
* Therefore here is how the DST string is constructed:
* | \| | STD Time | \| | DST Time | \| | UTC Offset | \| | DST Rule Year | Month DST Starts | Day DST Starts | Hour DST Starts | Day of Week | \| | Month DST Ends | Day DST Ends | Hour DST Ends | Day of Week |
* |----|----------|----|----------|----|------------|----|---------------|------------------|----------------|-----------------|-------------|----|----------------|--------------|---------------|-------------|
* | :  |  XXX     | :  | YYY      | :  | NNN        | :  | (YYYY)        | MM               | DD*            | HH              | +/-W**      | :  | MM             | DD           | HH            | +/-W        |
* | :  |  GMT-5   | :  | GMT-4    | :  | -0500      | :  | (2007)        | 03               | 08             | 02              | +0          | :  | 11             | 01           | 02            | +0          |
* - * An 8 for the day means that DST will start around the 8th day of the
*   month. Or that the +/-W parameter is relative to the 8th day of the month.
* - ** A + here means that the DST rule will start \b on or \b after the
*   previously specified day (the 8th). 0 means that it should happen on a
*   sunday. Therefore if the 8th is a sunday (and the 8th cannot be the first
*   sunday of the month) then the rule will take affect on that day - or it
*   will happen on the very next sunday.
* \par
* Result:
* \code
* :GMT-5:GMT-4:-0500:(2007)030802+0:110102+0
* \endcode
*
* \sa
* - time_zones - Supported time zones
*/
const char8_t * __getzone(void)
{
    const char8_t *current_zone = NULL;
    static const char8_t dst_time_zones[][50] =
    {
        // UTC time
        ":GMT+0:GMT+0:0000:0",
        // Newfoundland Standard Time UTC – 3:30
        ":GMT-3:GMT-2:-0330:(2007)030802+0:110102+0",
        // Atlantic Standard Time, UTC – 4
        ":GMT-4:GMT-3:-0400:(2007)030802+0:110102+0",
        // Eastern Standard Time, UTC – 5
        ":GMT-5:GMT-4:-0500:(2007)030802+0:110102+0",
        // Central Standard Time, UTC – 6
        ":GMT-6:GMT-5:-0600:(2007)030802+0:110102+0",
        // Mountain Standard Time, UTC – 7
        ":GMT-7:GMT-6:-0700:(2007)030802+0:110102+0",
        // Pacific Standard Time, UTC – 8
        ":GMT-8:GMT-7:-0800:(2007)030802+0:110102+0",
        // Alaska Standard Time, UTC – 9
        ":GMT-9:GMT-8:-0900:(2007)030802+0:110102+0",
        // Hawaii-Aleutian Standard Time, UTC – 10
        ":GMT-10:GMT-9:-1000:(2007)030802+0:110102+0"
    };

    static const char8_t std_time_zones[][20] =
    {
        // UTC time
        ":GMT+0:GMT+0:0000",
        // Newfoundland Standard Time UTC – 3:30
        ":GMT-3:GMT-2:-0330",
        // Atlantic Standard Time, UTC – 4
        ":GMT-4:GMT-3:-0400",
        // Eastern Standard Time, UTC – 5
        ":GMT-5:GMT-4:-0500",
        // Central Standard Time, UTC – 6
        ":GMT-6:GMT-5:-0600",
        // Mountain Standard Time, UTC – 7
        ":GMT-7:GMT-6:-0700",
        // Pacific Standard Time, UTC – 8
        ":GMT-8:GMT-7:-0800",
        // Alaska Standard Time, UTC – 9
        ":GMT-9:GMT-8:-0900",
        // Hawaii-Aleutian Standard Time, UTC – 10
        ":GMT-10:GMT-9:-1000"
    };

    switch(get_config()->time_zone)
    {
        case NST:
        {
            if(get_config()->b_dst)
            {
                current_zone = dst_time_zones[NST];
            }
            else
            {
                current_zone = std_time_zones[NST];
            }
        }
        break;

        case AST:
        {
            if(get_config()->b_dst)
            {
                current_zone = dst_time_zones[AST];
            }
            else
            {
                current_zone = std_time_zones[AST];
            }
        }
        break;

        case EST:
        {
            if(get_config()->b_dst)
            {
                current_zone = dst_time_zones[EST];
            }
            else
            {
                current_zone = std_time_zones[EST];
            }
        }
        break;

        case CST:
        {
            if(get_config()->b_dst)
            {
                current_zone = dst_time_zones[CST];
            }
            else
            {
                current_zone = std_time_zones[CST];
            }
        }
        break;

        case MST:
        {
            if(get_config()->b_dst)
            {
                current_zone = dst_time_zones[MST];
            }
            else
            {
                current_zone = std_time_zones[MST];
            }
        }
        break;

        case PST:
        {
            if(get_config()->b_dst)
            {
                current_zone = dst_time_zones[PST];
            }
            else
            {
                current_zone = std_time_zones[PST];
            }
        }
        break;

        case AKST:
        {
            if(get_config()->b_dst)
            {
                current_zone = dst_time_zones[AKST];
            }
            else
            {
                current_zone = std_time_zones[AKST];
            }
        }
        break;

        case HAST:
        {
            if(get_config()->b_dst)
            {
                current_zone = dst_time_zones[HAST];
            }
            else
            {
                current_zone = std_time_zones[HAST];
            }
        }
        break;

        case UTC:
        default:
            current_zone = std_time_zones[UTC];
        break;
    }

    return current_zone;
}

这篇关于是否有人为MSP430的IAR嵌入式工作台实现__getzone()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆