#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"
Go to the source code of this file.
|
static time_t | 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 Tz * | find_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...
|
|
time_t | 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) |
| 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_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...
|
|
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...
|
|
Time and date handling routines
- Authors
-
- Copyright
- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.
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.
◆ compute_tz()
static time_t compute_tz |
( |
time_t |
g, |
|
|
struct tm * |
utc |
|
) |
| |
|
static |
Calculate the number of seconds east of UTC.
- Parameters
-
- Return values
-
returns the seconds east of UTC given 'g' and its corresponding gmtime() representation
Definition at line 127 of file date.c.
131 time_t t = (((lt.tm_hour - utc->tm_hour) * 60) + (lt.tm_min - utc->tm_min)) * 60;
133 int yday = (lt.tm_yday - utc->tm_yday);
◆ 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
-
t | UTC time |
w | True if west of UTC, false if east |
h | Number of hours in the timezone |
m | Number of minutes in the timezone |
- Return values
-
Timezone | offset in seconds |
Definition at line 159 of file date.c.
162 return t + (w ? 1 : -1) * (((time_t) h * 3600) + ((time_t) m * 60));
◆ find_tz()
static const struct Tz* find_tz |
( |
const char * |
s, |
|
|
size_t |
len |
|
) |
| |
|
static |
Look up a timezone.
- Parameters
-
s | Timezone to lookup |
len | Length of the s string |
- Return values
-
ptr | Pointer to the Tz struct |
NULL | Not found |
Definition at line 174 of file date.c.
◆ is_leap_year_feb()
static int is_leap_year_feb |
( |
struct tm * |
tm | ) |
|
|
static |
Is a given February in a leap year.
- Parameters
-
- Return values
-
Definition at line 189 of file date.c.
194 int y = tm->tm_year + 1900;
195 return ((y & 3) == 0) && (((y % 100) != 0) || ((y % 400) == 0));
◆ mutt_date_local_tz()
time_t mutt_date_local_tz |
( |
time_t |
t | ) |
|
Calculate the local timezone in seconds east of UTC.
- Parameters
-
- Return values
-
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.
◆ mutt_date_make_time()
time_t mutt_date_make_time |
( |
struct tm * |
t, |
|
|
bool |
local |
|
) |
| |
Convert struct tm
to time_t
- Parameters
-
t | Time to convert |
local | Should the local timezone be considered |
- Return values
-
num | Time in Unix format |
TIME_T_MIN | Error |
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.
235 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
239 if (t->tm_year > 10000)
241 if (t->tm_year < -10000)
244 if ((t->tm_mday < 1) || (t->tm_mday > 31))
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))
251 if (t->tm_year > 9999)
260 if ((t->tm_year % 4) || (t->tm_mon < 2))
265 g += (t->tm_year - 70) * (time_t) 365;
266 g += (t->tm_year - 69) / 4;
◆ mutt_date_normalize_time()
void mutt_date_normalize_time |
( |
struct tm * |
tm | ) |
|
Fix the contents of a struct tm.
- Parameters
-
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.
301 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
305 while (tm->tm_sec < 0)
310 while (tm->tm_sec >= 60)
315 while (tm->tm_min < 0)
320 while (tm->tm_min >= 60)
325 while (tm->tm_hour < 0)
330 while (tm->tm_hour >= 24)
336 while (tm->tm_mon < 0)
341 while (tm->tm_mon >= 12)
346 while (tm->tm_mday <= 0)
357 while (tm->tm_mday > (DaysPerMonth[tm->tm_mon] + (leap =
is_leap_year_feb(tm))))
359 tm->tm_mday -= DaysPerMonth[tm->tm_mon] + leap;
◆ mutt_date_make_date()
void mutt_date_make_date |
( |
struct Buffer * |
buf | ) |
|
Write a date in RFC822 format to a buffer.
- Parameters
-
Appends the date to the passed in buffer. The buffer is not cleared because some callers prepend quotes.
Definition at line 377 of file date.c.
390 tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec,
391 (
int) tz / 60, (
int) abs((
int) tz) % 60);
◆ mutt_date_check_month()
int mutt_date_check_month |
( |
const char * |
s | ) |
|
Is the string a valid month name.
- Parameters
-
- Return values
-
num | Index into Months array (0-based) |
-1 | Error |
- Note
- Only the first three characters are checked
-
The comparison is case insensitive
Definition at line 403 of file date.c.
◆ mutt_date_epoch()
time_t mutt_date_epoch |
( |
void |
| ) |
|
Return the number of seconds since the Unix epoch.
- Return values
-
s | The number of s since the Unix epoch, or 0 on failure |
Definition at line 416 of file date.c.
◆ mutt_date_epoch_ms()
uint64_t mutt_date_epoch_ms |
( |
void |
| ) |
|
Return the number of milliseconds since the Unix epoch.
- Return values
-
ms | The number of ms since the Unix epoch, or 0 on failure |
Definition at line 425 of file date.c.
427 struct timeval tv = { 0, 0 };
428 gettimeofday(&tv, NULL);
431 return (uint64_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
◆ 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] | s | String to parse |
[out] | tz_out | Pointer to timezone (optional) |
- Return values
-
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 445 of file date.c.
465 struct tm tm = { 0 };
490 else if (tm.tm_year >= 1900)
494 int hour, min, sec = 0;
499 if ((hour > 23) || (min > 59) || (sec > 60))
508 bool zoccident =
false;
513 zoccident = (direction ==
'-');
517 const struct Tz *tz =
◆ 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
-
buf | Buffer to store the results |
buflen | Length of buffer |
timestamp | Time to format |
- Return values
-
num | Characters written to buf |
Caller should provide a buffer of at least 27 bytes.
Definition at line 546 of file date.c.
556 return snprintf(buf, buflen,
"%02d-%s-%d %02d:%02d:%02d %+03d%02d",
557 tm.tm_mday,
Months[tm.tm_mon], tm.tm_year + 1900, tm.tm_hour,
558 tm.tm_min, tm.tm_sec, (
int) tz / 60, (
int) abs((
int) tz) % 60);
◆ 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
-
buf | Buffer to store the results |
buflen | Length of buffer |
timestamp | Time to format |
- Return values
-
num | Characters 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 572 of file date.c.
578 return snprintf(buf, buflen,
"%s, %d %s %d %02d:%02d:%02d UTC",
580 tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec);
◆ 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
-
- Return values
-
Definition at line 589 of file date.c.
610 int zhours, zminutes;
612 bool zoccident = (direction ==
'-');
◆ 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
-
now | Time now |
timeout | Timeout in seconds |
- Return values
-
This will truncate instead of overflowing.
Definition at line 625 of file date.c.
633 return now + timeout;
◆ 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
-
- Return values
-
obj | Broken-down time representation |
Uses current time if t is MUTT_DATE_NOW
Definition at line 643 of file date.c.
645 struct tm tm = { 0 };
650 localtime_r(&t, &tm);
◆ 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
-
- Return values
-
obj | Broken-down time representation |
Uses current time if t is MUTT_DATE_NOW
Definition at line 661 of file date.c.
663 struct tm tm = { 0 };
◆ mutt_date_localtime_format()
size_t mutt_date_localtime_format |
( |
char * |
buf, |
|
|
size_t |
buflen, |
|
|
const char * |
format, |
|
|
time_t |
t |
|
) |
| |
Format localtime.
- Parameters
-
buf | Buffer to store formatted time |
buflen | Buffer size |
format | Format to apply |
t | Time to format |
- Return values
-
num | Number of Bytes added to buffer, excluding null byte. |
Definition at line 680 of file date.c.
686 return strftime(buf, buflen, format, &tm);
◆ mutt_date_sleep_ms()
void mutt_date_sleep_ms |
( |
size_t |
ms | ) |
|
Sleep for milliseconds.
- Parameters
-
ms | Number of milliseconds to sleep |
Definition at line 693 of file date.c.
697 .tv_nsec = (ms % 1000) * 1000000UL,
699 nanosleep(&sleep, NULL);
◆ Weekdays
const char* const Weekdays[] |
|
static |
Initial value:= {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
}
Day of the week (abbreviated)
Definition at line 48 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 55 of file date.c.
◆ TimeZones
const struct Tz TimeZones[] |
|
static |
Lookup table of Time Zones.
- Note
- Keep in alphabetical order
Definition at line 65 of file date.c.
@ PREX_RFC5322_DATE_MATCH_SECOND
Tue, 3 Mar 2020 14:32:[55] +0200
@ PREX_RFC5322_DATE_MATCH_TZ
Tue, 3 Mar 2020 14:32:55 [+0200]
uint64_t mutt_date_epoch_ms(void)
Return the number of milliseconds since the Unix epoch.
@ PREX_RFC5322_DATE_MATCH_MINUTE
Tue, 3 Mar 2020 14:[32]:55 +0200
@ PREX_RFC5322_DATE_MATCH_TZ_OBS
Tue, 3 Mar 2020 14:32:55[UT]
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
@ LL_DEBUG1
Log at debug level 1.
@ PREX_RFC5322_DATE_MATCH_YEAR
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
[Mon, (Comment) 16 Mar 2020 15:09:35 -0700]
@ PREX_RFC5322_DATE_LAX_MATCH_TZ
Tue, 3 Mar 2020 14:32:55 [+0200]
@ PREX_RFC5322_DATE_MATCH_HOUR
Tue, 3 Mar 2020 [14]:32:55 +0200
@ PREX_RFC5322_DATE_LAX_MATCH_SECOND
Tue, 3 Mar 2020 14:32:[55] +0200
@ PREX_RFC5322_DATE_MATCH_DAY
Tue, [3] Mar 2020 14:32:55 +0200
#define mutt_array_size(x)
@ PREX_IMAP_DATE_MATCH_DAY
[ 4]-MAR-2020 15:09:35 -0700
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 *const Months[]
Months of the year (abbreviated)
static const char *const Weekdays[]
Day of the week (abbreviated)
static const char * timestamp(time_t stamp)
Create a YYYY-MM-DD HH:MM:SS timestamp.
@ PREX_IMAP_DATE_MATCH_TZ
15-MAR-2020 15:09:35 [-0700]
unsigned char zhours
Hours away from UTC.
static const struct Tz * find_tz(const char *s, size_t len)
Look up a timezone.
time_t mutt_date_make_time(struct tm *t, bool local)
Convert struct tm to time_t
static const struct Tz TimeZones[]
Lookup table of Time Zones.
static regoff_t mutt_regmatch_start(const regmatch_t *match)
Return the start of a match.
int mutt_date_check_month(const char *s)
Is the string a valid month name.
@ PREX_RFC5322_DATE_LAX_MATCH_YEAR
Tue, 3 Mar [2020] 14:32:55 +0200
static size_t mutt_regmatch_len(const regmatch_t *match)
Return the length of a match.
struct tm mutt_date_localtime(time_t t)
Converts calendar time to a broken-down time structure expressed in user timezone.
time_t mutt_date_local_tz(time_t t)
Calculate the local timezone in seconds east of UTC.
@ PREX_RFC5322_DATE
[Mon, 16 Mar 2020 15:09:35 -0700]
@ PREX_IMAP_DATE_MATCH_TIME
15-MAR-2020 [15:09:35] -0700
#define mutt_debug(LEVEL,...)
static int is_leap_year_feb(struct tm *tm)
Is a given February in a leap year.
@ PREX_IMAP_DATE_MATCH_YEAR
15-MAR-[2020] 15:09:35 -0700
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
#define MUTT_DATE_NOW
Constant representing the 'current time', see: mutt_date_gmtime(), mutt_date_localtime()
@ PREX_RFC5322_DATE_MATCH_MONTH
Tue, 3 [Jan] 2020 14:32:55 +0200
@ PREX_RFC5322_DATE_LAX_MATCH_HOUR
Tue, 3 Mar 2020 [14]:32:55 +0200
unsigned char zminutes
Minutes away from UTC.
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
struct tm mutt_date_gmtime(time_t t)
Converts calendar time to a broken-down time structure expressed in UTC timezone.
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.
static time_t compute_tz(time_t g, struct tm *utc)
Calculate the number of seconds east of UTC.
Time value with nanosecond precision.
@ PREX_RFC5322_DATE_LAX_MATCH_MONTH
Tue, 3 [Jan] 2020 14:32:55 +0200
List of recognised Timezones.
@ PREX_RFC5322_DATE_LAX_MATCH_TZ_OBS
Tue, 3 Mar 2020 14:32:55[UT]
@ PREX_IMAP_DATE
[16-MAR-2020 15:09:35 -0700]
bool zoccident
True if west of UTC, False if East.
@ PREX_IMAP_DATE_MATCH_MONTH
15-[MAR]-2020 15:09:35 -0700
@ LL_DEBUG2
Log at debug level 2.
@ PREX_RFC5322_DATE_LAX_MATCH_DAY
Tue, [3] Mar 2020 14:32:55 +0200
regmatch_t * mutt_prex_capture(enum Prex which, const char *str)