NeoMutt  2023-03-22-27-g3cb248
Teaching an old dog new tricks
DOXYGEN
date.c File Reference

Time and date handling routines. More...

#include "config.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include "date.h"
#include "buffer.h"
#include "logging.h"
#include "memory.h"
#include "prex.h"
#include "regex3.h"
#include "string2.h"
+ Include dependency graph for date.c:

Go to the source code of this file.

Functions

static int compute_tz (time_t g, struct tm *utc)
 Calculate the number of seconds east of UTC. More...
 
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. More...
 
static const struct Tzfind_tz (const char *s, size_t len)
 Look up a timezone. More...
 
static int is_leap_year_feb (struct tm *tm)
 Is a given February in a leap year. More...
 
int mutt_date_local_tz (time_t t)
 Calculate the local timezone in seconds east of UTC. More...
 
time_t mutt_date_make_time (struct tm *t, bool local)
 Convert struct tm to time_t More...
 
void mutt_date_normalize_time (struct tm *tm)
 Fix the contents of a struct tm. More...
 
void mutt_date_make_date (struct Buffer *buf, bool local)
 Write a date in RFC822 format to a buffer. More...
 
int mutt_date_check_month (const char *s)
 Is the string a valid month name. More...
 
time_t mutt_date_now (void)
 Return the number of seconds since the Unix epoch. More...
 
uint64_t mutt_date_now_ms (void)
 Return the number of milliseconds since the Unix epoch. More...
 
time_t mutt_date_parse_date (const char *s, struct Tz *tz_out)
 Parse a date string in RFC822 format. More...
 
int mutt_date_make_imap (char *buf, size_t buflen, time_t timestamp)
 Format date in IMAP style: DD-MMM-YYYY HH:MM:SS +ZZzz. More...
 
int mutt_date_make_tls (char *buf, size_t buflen, time_t timestamp)
 Format date in TLS certificate verification style. More...
 
time_t mutt_date_parse_imap (const char *s)
 Parse date of the form: DD-MMM-YYYY HH:MM:SS +ZZzz. More...
 
time_t mutt_date_add_timeout (time_t now, time_t timeout)
 Safely add a timeout to a given time_t value. More...
 
struct tm mutt_date_localtime (time_t t)
 Converts calendar time to a broken-down time structure expressed in user timezone. More...
 
struct tm mutt_date_gmtime (time_t t)
 Converts calendar time to a broken-down time structure expressed in UTC timezone. More...
 
size_t mutt_date_localtime_format (char *buf, size_t buflen, const char *format, time_t t)
 Format localtime. More...
 
void mutt_date_sleep_ms (size_t ms)
 Sleep for milliseconds. More...
 

Variables

static const char *const Weekdays []
 Day of the week (abbreviated) More...
 
static const char *const Months []
 Months of the year (abbreviated) More...
 
static const struct Tz TimeZones []
 Lookup table of Time Zones. More...
 

Detailed Description

Time and date handling routines.

Authors
  • Michael R. Elkins

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file date.c.

Function Documentation

◆ compute_tz()

static int compute_tz ( time_t  g,
struct tm *  utc 
)
static

Calculate the number of seconds east of UTC.

Parameters
gLocal time
utcUTC time
Return values
numSeconds east of UTC

returns the seconds east of UTC given 'g' and its corresponding gmtime() representation

Definition at line 127 of file date.c.

128{
129 struct tm lt = mutt_date_localtime(g);
130
131 int tz = (((lt.tm_hour - utc->tm_hour) * 60) + (lt.tm_min - utc->tm_min)) * 60;
132
133 int yday = (lt.tm_yday - utc->tm_yday);
134 if (yday != 0)
135 {
136 /* This code is optimized to negative timezones (West of Greenwich) */
137 if ((yday == -1) || /* UTC passed midnight before localtime */
138 (yday > 1)) /* UTC passed new year before localtime */
139 {
140 tz -= (24 * 60 * 60);
141 }
142 else
143 {
144 tz += (24 * 60 * 60);
145 }
146 }
147
148 return tz;
149}
struct tm mutt_date_localtime(time_t t)
Converts calendar time to a broken-down time structure expressed in user timezone.
Definition: date.c:657
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_tz_offset()

