← Commit list

283db12e05

Daniel Stenberg
Daniel Stenberg
2026-04-08
SUCCESS Duration: 246s

Subject

parsedate: bsearch the time zones

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+80 -83
@@ -25,6 +25,7 @@
#include "parsedate.h"
#include "curlx/strparse.h"
+#include "curlx/strcopy.h"
/*
A brief summary of the date string formats this parser groks:
@@ -108,89 +109,83 @@ static const char * const weekday[] = {
struct tzinfo {
char name[5];
- int offset; /* +/- in minutes */
+ int16_t offset; /* +/- in minutes */
};
-/* Here's a bunch of frequently used time zone names. These were supported
- by the old getdate parser. */
#define tDAYZONE (-60) /* offset for daylight savings time */
+
+/* alpha-sorted list of time zones */
static const struct tzinfo tz[] = {
- { "GMT", 0 }, /* Greenwich Mean */
- { "UT", 0 }, /* Universal Time */
- { "UTC", 0 }, /* Universal (Coordinated) */
- { "WET", 0 }, /* Western European */
- { "BST", 0 + tDAYZONE }, /* British Summer */
- { "WAT", 60 }, /* West Africa */
- { "AST", 240 }, /* Atlantic Standard */
+ { "A", -1 * 60 }, /* Alpha */
{ "ADT", 240 + tDAYZONE }, /* Atlantic Daylight */
- { "EST", 300 }, /* Eastern Standard */
- { "EDT", 300 + tDAYZONE }, /* Eastern Daylight */
- { "CST", 360 }, /* Central Standard */
+ { "AHST", 600 }, /* Alaska-Hawaii Standard */
+ { "AST", 240 }, /* Atlantic Standard */
+ { "B", -2 * 60 }, /* Bravo */
+ { "BST", 0 + tDAYZONE }, /* British Summer */
+ { "C", -3 * 60 }, /* Charlie */
+ { "CAT", 600 }, /* Central Alaska */
+ { "CCT", -480 }, /* China Coast, USSR Zone 7 */
{ "CDT", 360 + tDAYZONE }, /* Central Daylight */
- { "MST", 420 }, /* Mountain Standard */
- { "MDT", 420 + tDAYZONE }, /* Mountain Daylight */
- { "PST", 480 }, /* Pacific Standard */
- { "PDT", 480 + tDAYZONE }, /* Pacific Daylight */
- { "YST", 540 }, /* Yukon Standard */
- { "YDT", 540 + tDAYZONE }, /* Yukon Daylight */
- { "HST", 600 }, /* Hawaii Standard */
+ { "CEST", -60 + tDAYZONE }, /* Central European Summer */
+ { "CET", -60 }, /* Central European */
+ { "CST", 360 }, /* Central Standard */
+ { "D", -4 * 60 }, /* Delta */
+ { "E", -5 * 60 }, /* Echo */
+ { "EADT", -600 + tDAYZONE }, /* Eastern Australian Daylight */
+ { "EAST", -600 }, /* Eastern Australian Standard */
+ { "EDT", 300 + tDAYZONE }, /* Eastern Daylight */
+ { "EET", -120 }, /* Eastern Europe, USSR Zone 1 */
+ { "EST", 300 }, /* Eastern Standard */
+ { "F", -6 * 60 }, /* Foxtrot */
+ { "FST", -60 + tDAYZONE }, /* French Summer */
+ { "FWT", -60 }, /* French Winter */
+ { "G", -7 * 60 }, /* Golf */
+ { "GMT", 0 }, /* Greenwich Mean */
+ { "GST", -600 }, /* Guam Standard, USSR Zone 9 */
+ { "H", -8 * 60 }, /* Hotel */
{ "HDT", 600 + tDAYZONE }, /* Hawaii Daylight */
- { "CAT", 600 }, /* Central Alaska */
- { "AHST", 600 }, /* Alaska-Hawaii Standard */
- { "NT", 660 }, /* Nome */ /* spellchecker:disable-line */
+ { "HST", 600 }, /* Hawaii Standard */
+ { "I", -9 * 60 }, /* India */
+ { "IDLE", -720 }, /* International Date Line East */
{ "IDLW", 720 }, /* International Date Line West */
- { "CET", -60 }, /* Central European */
- { "MET", -60 }, /* Middle European */
- { "MEWT", -60 }, /* Middle European Winter */
+ { "JST", -540 }, /* Japan Standard, USSR Zone 8 */
+ { "K", -10 * 60 }, /* Kilo */
+ { "L", -11 * 60 }, /* Lima */
+ { "M", -12 * 60 }, /* Mike */
+ { "MDT", 420 + tDAYZONE }, /* Mountain Daylight */
{ "MEST", -60 + tDAYZONE }, /* Middle European Summer */
- { "CEST", -60 + tDAYZONE }, /* Central European Summer */
{ "MESZ", -60 + tDAYZONE }, /* Middle European Summer */
- { "FWT", -60 }, /* French Winter */
- { "FST", -60 + tDAYZONE }, /* French Summer */
- { "EET", -120 }, /* Eastern Europe, USSR Zone 1 */
+ { "MET", -60 }, /* Middle European */
+ { "MEWT", -60 }, /* Middle European Winter */
+ { "MST", 420 }, /* Mountain Standard */
+ { "N", 60 }, /* November */
+ { "NT", 660 }, /* Nome */ /* spellchecker:disable-line */
+ { "NZDT", -720 + tDAYZONE }, /* New Zealand Daylight */
+ { "NZST", -720 }, /* New Zealand Standard */
+ { "NZT", -720 }, /* New Zealand */
+ { "O", 2 * 60 }, /* Oscar */
+ { "P", 3 * 60 }, /* Papa */
+ { "PDT", 480 + tDAYZONE }, /* Pacific Daylight */
+ { "PST", 480 }, /* Pacific Standard */
+ { "Q", 4 * 60 }, /* Quebec */
+ { "R", 5 * 60 }, /* Romeo */
+ { "S", 6 * 60 }, /* Sierra */
+ { "T", 7 * 60 }, /* Tango */
+ { "U", 8 * 60 }, /* Uniform */
+ { "UT", 0 }, /* Universal Time */
+ { "UTC", 0 }, /* Universal (Coordinated) */
+ { "V", 9 * 60 }, /* Victor */
+ { "W", 10 * 60 }, /* Whiskey */
+ { "WADT", -420 + tDAYZONE }, /* West Australian Daylight */
{ "WAST", -420 }, /* spellchecker:disable-line */
/* West Australian Standard */
- { "WADT", -420 + tDAYZONE }, /* West Australian Daylight */
- { "CCT", -480 }, /* China Coast, USSR Zone 7 */
- { "JST", -540 }, /* Japan Standard, USSR Zone 8 */
- { "EAST", -600 }, /* Eastern Australian Standard */
- { "EADT", -600 + tDAYZONE }, /* Eastern Australian Daylight */
- { "GST", -600 }, /* Guam Standard, USSR Zone 9 */
- { "NZT", -720 }, /* New Zealand */
- { "NZST", -720 }, /* New Zealand Standard */
- { "NZDT", -720 + tDAYZONE }, /* New Zealand Daylight */
- { "IDLE", -720 }, /* International Date Line East */
- /* Next up: Military timezone names. RFC822 allowed these, but (as noted in
- RFC 1123) had their signs wrong. Here we use the correct signs to match
- actual military usage.
- */
- { "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 */
- /* "J", Juliet is not used as a timezone, to indicate the observer's local
- time */
- { "K", -10 * 60 }, /* Kilo */
- { "L", -11 * 60 }, /* Lima */
- { "M", -12 * 60 }, /* Mike */
- { "N", 1 * 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 */
+ { "WAT", 60 }, /* West Africa */
+ { "WET", 0 }, /* Western European */
+ { "X", 11 * 60 }, /* X-ray */
+ { "Y", 12 * 60 }, /* Yankee */
+ { "YDT", 540 + tDAYZONE }, /* Yukon Daylight */
+ { "YST", 540 }, /* Yukon Standard */
+ { "Z", 0 }, /* Zulu, zero meridian, a.k.a. UTC */
};
/* returns:
@@ -233,22 +228,24 @@ static int checkmonth(const char *check, size_t len)
return -1; /* return the offset or -1, no real offset is -1 */
}
-/* return the time zone offset between GMT and the input one, in number
- of seconds or -1 if the timezone was not found/legal */
+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 the time zone offset between GMT and the input one, in number of
+ seconds or -1 if the timezone was not found/legal */
static int checktz(const char *check, size_t len)
{
- unsigned int i;
- const struct tzinfo *what = tz;
- if(len > 4) /* longer than any valid timezone */
- return -1;
-
- for(i = 0; i < CURL_ARRAYSIZE(tz); i++) {
- size_t ilen = strlen(what->name);
- if((ilen == len) &&
- curl_strnequal(check, what->name, len))
+ if(len <= 4) {
+ const struct tzinfo *what;
+ struct tzinfo find;
+ curlx_strcopy(find.name, sizeof(find.name), check, len);
+ what = bsearch(&find, tz, CURL_ARRAYSIZE(tz), sizeof(tz[0]), tzcompare);
+ if(what)
return what->offset * 60;
- what++;
}
return -1;
}
tests/libtest/lib517.c+3 -0
@@ -52,6 +52,9 @@ static CURLcode test_lib517(const char *URL)
{ "1994.Nov.6", 784080000 },
{ "Sun/Nov/6/94/GMT", 784080000 },
{ "Sun, 06 Nov 1994 08:49:37 CET", 784108177 },
+ { "Sun, 06 Nov 1994 08:49:37 cet", -1 }, /* lowercase time zone */
+ { "Sun, 06 Nov 1994 08:49:37 utc", -1 }, /* lowercase time zone */
+ { "Sun, 06 Nov 1994 08:49:37 gmt", -1 }, /* lowercase time zone */
{ "06 Nov 1994 08:49:37 EST", 784129777 },
{ "Sun, 06 Nov 1994 08:49:37 UT", 784111777 },
{ "Sun, 12 Sep 2004 15:05:58 -0700", 1095026758 },