是否有人为MSP430的IAR Embedded Workbench实现了_getzone()?
我必须在我的申请中处理一些时间转换。我希望尽可能多地使用标准库函数。现在,我使用时间结构作为我的系统时基。但是,某些设备可以将时间同步到我的设备,并且该时间可能是UTC,也可能不是UTC。此外,我的设备将时间同步到另一个设备,该时间将始终为UTC 无论如何,我可以询问用户同步到我的设备的时间的时区,以及他们是否使用DST。当我的设备获得时间同步时,我可以使用mktime直接生成我的时间戳(我的设备系统时间需要与它们同步的时间相匹配,以便进行时间戳,否则我必须不断进行转换),然后,如果我知道我的时间同步来自非UTC来源,我可以使用gmtime()获取UTC时间。问题是,默认情况下localtime()和gmtime()将返回相同的值,因为库在默认情况下会认为它是在UTC时间,并且没有DST或时区偏移 因此,我认为解决这个问题的方法是实现并覆盖library\uu getzone函数 摘自EW430_CompilerReference.pdf第106页 要使_time32、_time64和date函数工作,必须实现 函数clock、_time32、_time64和_getzone。是否使用_utime32 或者uu time64取决于时间使用的接口,请参阅time.h,第304页 _uugetzone的默认实现指定UTC(协调通用) 时间)作为时区 问题1:我的推理是否正确,实现这个_ugetzone函数是我想要的最好方法 我之所以犹豫不决,是因为_getzone返回的值是一个奇怪的字符串,格式如下: :[XXX[:YYY[:NNN[:DST[:DST…][]]] 其中XXX是标准时区名称(例如,美国东部标准时间为GMT-5),YYY是夏令时时区名称(例如,美国东部标准时间为GMT-4),NNN是UTC的数字偏移量,格式为HHMM(可以有一个-符号),然后DST为夏令时规则指定一系列选项,这些选项具有自己令人不快的格式 无论如何,这对我来说应该是非常直接的,因为我只担心加拿大和美国有相同的DST规则是否有人为MSP430的IAR Embedded Workbench实现了_getzone()?,c,c99,msp430,iar,ctime,C,C99,Msp430,Iar,Ctime,我必须在我的申请中处理一些时间转换。我希望尽可能多地使用标准库函数。现在,我使用时间结构作为我的系统时基。但是,某些设备可以将时间同步到我的设备,并且该时间可能是UTC,也可能不是UTC。此外,我的设备将时间同步到另一个设备,该时间将始终为UTC 无论如何,我可以询问用户同步到我的设备的时间的时区,以及他们是否使用DST。当我的设备获得时间同步时,我可以使用mktime直接生成我的时间戳(我的设备系统时间需要与它们同步的时间相匹配,以便进行时间戳,否则我必须不断进行转换),然后,如果我知道我的时
问题2:是否有人有任何用于生成该字符串的示例代码,以便我检查我对该字符串的理解?这是我对u getzone()的实现。现在我的系统时基是UTC。当用户配置我的系统时,如果时间源不提供UTC,我会询问他们的本地时间。然后,当他们向我的系统提供时间同步时,他们提供的时间将通过调用MKTIME转换为UTC(这将考虑DST规则)。然后,当时间被呈现回用户时,它将通过调用localtime()来完成
char const * __getzone()
{
return ":GMT+2:GMT+3:0200:(1996)033103-0:103104-0";
// Ukraine; rule: (last Sun (March | October) )
}
在实现过程中我们了解到的另一件事是,IAR对MKTIME()的实现将调用u getzone(),但除非将tm_isdst设置为“-1”,否则不会考虑DST规则-1调用MKTIME()确定是否根据规则应用DST
/*!
* \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;
}
上面的乌克兰规则不太正确,因为它不适用于31日的周日。如果您阅读了getzone中的规则,那么c-W表示该日期之前的星期天 正确的规则如下
char const * __getzone()
{
return ":GMT+2:GMT+3:0200:(1996)032503+0:102504+0";
// Ukraine; rule: (last Sun (March | October) )
}
对于德国,您可以使用:
char const * __getzone() {
return ":GMT+1:GMT+2:0100:032502+0:102502+0";
}
要么是乌克兰的错误,要么是我的错误,但我用一个实际的设备测试了我的,得到了正确的结果。以下是我的测试:
//Forward
time_t ts = 1490489997L;//26.03.2017-01:59:57 3 seconds before dst
struct tm* pre = localtime(&ts);
time_t after = ts + 5L;//wait 5 seconds -> 26.03.2017-03:00:02
struct tm* post = localtime(&after);
//Backward
time_t ts = 1509238797L;//29.10.2017-02:59:57 3 seconds before dst
struct tm* pre = localtime(&ts);
time_t after = ts + 5L;//wait 5 seconds -> 29.10.2017-02:00:02
struct tm* post = localtime(&after);
致意
Michael我认为这是有道理的,但让我确保我理解:对于一个月中的某一天,你有'31'和-0。因此,这是上一个星期天最接近一个月的最后一天。感谢您回来并展示您所做的一切+1Np-如果您有任何问题,请告诉我!
//Forward
time_t ts = 1490489997L;//26.03.2017-01:59:57 3 seconds before dst
struct tm* pre = localtime(&ts);
time_t after = ts + 5L;//wait 5 seconds -> 26.03.2017-03:00:02
struct tm* post = localtime(&after);
//Backward
time_t ts = 1509238797L;//29.10.2017-02:59:57 3 seconds before dst
struct tm* pre = localtime(&ts);
time_t after = ts + 5L;//wait 5 seconds -> 29.10.2017-02:00:02
struct tm* post = localtime(&after);