static time_t add_tz_offset ( time_t  t,
bool  w,
time_t  h,
time_t  m 
)
static

Compute and add a timezone offset to an UTC time.

Parameters
tUTC time
wTrue if west of UTC, false if east
hNumber of hours in the timezone
mNumber of minutes in the timezone
Return values
numTimezone offset in seconds

Definition at line 159 of file date.c.

160{
161 if ((t != TIME_T_MAX) && (t != TIME_T_MIN))
162 return t + (w ? 1 : -1) * (((time_t) h * 3600) + ((time_t) m * 60));
163 else
164 return t;
165}
#define TIME_T_MAX
Definition: date.h:33
#define TIME_T_MIN
Definition: date.h:34
+ Here is the caller graph for this function:

◆ find_tz()

static const struct Tz * find_tz ( const char *  s,
size_t  len 
)
static

Look up a timezone.

Parameters
sTimezone to lookup
lenLength of the s string
Return values
ptrPointer to the Tz struct
NULLNot found

Definition at line 174 of file date.c.

175{
176 for (size_t i = 0; i < mutt_array_size(TimeZones); i++)
177 {
178 if (mutt_istrn_equal(TimeZones[i].tzname, s, len))
179 return &TimeZones[i];
180 }
181 return NULL;
182}
static const struct Tz TimeZones[]
Lookup table of Time Zones.
Definition: date.c:64
#define mutt_array_size(x)
Definition: memory.h:36
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.
Definition: string.c:524
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_leap_year_feb()

static int is_leap_year_feb ( struct tm *  tm)
static

Is a given February in a leap year.

Parameters
tmDate to be tested
Return values
trueIt's a leap year

Definition at line 189 of file date.c.

190{
191 if (tm->tm_mon != 1)
192 return 0;
193
194 int y = tm->tm_year + 1900;
195 return ((y & 3) == 0) && (((y % 100) != 0) || ((y % 400) == 0));
196}
+ Here is the caller graph for this function:

◆ mutt_date_local_tz()

int mutt_date_local_tz ( time_t  t)

Calculate the local timezone in seconds east of UTC.

Parameters
tTime to examine
Return values
numSeconds east of UTC

Returns the local timezone in seconds east of UTC for the time t, or for the current time if t is zero.

Definition at line 206 of file date.c.

207{
208 /* Check we haven't overflowed the time (on 32-bit arches) */
209 if ((t == TIME_T_MAX) || (t == TIME_T_MIN))
210 return 0;
211
212 if (t == 0)
213 t = mutt_date_now();
214
215 struct tm tm = mutt_date_gmtime(t);
216 return compute_tz(t, &tm);
217}
static int compute_tz(time_t g, struct tm *utc)
Calculate the number of seconds east of UTC.
Definition: date.c:127
struct tm mutt_date_gmtime(time_t t)
Converts calendar time to a broken-down time structure expressed in UTC timezone.
Definition: date.c:678
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:432
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_date_make_time()

time_t mutt_date_make_time ( struct tm *  t,
bool  local 
)

Convert struct tm to time_t

Parameters
tTime to convert
localShould the local timezone be considered
Return values
numTime in Unix format
TIME_T_MINError

Convert a struct tm to time_t, but don't take the local timezone into account unless "local" is nonzero

Definition at line 229 of file date.c.

