NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
date.h File Reference

Time and date handling routines. More...

#include <stdbool.h>
#include <stdint.h>
#include <time.h>
+ Include dependency graph for date.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Tz
 List of recognised Timezones. More...
 

Macros

#define TIME_T_MAX   ((((time_t) 1 << (sizeof(time_t) * 8 - 2)) - 1) * 2 + 1)
 
#define TIME_T_MIN   (-TIME_T_MAX - 1)
 
#define TM_YEAR_MAX   (1970 + (((((TIME_T_MAX - 59) / 60) - 59) / 60) - 23) / 24 / 366)
 
#define TM_YEAR_MIN   (1970 - (TM_YEAR_MAX - 1970) - 1)
 
#define MUTT_DATE_NOW   -9999
 Constant representing the 'current time', see: mutt_date_gmtime(), mutt_date_localtime() More...
 

Functions

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

Macro Definition Documentation

◆ TIME_T_MAX

#define TIME_T_MAX   ((((time_t) 1 << (sizeof(time_t) * 8 - 2)) - 1) * 2 + 1)

Definition at line 33 of file date.h.

◆ TIME_T_MIN

#define TIME_T_MIN   (-TIME_T_MAX - 1)

Definition at line 34 of file date.h.

◆ TM_YEAR_MAX

#define TM_YEAR_MAX   (1970 + (((((TIME_T_MAX - 59) / 60) - 59) / 60) - 23) / 24 / 366)

Definition at line 35 of file date.h.

◆ TM_YEAR_MIN

#define TM_YEAR_MIN   (1970 - (TM_YEAR_MAX - 1970) - 1)

Definition at line 37 of file date.h.

◆ MUTT_DATE_NOW

#define MUTT_DATE_NOW   -9999

Constant representing the 'current time', see: mutt_date_gmtime(), mutt_date_localtime()

Definition at line 39 of file date.h.

Function Documentation

◆ 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 636 of file date.c.

637 {
638  if (timeout < 0)
639  return now;
640 
641  if ((TIME_T_MAX - now) < timeout)
642  return TIME_T_MAX;
643 
644  return now + timeout;
645 }
#define TIME_T_MAX
Definition: date.h:33
+ 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 414 of file date.c.

415 {
416  for (int i = 0; i < mutt_array_size(Months); i++)
417  if (mutt_istr_startswith(s, Months[i]))
418  return i;
419 
420  return -1; /* error */
421 }
static const char *const Months[]
Months of the year (abbreviated)
Definition: date.c:55
#define mutt_array_size(x)
Definition: memory.h:33
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:172
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_date_epoch()

time_t mutt_date_epoch ( void  )

Return the number of seconds since the Unix epoch.

Return values
sThe number of s since the Unix epoch, or 0 on failure

Definition at line 427 of file date.c.

428 {
429  return mutt_date_epoch_ms() / 1000;
430 }
uint64_t mutt_date_epoch_ms(void)
Return the number of milliseconds since the Unix epoch.
Definition: date.c:436
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_date_epoch_ms()

uint64_t mutt_date_epoch_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 436 of file date.c.

