61 "Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
68 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
69 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
79 {
"aat", 1, 0,
true },
80 {
"adt", 4, 0,
false },
81 {
"ast", 3, 0,
false },
83 {
"bst", 1, 0,
false },
84 {
"cat", 1, 0,
false },
85 {
"cdt", 5, 0,
true },
86 {
"cest", 2, 0,
false },
87 {
"cet", 1, 0,
false },
88 {
"cst", 6, 0,
true },
91 {
"eat", 3, 0,
false },
92 {
"edt", 4, 0,
true },
93 {
"eest", 3, 0,
false },
94 {
"eet", 2, 0,
false },
95 {
"egst", 0, 0,
false },
96 {
"egt", 1, 0,
true },
97 {
"est", 5, 0,
true },
98 {
"gmt", 0, 0,
false },
99 {
"gst", 4, 0,
false },
100 {
"hkt", 8, 0,
false },
101 {
"ict", 7, 0,
false },
102 {
"idt", 3, 0,
false },
103 {
"ist", 2, 0,
false },
105 {
"jst", 9, 0,
false },
106 {
"kst", 9, 0,
false },
107 {
"mdt", 6, 0,
true },
108 {
"met", 1, 0,
false },
109 {
"met dst", 2, 0,
false },
110 {
"msd", 4, 0,
false },
111 {
"msk", 3, 0,
false },
112 {
"mst", 7, 0,
true },
113 {
"nzdt", 13, 0,
false },
114 {
"nzst", 12, 0,
false },
115 {
"pdt", 7, 0,
true },
116 {
"pst", 8, 0,
true },
117 {
"sat", 2, 0,
false },
118 {
"smt", 4, 0,
false },
119 {
"sst", 11, 0,
true },
121 {
"utc", 0, 0,
false },
122 {
"wat", 0, 0,
false },
123 {
"west", 1, 0,
false },
124 {
"wet", 0, 0,
false },
125 {
"wgst", 2, 0,
true },
126 {
"wgt", 3, 0,
true },
127 {
"wst", 8, 0,
false },
144 int tz = (((lt.tm_hour - utc->tm_hour) * 60) + (lt.tm_min - utc->tm_min)) * 60;
146 int yday = (lt.tm_yday - utc->tm_yday);
153 tz -= (24 * 60 * 60);
157 tz += (24 * 60 * 60);
175 return t + (w ? 1 : -1) * (((time_t) h * 3600) + ((time_t) m * 60));
187static const struct Tz *
find_tz(
const char *s,
size_t len)
207 int y = tm->tm_year + 1900;
208 return ((y & 3) == 0) && (((y % 100) != 0) || ((y % 400) == 0));
248 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
252 if (t->tm_year > 10000)
254 if (t->tm_year < -10000)
257 if ((t->tm_mday < 1) || (t->tm_mday > 31))
259 if ((t->tm_hour < 0) || (t->tm_hour > 23) || (t->tm_min < 0) ||
260 (t->tm_min > 59) || (t->tm_sec < 0) || (t->tm_sec > 60))
264 if (t->tm_year > 9999)
273 if ((t->tm_year % 4) || (t->tm_mon < 2))
280 g += (t->tm_year - 70) * (time_t) 365;
281 g += (t->tm_year - 69) / 4;
316 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
320 while (tm->tm_sec < 0)
325 while (tm->tm_sec >= 60)
330 while (tm->tm_min < 0)
335 while (tm->tm_min >= 60)
340 while (tm->tm_hour < 0)
345 while (tm->tm_hour >= 24)
351 while (tm->tm_mon < 0)
356 while (tm->tm_mon >= 12)
361 while (tm->tm_mday <= 0)
374 while (tm->tm_mday > (DaysPerMonth[tm->tm_mon] + (leap =
is_leap_year_feb(tm))))
376 tm->tm_mday -= DaysPerMonth[tm->tm_mon] + leap;
402 struct tm tm = { 0 };
419 tm.tm_mday,
Months[tm.tm_mon], tm.tm_year + 1900, tm.tm_hour,
420 tm.tm_min, tm.tm_sec, tz / 60, abs(tz) % 60);
440 memcpy(&sv, buf,
sizeof(sv));
444 memcpy(&mv,
Months[i],
sizeof(mv));
467 struct timeval tv = { 0, 0 };
468 gettimeofday(&tv, NULL);
471 return ((uint64_t) tv.tv_sec * 1000) + (tv.tv_usec / 1000);
482#ifdef HAVE_CLOCK_GETTIME
483 if (clock_gettime(CLOCK_REALTIME, tp) != 0)
486 struct timeval tv = { 0, 0 };
487 if (gettimeofday(&tv, NULL) != 0)
489 tp->tv_sec = tv.tv_sec;
490 tp->tv_nsec = tv.tv_usec * 1000;
509 const char *ptr = str;
511 while ((ptr < end) && (ptr < (str + 5)) && (*ptr >=
'0') && (*ptr <=
'9'))
513 v = (v * 10) + (*ptr -
'0');
539 size_t len = strlen(s);
542 if ((len >= 5) && (s[4] ==
' ') &&
543 (
eqi4(s,
"Mon,") ||
eqi4(s,
"Tue,") ||
eqi4(s,
"Wed,") ||
550 while ((len > 0) && (*s ==
' '))
556 if ((len == 0) || (*s <
'0') || (*s >
'9'))
559 struct tm tm = { 0 };
563 if ((mday_len == 0) || (mday_len > 2) || (tm.tm_mday > 31))
568 if ((len == 0) || (*s !=
' '))
582 if ((len == 0) || (*s !=
' '))
589 if ((year_len != 2) && (year_len != 4))
593 else if (tm.tm_year >= 1900)
598 if ((len == 0) || (*s !=
' '))
604 if ((len < 3) || (s[0] <
'0') || (s[0] >
'2') || (s[1] <
'0') ||
605 (s[1] >
'9') || (s[2] !=
':'))
609 tm.tm_hour = ((s[0] -
'0') * 10) + (s[1] -
'0');
616 if ((len < 2) || (s[0] <
'0') || (s[0] >
'5') || (s[1] <
'0') || (s[1] >
'9'))
618 tm.tm_min = ((s[0] -
'0') * 10) + (s[1] -
'0');
625 if ((len > 0) && (s[0] ==
':'))
629 if ((len < 2) || (s[0] <
'0') || (s[0] >
'5') || (s[1] <
'0') || (s[1] >
'9'))
631 tm.tm_sec = ((s[0] -
'0') * 10) + (s[1] -
'0');
638 while ((len > 0) && (*s ==
' '))
646 while ((len > 0) && (s[len - 1] ==
' '))
648 if ((len >= 2) && (s[len - 1] ==
')'))
650 for (
int i = len - 1; i-- > 0;)
657 if (!isalpha(s[i]) && (s[i] !=
' '))
661 while ((len > 0) && (s[len - 1] ==
' '))
667 bool zoccident =
false;
670 if ((len == 5) && ((s[0] ==
'+') || (s[0] ==
'-')) && (s[1] >=
'0') &&
671 (s[1] <=
'9') && (s[2] >=
'0') && (s[2] <=
'9') && (s[3] >=
'0') &&
672 (s[3] <=
'9') && (s[4] >=
'0') && (s[4] <=
'9'))
674 zoccident = (s[0] ==
'-');
675 zhours = ((s[1] -
'0') * 10) + (s[2] -
'0');
676 zminutes = ((s[3] -
'0') * 10) + (s[4] -
'0');
680 for (
int i = 0; i < len; ++i)
733 struct tm tm = { 0 };
758 else if (tm.tm_year >= 1900)
762 int hour = 0, min = 0, sec = 0;
767 if ((hour > 23) || (min > 59) || (sec > 60))
776 bool zoccident =
false;
779 char direction =
'\0';
781 zoccident = (direction ==
'-');
821 return buf_printf(buf,
"%02d-%s-%d %02d:%02d:%02d %+03d%02d", tm.tm_mday,
822 Months[tm.tm_mon], tm.tm_year + 1900, tm.tm_hour, tm.tm_min,
823 tm.tm_sec, tz / 60, abs(tz) % 60);
843 return snprintf(buf, buflen,
"%s, %d %s %d %02d:%02d:%02d UTC",
845 tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec);
866 struct tm tm = { 0 };
874 char direction =
'\0';
875 int zhours = 0, zminutes = 0;
877 bool zoccident = (direction ==
'-');
898 return now + timeout;
908 struct tm tm = { 0 };
910 struct tm *ret = localtime_r(&t, &tm);
913 mutt_debug(
LL_DEBUG1,
"Could not convert time_t via localtime_r() to struct tm: time_t = %jd\n",
915 struct tm default_tm = { 0 };
929 struct tm tm = { 0 };
931 struct tm *ret = gmtime_r(&t, &tm);
934 mutt_debug(
LL_DEBUG1,
"Could not convert time_t via gmtime_r() to struct tm: time_t = %jd\n",
936 struct tm default_tm = { 0 };
957 return strftime(buf, buflen, format, &tm);
970 const char *format, time_t t, locale_t loc)
976 return strftime_l(buf, buflen, format, &tm, loc);
985 const struct timespec sleep = {
987 .tv_nsec = (ms % 1000) * 1000000UL,
989 nanosleep(&sleep, NULL);
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
General purpose object for storing and parsing strings.
Time and date handling routines.
Case-insensitive fixed-chunk comparisons.
static bool eqi4(const char *a, const char b[4])
Compare two 4-byte strings, ignoring case - See: Case-insensitive fixed-chunk comparisons.
#define mutt_debug(LEVEL,...)
@ LL_DEBUG2
Log at debug level 2.
@ LL_DEBUG1
Log at debug level 1.
Memory management wrappers.
#define mutt_array_size(x)
struct tm mutt_date_localtime(time_t t)
Converts calendar time to a broken-down time structure expressed in user timezone.
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
uint64_t mutt_date_now_ms(void)
Return the number of milliseconds since the Unix epoch.
static int compute_tz(time_t g, struct tm *utc)
Calculate the number of seconds east of UTC.
void mutt_date_make_date(struct Buffer *buf, bool local)
Write a date in RFC822 format to a buffer.
time_t mutt_date_make_time(struct tm *t, bool local)
Convert struct tm to time_t
static int parse_small_uint(const char *str, const char *end, int *val)
Parse a positive integer of at most 5 digits.
static const char *const Months[]
Months of the year (abbreviated)
void mutt_date_sleep_ms(size_t ms)
Sleep for milliseconds.
int mutt_date_check_month(const char *s)
Is the string a valid month name.
static const struct Tz * find_tz(const char *s, size_t len)
Look up a timezone.
struct tm mutt_date_gmtime(time_t t)
Converts calendar time to a broken-down time structure expressed in UTC timezone.
size_t mutt_date_localtime_format_locale(char *buf, size_t buflen, const char *format, time_t t, locale_t loc)
Format localtime using a given locale.
int mutt_date_make_tls(char *buf, size_t buflen, time_t timestamp)
Format date in TLS certificate verification style.
int mutt_date_make_imap(struct Buffer *buf, time_t timestamp)
Format date in IMAP style: DD-MMM-YYYY HH:MM:SS +ZZzz.
static int is_leap_year_feb(struct tm *tm)
Is a given February in a leap year.
static const char *const Weekdays[]
Day of the week (abbreviated)
static time_t mutt_date_parse_rfc5322_strict(const char *s, struct Tz *tz_out)
Parse a date string in RFC822 format.
int mutt_date_local_tz(time_t t)
Calculate the local timezone in seconds east of UTC.
time_t mutt_date_add_timeout(time_t now, time_t timeout)
Safely add a timeout to a given time_t value.
static const struct Tz TimeZones[]
Lookup table of Time Zones.
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
time_t mutt_date_parse_date(const char *s, struct Tz *tz_out)
Parse a date string in RFC822 format.
time_t mutt_date_parse_imap(const char *s)
Parse date of the form: DD-MMM-YYYY HH:MM:SS +ZZzz.
void mutt_time_now(struct timespec *tp)
Set the provided time field to the current time.
void mutt_date_normalize_time(struct tm *tm)
Fix the contents of a struct tm.
static time_t add_tz_offset(time_t t, bool w, time_t h, time_t m)
Compute and add a timezone offset to an UTC time.
static const char * timestamp(time_t stamp)
Create a YYYY-MM-DD HH:MM:SS timestamp.
bool mutt_istrn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings ignoring case (to a maximum), safely.
regmatch_t * mutt_prex_capture(enum Prex which, const char *str)
Match a precompiled regex against a string.
Manage precompiled / predefined regular expressions.
@ PREX_IMAP_DATE_MATCH_TIME
15-MAR-2020 [15:09:35] -0700
@ PREX_IMAP_DATE_MATCH_YEAR
15-MAR-[2020] 15:09:35 -0700
@ PREX_IMAP_DATE_MATCH_DAY
[ 4]-MAR-2020 15:09:35 -0700
@ PREX_IMAP_DATE_MATCH_TZ
15-MAR-2020 15:09:35 [-0700]
@ PREX_IMAP_DATE_MATCH_MONTH
15-[MAR]-2020 15:09:35 -0700
@ PREX_IMAP_DATE
[16-MAR-2020 15:09:35 -0700]
@ PREX_RFC5322_DATE_LAX
[Mon, (Comment) 16 Mar 2020 15:09:35 -0700]
@ PREX_RFC5322_DATE_LAX_MATCH_SECOND
Tue, 3 Mar 2020 14:32:[55] +0200
@ PREX_RFC5322_DATE_LAX_MATCH_TZ
Tue, 3 Mar 2020 14:32:55 [+0200]
@ PREX_RFC5322_DATE_LAX_MATCH_YEAR
Tue, 3 Mar [2020] 14:32:55 +0200
@ PREX_RFC5322_DATE_LAX_MATCH_HOUR
Tue, 3 Mar 2020 [14]:32:55 +0200
@ PREX_RFC5322_DATE_LAX_MATCH_MINUTE
Tue, 3 Mar 2020 14:[32]:55 +0200
@ PREX_RFC5322_DATE_LAX_MATCH_TZ_OBS
Tue, 3 Mar 2020 14:32:55[UT]
@ PREX_RFC5322_DATE_LAX_MATCH_MONTH
Tue, 3 [Jan] 2020 14:32:55 +0200
@ PREX_RFC5322_DATE_LAX_MATCH_DAY
Tue, [3] Mar 2020 14:32:55 +0200
Manage regular expressions.
static size_t mutt_regmatch_len(const regmatch_t *match)
Return the length of a match.
static regoff_t mutt_regmatch_start(const regmatch_t *match)
Return the start of a match.
String manipulation functions.
String manipulation buffer.
List of recognised Timezones.
unsigned char zminutes
Minutes away from UTC.
bool zoccident
True if west of UTC, False if East.
char tzname[8]
Name, e.g. UTC.
unsigned char zhours
Hours away from UTC.