230{
231 if (!t)
232 return TIME_T_MIN;
233
234 static const int AccumDaysPerMonth[mutt_array_size(Months)] = {
235 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
236 };
237
238 /* Prevent an integer overflow, with some arbitrary limits. */
239 if (t->tm_year > 10000)
240 return TIME_T_MAX;
241 if (t->tm_year < -10000)
242 return TIME_T_MIN;
243
244 if ((t->tm_mday < 1) || (t->tm_mday > 31))
245 return TIME_T_MIN;
246 if ((t->tm_hour < 0) || (t->tm_hour > 23) || (t->tm_min < 0) ||
247 (t->tm_min > 59) || (t->tm_sec < 0) || (t->tm_sec > 60))
248 {
249 return TIME_T_MIN;
250 }
251 if (t->tm_year > 9999)
252 return TIME_T_MAX;
253
254 /* Compute the number of days since January 1 in the same year */
255 int yday = AccumDaysPerMonth[t->tm_mon % mutt_array_size(Months)];
256
257 /* The leap years are 1972 and every 4. year until 2096,
258 * but this algorithm will fail after year 2099 */
259 yday += t->tm_mday;
260 if ((t->tm_year % 4) || (t->tm_mon < 2))
261 yday--;
262 t->tm_yday = yday;
263
264 time_t g = yday;
265
266 /* Compute the number of days since January 1, 1970 */
267 g += (t->tm_year - 70) * (time_t) 365;
268 g += (t->tm_year - 69) / 4;
269
270 /* Compute the number of hours */
271 g *= 24;
272 g += t->tm_hour;
273
274 /* Compute the number of minutes */
275 g *= 60;
276 g += t->tm_min;
277
278 /* Compute the number of seconds */
279 g *= 60;
280 g += t->tm_sec;
281
282 if (local)
283 g -= compute_tz(g, t);
284
285 return g;
286}
static const char *const Months[]
Months of the year (abbreviated)
Definition: date.c:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_date_normalize_time()

void mutt_date_normalize_time ( struct tm *  tm)

Fix the contents of a struct tm.

Parameters
tmTime to correct

If values have been added/subtracted from a struct tm, it can lead to invalid dates, e.g. Adding 10 days to the 25th of a month.

This function will correct any over/under-flow.

Definition at line 297 of file date.c.

298{
299 if (!tm)
300 return;
301
302 static const char DaysPerMonth[mutt_array_size(Months)] = {
303 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
304 };
305 int leap;
306
307 while (tm->tm_sec < 0)
308 {
309 tm->tm_sec += 60;
310 tm->tm_min--;
311 }
312 while (tm->tm_sec >= 60)
313 {
314 tm->tm_sec -= 60;
315 tm->tm_min++;
316 }
317 while (tm->tm_min < 0)
318 {
319 tm->tm_min += 60;
320 tm->tm_hour--;
321 }
322 while (tm->tm_min >= 60)
323 {
324 tm->tm_min -= 60;
325 tm->tm_hour++;
326 }
327 while (tm->tm_hour < 0)
328 {
329 tm->tm_hour += 24;
330 tm->tm_mday--;
331 }
332 while (tm->tm_hour >= 24)
333 {
334 tm->tm_hour -= 24;
335 tm->tm_mday++;
336 }
337 /* use loops on NNNdwmy user input values? */
338 while (tm->tm_mon < 0)
339 {
340 tm->tm_mon += 12;
341 tm->tm_year--;
342 }
343 while (tm->tm_mon >= 12)
344 {
345 tm->tm_mon -= 12;
346 tm->tm_year++;
347 }
348 while (tm->tm_mday <= 0)
349 {
350 if (tm->tm_mon)
351 {
352 tm->tm_mon--;
353 }
354 else
355 {
356 tm->tm_mon = 11;
357 tm->tm_year--;
358 }
359 tm->tm_mday += DaysPerMonth[tm->tm_mon] + is_leap_year_feb(tm);
360 }
361 while (tm->tm_mday > (DaysPerMonth[tm->tm_mon] + (leap = is_leap_year_feb(tm))))
362 {
363 tm->tm_mday -= DaysPerMonth[tm->tm_mon] + leap;
364 if (tm->tm_mon < 11)
365 {
366 tm->tm_mon++;
367 }
368 else
369 {
370 tm->tm_mon = 0;
371 tm->tm_year++;
372 }
373 }
374}
static int is_leap_year_feb(struct tm *tm)
Is a given February in a leap year.
Definition: date.c:189
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_date_make_date()