437 {
438  struct timeval tv = { 0, 0 };
439  gettimeofday(&tv, NULL);
440  /* We assume that gettimeofday doesn't modify its first argument on failure.
441  * We also kind of assume that gettimeofday does not fail. */
442  return (uint64_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
443 }
+ 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

Uses current time if t is MUTT_DATE_NOW

Definition at line 672 of file date.c.

673 {
674  struct tm tm = { 0 };
675 
676  if (t == MUTT_DATE_NOW)
677  t = mutt_date_epoch();
678 
679  gmtime_r(&t, &tm);
680  return tm;
681 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:427
#define MUTT_DATE_NOW
Constant representing the &#39;current time&#39;, see: mutt_date_gmtime(), mutt_date_localtime() ...
Definition: date.h:39
+ Here is the call graph for this function:
+ 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 null byte.

Definition at line 691 of file date.c.

692 {
693  if (!buf || !format)
694  return 0;
695 
696  struct tm tm = mutt_date_localtime(t);
697  return strftime(buf, buflen, format, &tm);
698 }
struct tm mutt_date_localtime(time_t t)
Converts calendar time to a broken-down time structure expressed in user timezone.
Definition: date.c:654
+ Here is the call graph for this function:
+ 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

Uses current time if t is MUTT_DATE_NOW

Definition at line 654 of file date.c.

655 {
656  struct tm tm = { 0 };
657 
658  if (t == MUTT_DATE_NOW)
659  t = mutt_date_epoch();
660 
661  localtime_r(&t, &tm);
662  return tm;
663 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:427
#define MUTT_DATE_NOW
Constant representing the &#39;current time&#39;, see: mutt_date_gmtime(), mutt_date_localtime() ...
Definition: date.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_date_local_tz()

time_t 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_epoch();
214 
215  struct tm tm = mutt_date_gmtime(t);
216  return compute_tz(t, &tm);
217 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:427
#define TIME_T_MIN
Definition: date.h:34
#define TIME_T_MAX
Definition: date.h:33
struct tm mutt_date_gmtime(time_t t)
Converts calendar time to a broken-down time structure expressed in UTC timezone. ...
Definition: date.c:672
static time_t compute_tz(time_t g, struct tm *utc)
Calculate the number of seconds east of UTC.
Definition: date.c:127
+ 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 378 of file date.c.

379 {
380  if (!buf)
381  return;
382 
383  struct tm tm;
384  time_t tz = 0;
385 
386  time_t t = mutt_date_epoch();
387  if (local)
388  {
389  tm = mutt_date_localtime(t);
390  tz = mutt_date_local_tz(t);
391  }
392  else
393  {
394  tm = mutt_date_gmtime(t);
395  }
396 
397  tz /= 60;
398 
399  mutt_buffer_add_printf(buf, "%s, %d %s %d %02d:%02d:%02d %+03d%02d",
400  Weekdays[tm.tm_wday], tm.tm_mday, Months[tm.tm_mon],
401  tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec,
402  (int) tz / 60, (int) abs((int) tz) % 60);
403 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:427
struct tm mutt_date_localtime(time_t t)
Converts calendar time to a broken-down time structure expressed in user timezone.
Definition: date.c:654
static const char *const Months[]
Months of the year (abbreviated)
Definition: date.c:55
struct tm mutt_date_gmtime(time_t t)
Converts calendar time to a broken-down time structure expressed in UTC timezone. ...
Definition: date.c:672
time_t mutt_date_local_tz(time_t t)
Calculate the local timezone in seconds east of UTC.
Definition: date.c:206
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:203
static const char *const Weekdays[]
Day of the week (abbreviated)
Definition: date.c:48
+ 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 557 of file date.c.

558 {
559  if (!buf)
560  return -1;
561 
562  struct tm tm = mutt_date_localtime(timestamp);
563  time_t tz = mutt_date_local_tz(timestamp);
564 
565  tz /= 60;
566 
567  return snprintf(buf, buflen, "%02d-%s-%d %02d:%02d:%02d %+03d%02d",
568  tm.tm_mday, Months[tm.tm_mon], tm.tm_year + 1900, tm.tm_hour,
569  tm.tm_min, tm.tm_sec, (int) tz / 60, (int) abs((int) tz) % 60);
570 }
struct tm mutt_date_localtime(time_t t)
Converts calendar time to a broken-down time structure expressed in user timezone.
Definition: date.c:654
static const char *const Months[]
Months of the year (abbreviated)
Definition: date.c:55
static const char * timestamp(time_t stamp)
Create a YYYY-MM-DD HH:MM:SS timestamp.
Definition: logging.c:77
time_t 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_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  time_t g = 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  g += t->tm_mday;
260  if ((t->tm_year % 4) || (t->tm_mon < 2))
261  g--;
262  t->tm_yday = g;
263 
264  /* Compute the number of days since January 1, 1970 */
265  g += (t->tm_year - 70) * (time_t) 365;
266  g += (t->tm_year - 69) / 4;
267 
268  /* Compute the number of hours */
269  g *= 24;
270  g += t->tm_hour;
271 
272  /* Compute the number of minutes */
273  g *= 60;
274  g += t->tm_min;
275 
276  /* Compute the number of seconds */
277  g *= 60;
278  g += t->tm_sec;
279 
280  if (local)
281  g -= compute_tz(g, t);
282 
283  return g;
284 }
#define TIME_T_MIN
Definition: date.h:34
#define TIME_T_MAX
Definition: date.h:33
static const char *const Months[]
Months of the year (abbreviated)
Definition: date.c:55
#define mutt_array_size(x)
Definition: memory.h:33
static time_t compute_tz(time_t g, struct tm *utc)
Calculate the number of seconds east of UTC.
Definition: date.c:127
+ 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 583 of file date.c.

584 {
585  if (!buf)
586  return -1;
587 
588  struct tm tm = mutt_date_gmtime(timestamp);
589  return snprintf(buf, buflen, "%s, %d %s %d %02d:%02d:%02d UTC",
590  Weekdays[tm.tm_wday], tm.tm_mday, Months[tm.tm_mon],
591  tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec);
592 }
static const char *const Months[]
Months of the year (abbreviated)
Definition: date.c:55
static const char * timestamp(time_t stamp)
Create a YYYY-MM-DD HH:MM:SS timestamp.
Definition: logging.c:77
struct tm mutt_date_gmtime(time_t t)
Converts calendar time to a broken-down time structure expressed in UTC timezone. ...
Definition: date.c:672
static const char *const Weekdays[]
Day of the week (abbreviated)
Definition: date.c:48
+ 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 295 of file date.c.

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

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

601 {
602  const regmatch_t *match = mutt_prex_capture(PREX_IMAP_DATE, s);
603  if (!match)
604  return 0;
605 
606  const regmatch_t *mday = &match[PREX_IMAP_DATE_MATCH_DAY];
607  const regmatch_t *mmonth = &match[PREX_IMAP_DATE_MATCH_MONTH];
608  const regmatch_t *myear = &match[PREX_IMAP_DATE_MATCH_YEAR];
609  const regmatch_t *mtime = &match[PREX_IMAP_DATE_MATCH_TIME];
610  const regmatch_t *mtz = &match[PREX_IMAP_DATE_MATCH_TZ];
611 
612  struct tm tm;
613 
614  sscanf(s + mutt_regmatch_start(mday), " %d", &tm.tm_mday);
615  tm.tm_mon = mutt_date_check_month(s + mutt_regmatch_start(mmonth));
616  sscanf(s + mutt_regmatch_start(myear), "%d", &tm.tm_year);
617  tm.tm_year -= 1900;
618  sscanf(s + mutt_regmatch_start(mtime), "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
619 
620  char direction;
621  int zhours, zminutes;
622  sscanf(s + mutt_regmatch_start(mtz), "%c%02d%02d", &direction, &zhours, &zminutes);
623  bool zoccident = (direction == '-');
624 
625  return add_tz_offset(mutt_date_make_time(&tm, false), zoccident, zhours, zminutes);
626 }
[16-MAR-2020 15:09:35 -0700]
Definition: prex.h:39
15-MAR-2020 15:09:35 [-0700]
Definition: prex.h:190
15-MAR-2020 [15:09:35] -0700
Definition: prex.h:189
15-MAR-[2020] 15:09:35 -0700
Definition: prex.h:188
[ 4]-MAR-2020 15:09:35 -0700
Definition: prex.h:184
regmatch_t * mutt_prex_capture(enum Prex which, const char *str)
match a precompiled regex against a string
Definition: prex.c:301
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
static regoff_t mutt_regmatch_start(const regmatch_t *match)
Return the start of a match.
Definition: regex3.h:61
15-[MAR]-2020 15:09:35 -0700
Definition: prex.h:187
int mutt_date_check_month(const char *s)
Is the string a valid month name.
Definition: date.c:414
time_t mutt_date_make_time(struct tm *t, bool local)
Convert struct tm to time_t
Definition: date.c:229
+ 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 704 of file date.c.

705 {
706  const struct timespec sleep = {
707  .tv_sec = ms / 1000,
708  .tv_nsec = (ms % 1000) * 1000000UL,
709  };
710  nanosleep(&sleep, NULL);
711 }
time_t tv_sec
Definition: file.h:50
Time value with nanosecond precision.
Definition: file.h:48
+ Here is the caller graph for this function: