diff --git a/Source/CFTimeZone.c b/Source/CFTimeZone.c index da8a104..460bb8c 100644 --- a/Source/CFTimeZone.c +++ b/Source/CFTimeZone.c @@ -306,11 +306,29 @@ CFTimeZoneCreateWithTimeIntervalFromGMT (CFAllocatorRef alloc, tzfile.header.tzh_timecnt[3] = 1; tzfile.header.tzh_typecnt[3] = 1; tzfile.ttinfo.offset = CFSwapInt32HostToBig((SInt32)ti); - numChars = snprintf (tzfile.abbrev, 10, "GMT%c%02d:%02d", sign, hour, min); - tzfile.header.tzh_charcnt[3] = numChars; - - name = CFStringCreateWithCString (alloc, tzfile.abbrev, - kCFStringEncodingASCII); + /* The abbreviation is compact (GMT+5, GMT+5:30) while the name is padded + to four digits (GMT+0500). A zero offset is just GMT. */ + { + char nameBuf[16]; + + if ((SInt32) ti == 0) + { + numChars = snprintf (tzfile.abbrev, 10, "GMT"); + snprintf (nameBuf, sizeof (nameBuf), "GMT"); + } + else + { + if (min == 0) + numChars = snprintf (tzfile.abbrev, 10, "GMT%c%d", sign, hour); + else + numChars = snprintf (tzfile.abbrev, 10, "GMT%c%d:%02d", + sign, hour, min); + snprintf (nameBuf, sizeof (nameBuf), "GMT%c%02d%02d", sign, hour, min); + } + tzfile.header.tzh_charcnt[3] = numChars; + + name = CFStringCreateWithCString (alloc, nameBuf, kCFStringEncodingASCII); + } data = CFDataCreateWithBytesNoCopy (alloc, (UInt8*)&tzfile, sizeof(struct TZFile) - (10 - numChars), kCFAllocatorNull); new = CFTimeZoneCreate (alloc, name, data); diff --git a/Tests/CFTimeZone/basic.m b/Tests/CFTimeZone/basic.m index 2e2c16f..9be9547 100644 --- a/Tests/CFTimeZone/basic.m +++ b/Tests/CFTimeZone/basic.m @@ -9,21 +9,16 @@ int main (void) { CFTimeZoneRef tz; CFStringRef str; - CFStringRef expected; CFTimeInterval ti; CFAbsoluteTime at; tz = CFTimeZoneCreateWithTimeIntervalFromGMT (NULL, 0.0); PASS_CF(tz != NULL, "CFTimeZone create successfully."); -#ifdef __APPLE__ - expected = CFSTR("GMT"); -#else - expected = CFSTR("GMT+00:00"); -#endif - PASS_CFEQ(CFTimeZoneGetName(tz), expected, "CFTimeZone has correct name."); - + PASS_CFEQ(CFTimeZoneGetName(tz), CFSTR("GMT"), + "CFTimeZone has correct name."); + str = CFTimeZoneCopyAbbreviation (tz, 0.0); - PASS_CFEQ(str, expected, "Time zone abbreviations are equal."); + PASS_CFEQ(str, CFSTR("GMT"), "Time zone abbreviations are equal."); ti = CFTimeZoneGetSecondsFromGMT (tz, 0.0); PASS_CF(ti == 0.0, "GMT+00:00 offset from GMT is %g", ti); diff --git a/Tests/CFTimeZone/gmt_name.m b/Tests/CFTimeZone/gmt_name.m new file mode 100644 index 0000000..f910b9e --- /dev/null +++ b/Tests/CFTimeZone/gmt_name.m @@ -0,0 +1,70 @@ +#include "CoreFoundation/CFTimeZone.h" +#include "../CFTesting.h" + +/* The name of a GMT-offset zone is GMT for a zero offset and GMT followed by + the signed four-digit offset otherwise; the abbreviation is compact. */ + +static CFStringRef +tzname_of (CFTimeInterval ti) +{ + CFTimeZoneRef tz = CFTimeZoneCreateWithTimeIntervalFromGMT (NULL, ti); + CFStringRef name = (CFStringRef) CFRetain (CFTimeZoneGetName (tz)); + CFRelease (tz); + return name; +} + +static CFStringRef +tzabbr_of (CFTimeInterval ti) +{ + CFTimeZoneRef tz = CFTimeZoneCreateWithTimeIntervalFromGMT (NULL, ti); + CFStringRef abbr = CFTimeZoneCopyAbbreviation (tz, 0.0); + CFRelease (tz); + return abbr; +} + +int main (void) +{ + CFStringRef s; + + s = tzname_of (0.0); + PASS_CFEQ (s, CFSTR ("GMT"), "A zero offset is named GMT."); + CFRelease (s); + s = tzname_of (5 * 3600); + PASS_CFEQ (s, CFSTR ("GMT+0500"), "A five-hour offset is named GMT+0500."); + CFRelease (s); + s = tzname_of (-5 * 3600); + PASS_CFEQ (s, CFSTR ("GMT-0500"), + "A negative five-hour offset is named GMT-0500."); + CFRelease (s); + s = tzname_of (5 * 3600 + 30 * 60); + PASS_CFEQ (s, CFSTR ("GMT+0530"), + "A five-and-a-half-hour offset is named GMT+0530."); + CFRelease (s); + s = tzname_of (30 * 60); + PASS_CFEQ (s, CFSTR ("GMT+0030"), "A thirty-minute offset is named GMT+0030."); + CFRelease (s); + + s = tzabbr_of (0.0); + PASS_CFEQ (s, CFSTR ("GMT"), "A zero offset abbreviates to GMT."); + CFRelease (s); + s = tzabbr_of (5 * 3600); + PASS_CFEQ (s, CFSTR ("GMT+5"), "A five-hour offset abbreviates to GMT+5."); + CFRelease (s); + s = tzabbr_of (-5 * 3600); + PASS_CFEQ (s, CFSTR ("GMT-5"), + "A negative five-hour offset abbreviates to GMT-5."); + CFRelease (s); + s = tzabbr_of (5 * 3600 + 30 * 60); + PASS_CFEQ (s, CFSTR ("GMT+5:30"), + "A five-and-a-half-hour offset abbreviates to GMT+5:30."); + CFRelease (s); + s = tzabbr_of (30 * 60); + PASS_CFEQ (s, CFSTR ("GMT+0:30"), + "A thirty-minute offset abbreviates to GMT+0:30."); + CFRelease (s); + s = tzabbr_of (10 * 3600); + PASS_CFEQ (s, CFSTR ("GMT+10"), "A ten-hour offset abbreviates to GMT+10."); + CFRelease (s); + + return 0; +}