void mutt_date_make_date ( struct Buffer buf,
bool  local 
)

Write a date in RFC822 format to a buffer.

Parameters
bufBuffer for result
localIf true, use the local timezone. Otherwise use UTC.

Appends the date to the passed in buffer. The buffer is not cleared because some callers prepend quotes.

Definition at line 384 of file date.c.

385{
386 if (!buf)
387 return;
388
389 struct tm tm;
390 int tz = 0;
391
392 time_t t = mutt_date_now();
393 if (local)
394 {
395 tm = mutt_date_localtime(t);
396 tz = mutt_date_local_tz(t);
397 }
398 else
399 {
400 tm = mutt_date_gmtime(t);
401 }
402
403 tz /= 60;
404
405 mutt_buffer_add_printf(buf, "%s, %d %s %d %02d:%02d:%02d %+03d%02d", Weekdays[tm.tm_wday],
406 tm.tm_mday, Months[tm.tm_mon], tm.tm_year + 1900,
407 tm.tm_hour, tm.tm_min, tm.tm_sec, tz / 60, abs(tz) % 60);
408}
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:211
static const char *const Weekdays[]
Day of the week (abbreviated)
Definition: date.c:47
int mutt_date_local_tz(time_t t)
Calculate the local timezone in seconds east of UTC.
Definition: date.c:206
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_date_check_month()

int mutt_date_check_month ( const char *  s)

Is the string a valid month name.

Parameters
sString to check
Return values
numIndex into Months array (0-based)
-1Error
Note
Only the first three characters are checked
The comparison is case insensitive

Definition at line 419 of file date.c.

420{
421 for (int i = 0; i < mutt_array_size(Months); i++)
422 if (mutt_istr_startswith(s, Months[i]))
423 return i;
424
425 return -1; /* error */
426}
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:239
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_date_now()

time_t mutt_date_now ( void  )

Return the number of seconds since the Unix epoch.

Return values
numNumber of seconds since the Unix epoch, or 0 on failure

Definition at line 432 of file date.c.

433{
434 return mutt_date_now_ms() / 1000;
435}
uint64_t mutt_date_now_ms(void)
Return the number of milliseconds since the Unix epoch.
Definition: date.c:441
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_date_now_ms()

uint64_t mutt_date_now_ms ( void  )

Return the number of milliseconds since the Unix epoch.

Return values
msThe number of ms since the Unix epoch, or 0 on failure

Definition at line 441 of file date.c.

