[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: human-time?
From: |
Simon Josefsson |
Subject: |
Re: human-time? |
Date: |
Thu, 10 Jan 2008 18:26:05 +0100 |
User-agent: |
Gnus/5.110007 (No Gnus v0.7) Emacs/22.1 (gnu/linux) |
Below is code as a starting point, the self-tests produces:
7 weeks 5 days 12 hours 44 minutes 31 seconds
7 weeks 5 days 12 hours 44 minutes 1 second
7 weeks 5 days 12 hours 1 minute 11 seconds
7 weeks 5 days 1 hour 44 minutes 31 seconds
7 weeks 1 day 12 hours 44 minutes 31 seconds
1 week 5 days 12 hours 44 minutes 31 seconds
1 week 1 day 1 hour 1 minute 1 second
Which seems OK. The self test should strcmp these strings instead of
printing them, but right now printing is more useful.
I know the code can be cleaned up, and comments added, but right now I'm
mostly looking for comments on the general approach and on the function
prototype:
char *
human_readable_time (time_t age, unsigned int units)
I'd prefer if the module didn't use xvasprintf because I probably want
to use this in a library, and x* doesn't work well there (and there are
license problems too).
If we don't worry about translations, the largest string for one unit
would be '%d minutes', so we could put the output string in a buffer and
require the caller to allocate sufficient large buffer. What do you
think? Something like this:
char *
human_readable_time (time_t age, unsigned int units,
char *buf, size_t bufsiz);
Or possibly, to be able to find out the total length:
size_t
human_readable_time (time_t age, unsigned int units,
char *buf, size_t bufsiz);
this one would return the size of the string, regardless of whether that
fitted in the buf+bufsiz buffer.
The last one could be OK even if we allow translated strings. However,
we could also do it like:
char *
human_readable_time (time_t age, unsigned int units);
and allow the function to return NULL on memory allocation errors (and
errno would be set). Maybe this is cleaner, I find that functions that
use fixed-size buffers are difficult to use. And there are no
performance issues to consider here, I think, so the cost of memory
allocation should be irrelevant.
Hm. I just realized the function doesn't do rounding properly. So if
only one unit is requested, and the time is '7 weeks 6 days' the
function would return '7 weeks' rather than the expected '8 weeks'.
Also, there is the problem of how long a month and a year is, it isn't
really well-defined. This is mostly relevant if you use full precision,
otherwise the string is just an approximation anyway.
Thoughts?
/Simon
/* Test printing of human time distances.
Copyright (C) 2008 Free Software Foundation, Inc.
Written by Simon Josefsson.
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/>. */
#include <config.h>
#include "human-time.h"
#include <stdlib.h>
#include <stdio.h>
int
main (int ac, char *av[])
{
char *s;
s = human_readable_time (4711471, 99);
puts (s);
free (s);
s = human_readable_time (4711441, 99);
puts (s);
free (s);
s = human_readable_time (4708871, 99);
puts (s);
free (s);
s = human_readable_time (4671871, 99);
puts (s);
free (s);
s = human_readable_time (4365871, 99);
puts (s);
free (s);
s = human_readable_time (1082671, 99);
puts (s);
free (s);
s = human_readable_time (694861, 99);
puts (s);
free (s);
return 0;
}
/* human-time.h -- human readable time distance conversion
Copyright (C) 2008 Free Software Foundation, Inc.
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/>. */
/* Written by Simon Josefsson. */
#ifndef HUMAN_TIME_H_
# define HUMAN_TIME_H_ 1
#include <time.h>
char *human_readable_time (time_t age, unsigned int units);
#endif /* HUMAN_H_ */
/* human-time.h -- human readable time distance conversion
Copyright (C) 2008 Free Software Foundation, Inc.
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/>. */
/* Written by Simon Josefsson. */
#include <config.h>
#include "human-time.h"
#include <stdlib.h>
#include <xvasprintf.h>
char *
human_readable_time (time_t age, unsigned int units)
{
char *str;
if (age == 1)
return xasprintf ("1 second");
else if (age < 60)
return xasprintf ("%d seconds", age);
else if (age < 2 * 60)
str = xasprintf ("1 minute"), age -= 60;
else if (age < 60 * 60)
str = xasprintf ("%d minutes", age / 60), age -= 60 * (age / 60);
else if (age < 2 * 60 * 60)
str = xasprintf ("1 hour"), age -= 60 * 60;
else if (age < 24 * 60 * 60)
str = xasprintf ("%d hours", age / 60 / 60),
age -= 60 * 60 * (age / 60 / 60);
else if (age < 2 * 24 * 60 * 60)
str = xasprintf ("1 day"), age -= 24 * 60 * 60;
else if (age < 7 * 24 * 60 * 60)
str = xasprintf ("%d days", age / 24 / 60 / 60),
age -= 24 * 60 * 60 * (age / 60 / 60 / 24);
else if (age < 2 * 7 * 24 * 60 * 60)
str = xasprintf ("1 week"), age -= 7 * 24 * 60 * 60;
else
str = xasprintf ("%d weeks", age / 7 / 24 / 60 / 60),
age -= 7 * 24 * 60 * 60 * (age / 60 / 60 / 24 / 7);
if (units > 0 && age > 0)
{
char *next;
char *whole;
next = human_readable_time (age, units - 1);
whole = xasprintf ("%s %s", str, next);
free (str);
free (next);
str = whole;
}
return str;
}
Description:
Convert a time distance to a human readable string.
Files:
lib/human-time.h
lib/human-time.c
m4/human-time.m4
Depends-on:
xvasprintf
configure.ac:
gl_HUMAN_TIME
Makefile.am:
Include:
"human_time.h"
License:
LGPLv2+
Maintainer:
Simon Josefsson
Files:
tests/test-human-time.c
Depends-on:
configure.ac:
Makefile.am:
TESTS += test-human-time
check_PROGRAMS += test-human-time
License:
LGPLv2+
#serial 1
dnl Copyright (C) 2008 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_HUMAN_TIME],
[
AC_LIBOBJ([human-time])
dnl Prerequisites of lib/human-time.c.
:
])
- Proposed module, releasedate, James Youngman, 2008/01/09
- Re: Proposed module, releasedate, Bruno Haible, 2008/01/09
- Re: Proposed module, releasedate, James Youngman, 2008/01/10
- human-time? (was: Re: Proposed module, releasedate), Simon Josefsson, 2008/01/10
- Re: human-time?, Bruno Haible, 2008/01/10
- Re: human-time?, Simon Josefsson, 2008/01/10
- Re: human-time?,
Simon Josefsson <=
- Re: human-time?, Bruno Haible, 2008/01/10
- Re: human-time?, Paul Eggert, 2008/01/10
- Re: 'make' modification time warning (was: Re: human-time?), Bruno Haible, 2008/01/10
- Re: 'make' modification time warning, Paul Eggert, 2008/01/11
- Re: 'make' modification time warning, Matthew Woehlke, 2008/01/22
- Re: Proposed module, releasedate, Bruno Haible, 2008/01/10