← Commit list

f1956d2305

Daniel Stenberg
Daniel Stenberg
2026-09-19
SUCCESS Duration: 387s

Subject

parsedate: time zone strings

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/parsedate.c+97 -90
@@ -108,96 +108,99 @@ static const char * const weekday[] = {
};
struct tzinfo {
- char name[5];
+ uint32_t tz;
int16_t offset; /* +/- in minutes */
};
-#define tDAYZONE (-60) /* offset for daylight savings time */
-
-/* alpha-sorted list of single-letter time zones */
-static const struct tzinfo tzone[] = {
- { "A", -1 * 60 }, /* Alpha */
- { "B", -2 * 60 }, /* Bravo */
- { "C", -3 * 60 }, /* Charlie */
- { "D", -4 * 60 }, /* Delta */
- { "E", -5 * 60 }, /* Echo */
- { "F", -6 * 60 }, /* Foxtrot */
- { "G", -7 * 60 }, /* Golf */
- { "H", -8 * 60 }, /* Hotel */
- { "I", -9 * 60 }, /* India */
- { "", -1 }, /* not a timezone */
- { "K", -10 * 60 }, /* Kilo */
- { "L", -11 * 60 }, /* Lima */
- { "M", -12 * 60 }, /* Mike */
- { "N", 60 }, /* November */
- { "O", 2 * 60 }, /* Oscar */
- { "P", 3 * 60 }, /* Papa */
- { "Q", 4 * 60 }, /* Quebec */
- { "R", 5 * 60 }, /* Romeo */
- { "S", 6 * 60 }, /* Sierra */
- { "T", 7 * 60 }, /* Tango */
- { "U", 8 * 60 }, /* Uniform */
- { "V", 9 * 60 }, /* Victor */
- { "W", 10 * 60 }, /* Whiskey */
- { "X", 11 * 60 }, /* X-ray */
- { "Y", 12 * 60 }, /* Yankee */
- { "Z", 0 }, /* Zulu, zero meridian, a.k.a. UTC */
+#define DST (-60) /* offset for daylight savings time */
+
+/* alpha-sorted list of single-letter time zones, A - Z */
+static const int16_t tzone[] = {
+ -1 * 60, /* Alpha */
+ -2 * 60, /* Bravo */
+ -3 * 60, /* Charlie */
+ -4 * 60, /* Delta */
+ -5 * 60, /* Echo */
+ -6 * 60, /* Foxtrot */
+ -7 * 60, /* Golf */
+ -8 * 60, /* Hotel */
+ -9 * 60, /* India */
+ -1, /* J - not a timezone */
+ -10 * 60, /* Kilo */
+ -11 * 60, /* Lima */
+ -12 * 60, /* Mike */
+ 60, /* November */
+ 2 * 60, /* Oscar */
+ 3 * 60, /* Papa */
+ 4 * 60, /* Quebec */
+ 5 * 60, /* Romeo */
+ 6 * 60, /* Sierra */
+ 7 * 60, /* Tango */
+ 8 * 60, /* Uniform */
+ 9 * 60, /* Victor */
+ 10 * 60, /* Whiskey */
+ 11 * 60, /* X-ray */
+ 12 * 60, /* Yankee */
+ 0 /* Zulu, zero meridian, a.k.a. UTC */
};
-/* two-letter time zones */
-static const struct tzinfo tztwo[] = {
- { "NT", 660 }, /* Nome */ /* spellchecker:disable-line */
- { "UT", 0 }, /* Universal Time */
-};
+/* two-letter time zones
+
+ 11 * 60, NT - Nome spellchecker:disable-line
+ 0, UT - Universal Time
+
+*/
+
+#define MKTZ(a,b,c,d) (((a)<<24) | ((b)<<16) | ((c)<<8) | (d))
/* three-letter time zones */
static const struct tzinfo tzthree[] = {
- { "ADT", 240 + tDAYZONE }, /* Atlantic Daylight */
- { "AST", 240 }, /* Atlantic Standard */
- { "BST", 0 + tDAYZONE }, /* British Summer */
- { "CAT", 600 }, /* Central Alaska */
- { "CCT", -480 }, /* China Coast, USSR Zone 7 */
- { "CDT", 360 + tDAYZONE }, /* Central Daylight */
- { "CET", -60 }, /* Central European */
- { "CST", 360 }, /* Central Standard */
- { "EDT", 300 + tDAYZONE }, /* Eastern Daylight */
- { "EET", -120 }, /* Eastern Europe, USSR Zone 1 */
- { "EST", 300 }, /* Eastern Standard */
- { "FST", -60 + tDAYZONE }, /* French Summer */
- { "FWT", -60 }, /* French Winter */
- { "GMT", 0 }, /* Greenwich Mean */
- { "GST", -600 }, /* Guam Standard, USSR Zone 9 */
- { "HDT", 600 + tDAYZONE }, /* Hawaii Daylight */
- { "HST", 600 }, /* Hawaii Standard */
- { "JST", -540 }, /* Japan Standard, USSR Zone 8 */
- { "MDT", 420 + tDAYZONE }, /* Mountain Daylight */
- { "MET", -60 }, /* Middle European */
- { "MST", 420 }, /* Mountain Standard */
- { "NZT", -720 }, /* New Zealand */
- { "PDT", 480 + tDAYZONE }, /* Pacific Daylight */
- { "PST", 480 }, /* Pacific Standard */
- { "UTC", 0 }, /* Universal (Coordinated) */
- { "WAT", 60 }, /* West Africa */
- { "WET", 0 }, /* Western European */
- { "YDT", 540 + tDAYZONE }, /* Yukon Daylight */
- { "YST", 540 }, /* Yukon Standard */
+ { MKTZ('A', 'D', 'T', '\0'), 240 + DST }, /* Atlantic Daylight */
+ { MKTZ('A', 'S', 'T', '\0'), 240 }, /* Atlantic Standard */
+ { MKTZ('B', 'S', 'T', '\0'), 0 + DST }, /* British Summer */
+ { MKTZ('C', 'A', 'T', '\0'), 600 }, /* Central Alaska */
+ { MKTZ('C', 'C', 'T', '\0'), -480 }, /* China Coast, USSR Zone 7 */
+ { MKTZ('C', 'D', 'T', '\0'), 360 + DST }, /* Central Daylight */
+ { MKTZ('C', 'E', 'T', '\0'), -60 }, /* Central European */
+ { MKTZ('C', 'S', 'T', '\0'), 360 }, /* Central Standard */
+ { MKTZ('E', 'D', 'T', '\0'), 300 + DST }, /* Eastern Daylight */
+ { MKTZ('E', 'E', 'T', '\0'), -120 }, /* Eastern Europe, USSR Zone 1 */
+ { MKTZ('E', 'S', 'T', '\0'), 300 }, /* Eastern Standard */
+ { MKTZ('F', 'S', 'T', '\0'), -60 + DST }, /* French Summer */
+ { MKTZ('F', 'W', 'T', '\0'), -60 }, /* French Winter */
+ { MKTZ('G', 'M', 'T', '\0'), 0 }, /* Greenwich Mean */
+ { MKTZ('G', 'S', 'T', '\0'), -600 }, /* Guam Standard, USSR Zone 9 */
+ { MKTZ('H', 'D', 'T', '\0'), 600 + DST }, /* Hawaii Daylight */
+ { MKTZ('H', 'S', 'T', '\0'), 600 }, /* Hawaii Standard */
+ { MKTZ('J', 'S', 'T', '\0'), -540 }, /* Japan Standard, USSR Zone 8 */
+ { MKTZ('M', 'D', 'T', '\0'), 420 + DST }, /* Mountain Daylight */
+ { MKTZ('M', 'E', 'T', '\0'), -60 }, /* Middle European */
+ { MKTZ('M', 'S', 'T', '\0'), 420 }, /* Mountain Standard */
+ { MKTZ('N', 'Z', 'T', '\0'), -720 }, /* New Zealand */
+ { MKTZ('P', 'D', 'T', '\0'), 480 + DST }, /* Pacific Daylight */
+ { MKTZ('P', 'S', 'T', '\0'), 480 }, /* Pacific Standard */
+ { MKTZ('U', 'T', 'C', '\0'), 0 }, /* Universal (Coordinated) */
+ { MKTZ('W', 'A', 'T', '\0'), 60 }, /* West Africa */
+ { MKTZ('W', 'E', 'T', '\0'), 0 }, /* Western European */
+ { MKTZ('Y', 'D', 'T', '\0'), 540 + DST }, /* Yukon Daylight */
+ { MKTZ('Y', 'S', 'T', '\0'), 540 }, /* Yukon Standard */
};
/* four-letter time zones */
static const struct tzinfo tzfoura[] = {
- { "AHST", 600 }, /* Alaska-Hawaii Standard */
- { "CEST", -60 + tDAYZONE }, /* Central European Summer */
- { "EADT", -600 + tDAYZONE }, /* Eastern Australian Daylight */
- { "EAST", -600 }, /* Eastern Australian Standard */
- { "IDLE", -720 }, /* International Date Line East */
- { "IDLW", 720 }, /* International Date Line West */
- { "MEST", -60 + tDAYZONE }, /* Middle European Summer */
- { "MESZ", -60 + tDAYZONE }, /* Middle European Summer */
- { "MEWT", -60 }, /* Middle European Winter */
- { "NZDT", -720 + tDAYZONE }, /* New Zealand Daylight */
- { "NZST", -720 }, /* New Zealand Standard */
- { "WADT", -420 + tDAYZONE }, /* West Australian Daylight */
- { "WAST", -420 }, /* spellchecker:disable-line */
+ { MKTZ('A', 'H', 'S', 'T'), 600 }, /* Alaska-Hawaii Standard */
+ { MKTZ('C', 'E', 'S', 'T'), -60 + DST }, /* Central European Summer */
+ { MKTZ('E', 'A', 'D', 'T'), -600 + DST }, /* Eastern Australian Daylight */
+ { MKTZ('E', 'A', 'S', 'T'), -600 }, /* Eastern Australian Standard */
+ { MKTZ('I', 'D', 'L', 'E'), -720 }, /* International Date Line East */
+ { MKTZ('I', 'D', 'L', 'W'), 720 }, /* International Date Line West */
+ { MKTZ('M', 'E', 'S', 'T'), -60 + DST }, /* Middle European Summer */
+ { MKTZ('M', 'E', 'S', 'Z'), -60 + DST }, /* Middle European Summer */
+ { MKTZ('M', 'E', 'W', 'T'), -60 }, /* Middle European Winter */
+ { MKTZ('N', 'Z', 'D', 'T'), -720 + DST }, /* New Zealand Daylight */
+ { MKTZ('N', 'Z', 'S', 'T'), -720 }, /* New Zealand Standard */
+ { MKTZ('W', 'A', 'D', 'T'), -420 + DST }, /* West Australian Daylight */
+ { MKTZ('W', 'A', 'S', 'T'), -420 }, /* spellchecker:disable-line */
/* West Australian Standard */
};
@@ -320,7 +323,7 @@ static int tzcompare(const void *m1, const void *m2)
{
const struct tzinfo *tz1 = m1;
const struct tzinfo *tz2 = m2;
- return strcmp(tz1->name, tz2->name);
+ return tz1->tz - tz2->tz;
}
/* return the time zone offset between GMT and the input one, in number of
@@ -331,21 +334,25 @@ static int tzcompare(const void *m1, const void *m2)
UNITTEST int checktz(const char *check, size_t len);
UNITTEST int checktz(const char *check, size_t len)
{
+ char first;
if(len > 4)
return -1;
- else if(len == 1) {
+ first = check[0];
+ if(first < 'A')
+ return -1;
+ if(len == 1) {
/* short-cut single letter names */
- if((check[0] < 'A') || (check[0] > 'Z') || (check[0] == 'J'))
+ if((first > 'Z') || (first == 'J'))
return -1; /* no such tz */
- return tzone[check[0] - 'A'].offset * 60;
+ return tzone[first - 'A'] * 60;
}
else if(len == 2) {
/* two-letter names */
if(check[1] == 'T') {
- if(check[0] == 'N')
- return tztwo[0].offset * 60;
- else if(check[0] == 'U')
- return tztwo[1].offset * 60;
+ if(first == 'N')
+ return 11 * 60 * 60;
+ else if(first == 'U')
+ return 0;
}
return -1; /* nope */
}
@@ -353,9 +360,9 @@ UNITTEST int checktz(const char *check, size_t len)
/* three-letter name */
const struct tzinfo *what;
struct tzinfo find;
- if((check[0] < 'A') || (check[0] > 'Y'))
+ if(first > 'Y')
return -1;
- curlx_strcopy(find.name, sizeof(find.name), check, len);
+ find.tz = MKTZ(first, check[1], check[2], 0);
what = bsearch(&find, tzthree, CURL_ARRAYSIZE(tzthree),
sizeof(tzthree[0]), tzcompare);
if(what)
@@ -365,9 +372,9 @@ UNITTEST int checktz(const char *check, size_t len)
/* four-letter name */
const struct tzinfo *what;
struct tzinfo find;
- if((check[0] < 'A') || (check[0] > 'W'))
+ if(first > 'W')
return -1;
- curlx_strcopy(find.name, sizeof(find.name), check, len);
+ find.tz = MKTZ(first, check[1], check[2], check[3]);
what = bsearch(&find, tzfoura, CURL_ARRAYSIZE(tzfoura),
sizeof(tzfoura[0]), tzcompare);
if(what)