442{
443 struct timeval tv = { 0, 0 };
444 gettimeofday(&tv, NULL);
445 /* We assume that gettimeofday doesn't modify its first argument on failure.
446 * We also kind of assume that gettimeofday does not fail. */
447 return (uint64_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
448}
+ Here is the caller graph for this function:

◆ mutt_date_parse_date()

time_t mutt_date_parse_date ( const char *  s,
struct Tz tz_out 
)

Parse a date string in RFC822 format.

Parameters
[in]sString to parse
[out]tz_outPointer to timezone (optional)
Return values
numUnix time in seconds

Parse a date of the form: [ weekday , ] day-of-month month year hour:minute:second [ timezone ]

The 'timezone' field is optional; it defaults to +0000 if missing.

Definition at line 461 of file date.c.

462{
463 if (!s)
464 return -1;
465
466 bool lax = false;
467
468 const regmatch_t *match = mutt_prex_capture(PREX_RFC5322_DATE, s);
469 if (!match)
470 {
472 if (!match)
473 {
474 mutt_debug(LL_DEBUG1, "Could not parse date: <%s>\n", s);
475 return -1;
476 }
477 lax = true;
478 mutt_debug(LL_DEBUG2, "Fallback regex for date: <%s>\n", s);
479 }
480
481 struct tm tm = { 0 };
482
483 // clang-format off
484 const regmatch_t *mday = &match[lax ? PREX_RFC5322_DATE_LAX_MATCH_DAY : PREX_RFC5322_DATE_MATCH_DAY];
485 const regmatch_t *mmonth = &match[lax ? PREX_RFC5322_DATE_LAX_MATCH_MONTH : PREX_RFC5322_DATE_MATCH_MONTH];
486 const regmatch_t *myear = &match[lax ? PREX_RFC5322_DATE_LAX_MATCH_YEAR : PREX_RFC5322_DATE_MATCH_YEAR];
487 const regmatch_t *mhour = &match[lax ? PREX_RFC5322_DATE_LAX_MATCH_HOUR : PREX_RFC5322_DATE_MATCH_HOUR];
488 const regmatch_t *mminute = &match[lax ? PREX_RFC5322_DATE_LAX_MATCH_MINUTE : PREX_RFC5322_DATE_MATCH_MINUTE];
489 const regmatch_t *msecond = &match[lax ? PREX_RFC5322_DATE_LAX_MATCH_SECOND : PREX_RFC5322_DATE_MATCH_SECOND];
490 const regmatch_t *mtz = &match[lax ? PREX_RFC5322_DATE_LAX_MATCH_TZ : PREX_RFC5322_DATE_MATCH_TZ];
491 const regmatch_t *mtzobs = &match[lax ? PREX_RFC5322_DATE_LAX_MATCH_TZ_OBS : PREX_RFC5322_DATE_MATCH_TZ_OBS];
492 // clang-format on
493
494 /* Day */
495 sscanf(s + mutt_regmatch_start(mday), "%d", &tm.tm_mday);
496 if (tm.tm_mday > 31)
497 return -1;
498
499 /* Month */
500 tm.tm_mon = mutt_date_check_month(s + mutt_regmatch_start(mmonth));
501
502 /* Year */
503 sscanf(s + mutt_regmatch_start(myear), "%d", &tm.tm_year);
504 if (tm.tm_year < 50)
505 tm.tm_year += 100;
506 else if (tm.tm_year >= 1900)
507 tm.tm_year -= 1900;
508
509 /* Time */
510 int hour, min, sec = 0;
511 sscanf(s + mutt_regmatch_start(mhour), "%d", &hour);
512 sscanf(s + mutt_regmatch_start(mminute), "%d", &min);
513 if (mutt_regmatch_start(msecond) != -1)
514 sscanf(s + mutt_regmatch_start(msecond), "%d", &sec);
515 if ((hour > 23) || (min > 59) || (sec > 60))
516 return -1;
517 tm.tm_hour = hour;
518 tm.tm_min = min;
519 tm.tm_sec = sec;
520
521 /* Time zone */
522 int zhours = 0;
523 int zminutes = 0;
524 bool zoccident = false;
525 if (mutt_regmatch_start(mtz) != -1)
526 {
527 char direction;
528 sscanf(s + mutt_regmatch_start(mtz), "%c%02d%02d", &direction, &zhours, &zminutes);
529 zoccident = (direction == '-');
530 }
531 else if (mutt_regmatch_start(mtzobs) != -1)
532 {
533 const struct Tz *tz = find_tz(s + mutt_regmatch_start(mtzobs),
534 mutt_regmatch_len(mtzobs));
535 if (tz)
536 {
537 zhours = tz->zhours;
538 zminutes = tz->zminutes;
539 zoccident = tz->zoccident;
540 }
541 }
542
543 if (tz_out)
544 {
545 tz_out->zhours = zhours;
546 tz_out->zminutes = zminutes;
547 tz_out->zoccident = zoccident;
548 }
549
551}
time_t mutt_date_make_time(struct tm *t, bool local)
Convert struct tm to time_t
Definition: date.c:229
int mutt_date_check_month(const char *s)
Is the string a valid month name.
Definition: date.c:419
static const struct Tz * find_tz(const char *s, size_t len)
Look up a timezone.
Definition: date.c:174
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.
Definition: date.c:159
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
@ LL_DEBUG2
Log at debug level 2.
Definition: logging.h:41
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
regmatch_t * mutt_prex_capture(enum Prex which, const char *str)
Match a precompiled regex against a string.
Definition: prex.c:308
@ PREX_RFC5322_DATE_MATCH_TZ_OBS
Tue, 3 Mar 2020 14:32:55[UT]
Definition: prex.h:135
@ PREX_RFC5322_DATE_MATCH_TZ
Tue, 3 Mar 2020 14:32:55 [+0200]
Definition: prex.h:134
@ PREX_RFC5322_DATE_MATCH_SECOND
Tue, 3 Mar 2020 14:32:[55] +0200
Definition: prex.h:132
@ PREX_RFC5322_DATE_MATCH_YEAR
Tue, 3 Mar [2020] 14:32:55 +0200
Definition: prex.h:128
@ PREX_RFC5322_DATE_MATCH_HOUR
Tue, 3 Mar 2020 [14]:32:55 +0200
Definition: prex.h:129
@ PREX_RFC5322_DATE_MATCH_DAY
Tue, [3] Mar 2020 14:32:55 +0200
Definition: prex.h:126
@ PREX_RFC5322_DATE_MATCH_MINUTE
Tue, 3 Mar 2020 14:[32]:55 +0200
Definition: prex.h:130
@ PREX_RFC5322_DATE_MATCH_MONTH
Tue, 3 [Jan] 2020 14:32:55 +0200
Definition: prex.h:127
@ PREX_RFC5322_DATE
[Mon, 16 Mar 2020 15:09:35 -0700]
Definition: prex.h:37
@ PREX_RFC5322_DATE_LAX
[Mon, (Comment) 16 Mar 2020 15:09:35 -0700]
Definition: prex.h:38
@ PREX_RFC5322_DATE_LAX_MATCH_SECOND
Tue, 3 Mar 2020 14:32:[55] +0200
Definition: prex.h:169
@ PREX_RFC5322_DATE_LAX_MATCH_TZ
Tue, 3 Mar 2020 14:32:55 [+0200]
Definition: prex.h:172
@ PREX_RFC5322_DATE_LAX_MATCH_YEAR
Tue, 3 Mar [2020] 14:32:55 +0200
Definition: prex.h:161
@ PREX_RFC5322_DATE_LAX_MATCH_HOUR
Tue, 3 Mar 2020 [14]:32:55 +0200
Definition: prex.h:163
@ PREX_RFC5322_DATE_LAX_MATCH_MINUTE
Tue, 3 Mar 2020 14:[32]:55 +0200
Definition: prex.h:165
@ PREX_RFC5322_DATE_LAX_MATCH_TZ_OBS
Tue, 3 Mar 2020 14:32:55[UT]
Definition: prex.h:173
@ PREX_RFC5322_DATE_LAX_MATCH_MONTH
Tue, 3 [Jan] 2020 14:32:55 +0200
Definition: prex.h:159
@ PREX_RFC5322_DATE_LAX_MATCH_DAY
Tue, [3] Mar 2020 14:32:55 +0200
Definition: prex.h:157
static size_t mutt_regmatch_len(const regmatch_t *match)
Return the length of a match.
Definition: regex3.h:80
static regoff_t mutt_regmatch_start(const regmatch_t *match)
Return the start of a match.
Definition: regex3.h:60
List of recognised Timezones.
Definition: date.h:43
unsigned char zminutes
Minutes away from UTC.
Definition: date.h:46
bool zoccident
True if west of UTC, False if East.
Definition: date.h:47
unsigned char zhours
Hours away from UTC.
Definition: date.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_date_make_imap()

int mutt_date_make_imap ( char *  buf,
size_t  buflen,
time_t  timestamp 
)

Format date in IMAP style: DD-MMM-YYYY HH:MM:SS +ZZzz.

Parameters
bufBuffer to store the results
buflenLength of buffer
timestampTime to format
Return values
numCharacters written to buf

Caller should provide a buffer of at least 27 bytes.

Definition at line 562 of file date.c.

563{
564 if (!buf)
565 return -1;
566
567 struct tm tm = mutt_date_localtime(timestamp);
569
570 tz /= 60;
571
572 return snprintf(buf, buflen, "%02d-%s-%d %02d:%02d:%02d %+03d%02d",
573 tm.tm_mday, Months[tm.tm_mon], tm.tm_year + 1900, tm.tm_hour,
574 tm.tm_min, tm.tm_sec, tz / 60, abs(tz) % 60);
575}
static const char * timestamp(time_t stamp)
Create a YYYY-MM-DD HH:MM:SS timestamp.
Definition: logging.c:77
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_date_make_tls()

int mutt_date_make_tls ( char *  buf,
size_t  buflen,
time_t  timestamp 
)

Format date in TLS certificate verification style.

Parameters
bufBuffer to store the results
buflenLength of buffer
timestampTime to format
Return values
numCharacters written to buf

e.g., Mar 17 16:40:46 2016 UTC. The time is always in UTC.

Caller should provide a buffer of at least 27 bytes.

Definition at line 588 of file date.c.

589{
590 if (!buf)
591 return -1;
592
593 struct tm tm = mutt_date_gmtime(timestamp);
594 return snprintf(buf, buflen, "%s, %d %s %d %02d:%02d:%02d UTC",
595 Weekdays[tm.tm_wday], tm.tm_mday, Months[tm.tm_mon],
596 tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec);
597}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_date_parse_imap()

time_t mutt_date_parse_imap ( const char *  s)

Parse date of the form: DD-MMM-YYYY HH:MM:SS +ZZzz.

Parameters
sDate in string form
Return values
numUnix time
0Error

Definition at line 605 of file date.c.

606{
607 const regmatch_t *match = mutt_prex_capture(PREX_IMAP_DATE, s);
608 if (!match)
609 return 0;
610
611 const regmatch_t *mday = &match[PREX_IMAP_DATE_MATCH_DAY];
612 const regmatch_t *mmonth = &match[PREX_IMAP_DATE_MATCH_MONTH];
613 const regmatch_t *myear = &match[PREX_IMAP_DATE_MATCH_YEAR];
614 const regmatch_t *mtime = &match[PREX_IMAP_DATE_MATCH_TIME];
615 const regmatch_t *mtz = &match[PREX_IMAP_DATE_MATCH_TZ];
616
617 struct tm tm;
618
619 sscanf(s + mutt_regmatch_start(mday), " %d", &tm.tm_mday);
620 tm.tm_mon = mutt_date_check_month(s + mutt_regmatch_start(mmonth));
621 sscanf(s + mutt_regmatch_start(myear), "%d", &tm.tm_year);
622 tm.tm_year -= 1900;
623 sscanf(s + mutt_regmatch_start(mtime), "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
624
625 char direction;
626 int zhours, zminutes;
627 sscanf(s + mutt_regmatch_start(mtz), "%c%02d%02d", &direction, &zhours, &zminutes);
628 bool zoccident = (direction == '-');
629
630 return add_tz_offset(mutt_date_make_time(&tm, false), zoccident, zhours, zminutes);
631}
@ PREX_IMAP_DATE_MATCH_TIME
15-MAR-2020 [15:09:35] -0700
Definition: prex.h:190
@ PREX_IMAP_DATE_MATCH_YEAR
15-MAR-[2020] 15:09:35 -0700
Definition: prex.h:189
@ PREX_IMAP_DATE_MATCH_DAY
[ 4]-MAR-2020 15:09:35 -0700
Definition: prex.h:185
@ PREX_IMAP_DATE_MATCH_TZ
15-MAR-2020 15:09:35 [-0700]
Definition: prex.h:191
@ PREX_IMAP_DATE_MATCH_MONTH
15-[MAR]-2020 15:09:35 -0700
Definition: prex.h:188
@ PREX_IMAP_DATE
[16-MAR-2020 15:09:35 -0700]
Definition: prex.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_date_add_timeout()

time_t mutt_date_add_timeout ( time_t  now,
time_t  timeout 
)

Safely add a timeout to a given time_t value.

Parameters
nowTime now
timeoutTimeout in seconds
Return values
numUnix time to timeout

This will truncate instead of overflowing.

Definition at line 641 of file date.c.

642{
643 if (timeout < 0)
644 return now;
645
646 if ((TIME_T_MAX - now) < timeout)
647 return TIME_T_MAX;
648
649 return now + timeout;
650}
+ Here is the caller graph for this function:

◆ mutt_date_localtime()

struct tm mutt_date_localtime ( time_t  t)

Converts calendar time to a broken-down time structure expressed in user timezone.

Parameters
tTime
Return values
objBroken-down time representation

Definition at line 657 of file date.c.

658{
659 struct tm tm = { 0 };
660
661 struct tm *ret = localtime_r(&t, &tm);
662 if (!ret)
663 {
664 mutt_debug(LL_DEBUG1, "Could not convert time_t via localtime_r() to struct tm: time_t = %jd\n",
665 (intmax_t) t);
666 struct tm default_tm = { 0 }; // 1970-01-01 00:00:00
667 mktime(&default_tm); // update derived fields making tm into a valid tm.
668 tm = default_tm;
669 }
670 return tm;
671}
+ Here is the caller graph for this function:

◆ mutt_date_gmtime()

struct tm mutt_date_gmtime ( time_t  t)

Converts calendar time to a broken-down time structure expressed in UTC timezone.

Parameters
tTime
Return values
objBroken-down time representation

Definition at line 678 of file date.c.

679{
680 struct tm tm = { 0 };
681
682 struct tm *ret = gmtime_r(&t, &tm);
683 if (!ret)
684 {
685 mutt_debug(LL_DEBUG1, "Could not convert time_t via gmtime_r() to struct tm: time_t = %jd\n",
686 (intmax_t) t);
687 struct tm default_tm = { 0 }; // 1970-01-01 00:00:00
688 mktime(&default_tm); // update derived fields making tm into a valid tm.
689 tm = default_tm;
690 }
691 return tm;
692}
+ Here is the caller graph for this function:

◆ mutt_date_localtime_format()

size_t mutt_date_localtime_format ( char *  buf,
size_t  buflen,
const char *  format,
time_t  t 
)

Format localtime.

Parameters
bufBuffer to store formatted time
buflenBuffer size
formatFormat to apply
tTime to format
Return values
numNumber of Bytes added to buffer, excluding NUL byte

Definition at line 702 of file date.c.

703{
704 if (!buf || !format)
705 return 0;
706
707 struct tm tm = mutt_date_localtime(t);
708 return strftime(buf, buflen, format, &tm);
709}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_date_sleep_ms()

void mutt_date_sleep_ms ( size_t  ms)

Sleep for milliseconds.

Parameters
msNumber of milliseconds to sleep

Definition at line 715 of file date.c.

716{
717 const struct timespec sleep = {
718 .tv_sec = ms / 1000,
719 .tv_nsec = (ms % 1000) * 1000000UL,
720 };
721 nanosleep(&sleep, NULL);
722}
Time value with nanosecond precision.
Definition: file.h:50
time_t tv_sec
Number of seconds since the epoch.
Definition: file.h:51
+ Here is the caller graph for this function:

Variable Documentation

◆ Weekdays

const char* const Weekdays[]
static
Initial value:
= {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
}

Day of the week (abbreviated)

Definition at line 47 of file date.c.

◆ Months

const char* const Months[]
static
Initial value:
= {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
}

Months of the year (abbreviated)

Definition at line 54 of file date.c.

◆ TimeZones

const struct Tz TimeZones[]
static

Lookup table of Time Zones.

Note
Keep in alphabetical order

Definition at line 64 of file date.c.