notmuch/notmuch-time.c

138 lines
3.5 KiB
C
Raw Normal View History

/* notmuch - Not much of an email program, (just index and search)
*
* Copyright © 2009 Carl Worth
*
* 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 3 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/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
#include "notmuch-client.h"
/* Format a nice representation of 'time' relative to the current time.
*
* Examples include:
*
* 5 mins. ago (For times less than 60 minutes ago)
* Today 12:30 (For times >60 minutes but still today)
* Yest. 12:30
* Mon. 12:30 (Before yesterday but fewer than 7 days ago)
* October 12 (Between 7 and 180 days ago (about 6 months))
* 2008-06-30 (More than 180 days ago)
*
* The returned string is either static data (a string literal) or
* newly talloced data belonging to 'ctx'. That is, the caller should
* not modify nor free the returned value. But when the caller
* arranges for 'ctx' to be talloc_freed, then memory allocated here
* (if any) will be reclaimed.
*
*/
#define MINUTE (60)
#define HOUR (60 * MINUTE)
#define DAY (24 * HOUR)
#define RELATIVE_DATE_MAX 20
const char *
notmuch_time_relative_date (const void *ctx, time_t then)
{
struct tm tm_now, tm_then;
time_t now = time(NULL);
time_t delta;
char *result;
localtime_r (&now, &tm_now);
localtime_r (&then, &tm_then);
result = talloc_zero_size (ctx, RELATIVE_DATE_MAX);
if (result == NULL)
return "when?";
if (then > now)
return "the future";
delta = now - then;
if (delta > 180 * DAY) {
strftime (result, RELATIVE_DATE_MAX,
"%F", &tm_then); /* 2008-06-30 */
return result;
}
if (delta < 3600) {
snprintf (result, RELATIVE_DATE_MAX,
"%d mins. ago", (int) (delta / 60));
return result;
}
if (delta <= 7 * DAY) {
if (tm_then.tm_wday == tm_now.tm_wday &&
delta < DAY)
{
strftime (result, RELATIVE_DATE_MAX,
"Today %R", &tm_then); /* Today 12:30 */
return result;
} else if ((tm_now.tm_wday + 7 - tm_then.tm_wday) % 7 == 1) {
strftime (result, RELATIVE_DATE_MAX,
"Yest. %R", &tm_then); /* Yest. 12:30 */
return result;
} else {
if (tm_then.tm_wday != tm_now.tm_wday) {
strftime (result, RELATIVE_DATE_MAX,
"%a. %R", &tm_then); /* Mon. 12:30 */
return result;
}
}
}
strftime (result, RELATIVE_DATE_MAX,
"%B %d", &tm_then); /* October 12 */
return result;
}
#undef MINUTE
#undef HOUR
#undef DAY
void
notmuch_time_print_formatted_seconds (double seconds)
{
int hours;
int minutes;
if (seconds < 1) {
printf ("almost no time");
return;
}
if (seconds > 3600) {
hours = (int) seconds / 3600;
printf ("%dh ", hours);
seconds -= hours * 3600;
}
if (seconds > 60) {
minutes = (int) seconds / 60;
printf ("%dm ", minutes);
seconds -= minutes * 60;
}
printf ("%ds", (int) seconds);
}
/* Compute the number of seconds elapsed from start to end. */
double
notmuch_time_elapsed (struct timeval start, struct timeval end)
{
return ((end.tv_sec - start.tv_sec) +
(end.tv_usec - start.tv_usec) / 1e6);
}