commit-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Mailutils branch, master, updated. release-2.2-509-g7efa477


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-509-g7efa477
Date: Thu, 08 Dec 2011 16:47:53 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".

http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=7efa4777bddb68299355dce1f4125533d6467023

The branch, master has been updated
       via  7efa4777bddb68299355dce1f4125533d6467023 (commit)
       via  acec689ef648adaa5c420049bfb775953e184bda (commit)
       via  5af1d3a7bd8149139ad59baa11501e3d11b138a7 (commit)
      from  6301266fabab03f0e1dfcab76e7b6fc1e6eda1c6 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 7efa4777bddb68299355dce1f4125533d6467023
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Dec 8 18:43:21 2011 +0200

    Bugfixes.
    
    * imap4d/append.c: Don't reuse msg variable.
    * po/POTFILES.in: Remove unneeded file.

commit acec689ef648adaa5c420049bfb775953e184bda
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Dec 8 17:04:29 2011 +0200

    Revamp date/time calculations.
    
    * configure.ac: Build libmailutils/datetime/Makefile.am
    * include/mailutils/datetime.h (mu_datetime_julianday)
    (mu_datetime_dayofweek,mu_datetime_dayofyear)
    (mu_datetime_year_days): New protos.
    * libmailutils/Makefile.am (SUBDIRS): Add datetime
    (libmailutils_la_LIBADD): Add libdatetime.la
    * libmailutils/base/Makefile.am (libbase_la_SOURCES): Remove date.c
    and strftime.c.
    * libmailutils/base/date.c: Remove.
    * libmailutils/base/strftime.c: Move to libmailutils/datetime
    * libmailutils/datetime/Makefile.am: New file.
    * libmailutils/datetime/dow.c: New file.
    * libmailutils/datetime/doy.c: New file.
    * libmailutils/datetime/jd.c: New file.
    * libmailutils/datetime/scantime.c: New file.
    * libmailutils/datetime/streamftime.c: New file.
    * libmailutils/datetime/tab.c: New file.
    * libmailutils/datetime/unixtime.c: New file.
    * libmailutils/datetime/utcoff.c: New file.
    * libmailutils/datetime/yd.c: New file.
    * libmailutils/tests/scantime.at: Fix yday numbers.

commit 5af1d3a7bd8149139ad59baa11501e3d11b138a7
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Dec 8 13:20:17 2011 +0200

    Move date/time declarations into a separate header: mailutils/datetime.h
    
    Additionally, do not typedef mu_timezone, leave it in struct namespace.

-----------------------------------------------------------------------

Summary of changes:
 comsat/comsat.h                                    |    1 +
 configure.ac                                       |    1 +
 imap4d/append.c                                    |    8 +-
 imap4d/fetch.c                                     |    2 +-
 imap4d/util.c                                      |    8 +-
 include/mailutils/Makefile.am                      |    1 +
 include/mailutils/datetime.h                       |   85 ++
 include/mailutils/envelope.h                       |    6 -
 include/mailutils/imap.h                           |    2 +-
 include/mailutils/imapio.h                         |    2 +-
 include/mailutils/mailutils.h                      |    1 +
 include/mailutils/parse822.h                       |    4 +-
 include/mailutils/util.h                           |   38 -
 libmailutils/Makefile.am                           |    3 +-
 libmailutils/base/Makefile.am                      |    2 -
 libmailutils/base/amd.c                            |    1 +
 libmailutils/base/date.c                           | 1162 --------------------
 libmailutils/base/msgid.c                          |    1 +
 libmailutils/{cidr => datetime}/Makefile.am        |   19 +-
 libmu_dbm/close.c => libmailutils/datetime/dow.c   |   16 +-
 .../imap/close.c => libmailutils/datetime/doy.c    |   48 +-
 libmu_dbm/close.c => libmailutils/datetime/jd.c    |   19 +-
 libmailutils/datetime/scantime.c                   |  660 +++++++++++
 libmailutils/datetime/streamftime.c                |  411 +++++++
 libmailutils/{base => datetime}/strftime.c         |    2 +-
 libmailutils/{diag/muerror.c => datetime/tab.c}    |   46 +-
 .../muemail.c => libmailutils/datetime/unixtime.c  |   41 +-
 mail/list.c => libmailutils/datetime/utcoff.c      |   24 +-
 libmailutils/{list/push.c => datetime/yd.c}        |   10 +-
 libmailutils/imapio/time.c                         |    2 +-
 libmailutils/mailbox/msgenv.c                      |    7 +-
 libmailutils/stream/message_stream.c               |    9 +-
 libmailutils/tests/scantime.at                     |   58 +-
 libmailutils/tests/scantime.c                      |    4 +-
 libmailutils/tests/strftime.c                      |    2 +-
 libmu_scm/mu_message.c                             |    4 +-
 libmu_scm/mu_scm.h                                 |    1 +
 libmu_sieve/actions.c                              |    2 +-
 libproto/mbox/mbox.c                               |   14 +-
 mail/from.c                                        |    2 +-
 mail/mail.h                                        |    1 +
 mh/mh.h                                            |    1 +
 mh/mh_format.c                                     |   44 +-
 mh/sortm.c                                         |    2 +-
 po/POTFILES.in                                     |    1 -
 readmsg/readmsg.c                                  |    4 +-
 readmsg/readmsg.h                                  |    2 +-
 47 files changed, 1366 insertions(+), 1418 deletions(-)
 create mode 100644 include/mailutils/datetime.h
 delete mode 100644 libmailutils/base/date.c
 copy libmailutils/{cidr => datetime}/Makefile.am (83%)
 copy libmu_dbm/close.c => libmailutils/datetime/dow.c (77%)
 copy libproto/imap/close.c => libmailutils/datetime/doy.c (52%)
 copy libmu_dbm/close.c => libmailutils/datetime/jd.c (76%)
 create mode 100644 libmailutils/datetime/scantime.c
 create mode 100644 libmailutils/datetime/streamftime.c
 rename libmailutils/{base => datetime}/strftime.c (97%)
 copy libmailutils/{diag/muerror.c => datetime/tab.c} (56%)
 copy examples/muemail.c => libmailutils/datetime/unixtime.c (57%)
 copy mail/list.c => libmailutils/datetime/utcoff.c (67%)
 copy libmailutils/{list/push.c => datetime/yd.c} (79%)

diff --git a/comsat/comsat.h b/comsat/comsat.h
index ec9dab8..41efc41 100644
--- a/comsat/comsat.h
+++ b/comsat/comsat.h
@@ -29,6 +29,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <time.h>
 #include <signal.h>
 #include <errno.h>
 #include <termios.h>
diff --git a/configure.ac b/configure.ac
index 62b4409..dfacf09 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1470,6 +1470,7 @@ AC_CONFIG_FILES([
  libmailutils/sockaddr/Makefile
  libmailutils/cidr/Makefile
  libmailutils/cfg/Makefile
+ libmailutils/datetime/Makefile
  libmailutils/diag/Makefile
  libmailutils/filter/Makefile
  libmailutils/imapio/Makefile
diff --git a/imap4d/append.c b/imap4d/append.c
index b8c9198..632333a 100644
--- a/imap4d/append.c
+++ b/imap4d/append.c
@@ -20,7 +20,7 @@
 struct _temp_envelope
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   char *sender;
 };
 
@@ -174,9 +174,11 @@ imap4d_append0 (mu_mailbox_t mbox, int flags, char 
*date_time, char *text,
        {
          size_t num = 0;
          mu_attribute_t attr = NULL;
+         mu_message_t temp;
+         
          mu_mailbox_messages_count (mbox, &num);
-         mu_mailbox_get_message (mbox, num, &msg);
-         mu_message_get_attribute (msg, &attr);
+         mu_mailbox_get_message (mbox, num, &temp);
+         mu_message_get_attribute (temp, &attr);
          mu_attribute_set_flags (attr, flags);
        }
       /* FIXME: If not INBOX */
diff --git a/imap4d/fetch.c b/imap4d/fetch.c
index 40a963e..6e955c0 100644
--- a/imap4d/fetch.c
+++ b/imap4d/fetch.c
@@ -959,7 +959,7 @@ _frt_internaldate (struct fetch_function_closure *ffc,
   const char *date;
   mu_envelope_t env = NULL;
   struct tm tm, *tmp = NULL;
-  mu_timezone tz;
+  struct mu_timezone tz;
   
   mu_message_get_envelope (frt->msg, &env);
   if (mu_envelope_sget_date (env, &date) == 0
diff --git a/imap4d/util.c b/imap4d/util.c
index b494650..2482b9b 100644
--- a/imap4d/util.c
+++ b/imap4d/util.c
@@ -336,7 +336,7 @@ add2set (size_t ** set, int *n, unsigned long val)
 }
 
 static void
-adjust_tm (struct tm *tm, mu_timezone *tz, enum datetime_parse_mode flag)
+adjust_tm (struct tm *tm, struct mu_timezone *tz, enum datetime_parse_mode 
flag)
 {
   switch (flag)
     {
@@ -371,7 +371,7 @@ util_parse_internal_date (char *date, time_t *timep,
                          enum datetime_parse_mode flag)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   time_t time;
 
   if (mu_scan_datetime (date, MU_DATETIME_INTERNALDATE, &tm, &tz, NULL))
@@ -392,7 +392,7 @@ util_parse_822_date (const char *date, time_t *timep,
                     enum datetime_parse_mode flag)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   const char *p = date;
 
   if (mu_parse822_date_time (&p, date + strlen (date), &tm, &tz) == 0)
@@ -409,7 +409,7 @@ util_parse_ctime_date (const char *date, time_t *timep,
                       enum datetime_parse_mode flag)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
 
   if (mu_scan_datetime (date, MU_DATETIME_FROM, &tm, &tz, NULL) == 0)
     {
diff --git a/include/mailutils/Makefile.am b/include/mailutils/Makefile.am
index 27c1b5a..a7b116d 100644
--- a/include/mailutils/Makefile.am
+++ b/include/mailutils/Makefile.am
@@ -38,6 +38,7 @@ pkginclude_HEADERS = \
  cfg.h\
  cidr.h\
  cstr.h\
+ datetime.h\
  daemon.h\
  dbm.h\
  debug.h\
diff --git a/include/mailutils/datetime.h b/include/mailutils/datetime.h
new file mode 100644
index 0000000..de00618
--- /dev/null
+++ b/include/mailutils/datetime.h
@@ -0,0 +1,85 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General
+   Public License along with this library.  If not, see
+   <http://www.gnu.org/licenses/>. */
+
+#ifndef _MAILUTILS_DATETIME_H
+#define _MAILUTILS_DATETIME_H
+
+#include <time.h>
+#include <mailutils/types.h>
+
+  /* ----------------------- */
+  /* Date & time functions   */
+  /* ----------------------- */
+
+/* Argument ranges:
+
+   year != 0, AD if > 0, BC if < 0
+   1 <= month <= 12
+   1 <= day <= maxday(month)
+*/
+/* Compute Julian Day for the given date */
+int mu_datetime_julianday (int year, int month, int day);
+/* Compute day of week (Sunday - 0) */
+int mu_datetime_dayofweek (int year, int month, int day);
+/* Compute ordinal date (1-based) */
+int mu_datetime_dayofyear (int year, int month, int day);
+/* Return number of days in the year */
+int mu_datetime_year_days (int year);
+
+/* Day of week and month names in C locale */
+extern const char *_mu_datetime_short_month[];
+extern const char *_mu_datetime_full_month[];
+extern const char *_mu_datetime_short_wday[];
+extern const char *_mu_datetime_full_wday[];
+
+
+struct mu_timezone
+{
+  int utc_offset;  /* Seconds east of UTC. */
+
+  const char *tz_name;
+    /* Nickname for this timezone, if known. It is always considered
+       to be a pointer to static string, so will never be freed. */
+};
+
+int mu_parse_date (const char *p, time_t *rettime, const time_t *now);
+
+time_t mu_utc_offset (void);
+time_t mu_tm2time (struct tm *timeptr, struct mu_timezone *tz);
+size_t mu_strftime (char *s, size_t max, const char *format, struct tm *tm);
+
+int mu_c_streamftime (mu_stream_t str, const char *fmt, struct tm *tm,
+                     struct mu_timezone *tz);
+int mu_scan_datetime (const char *input, const char *fmt, struct tm *tm,
+                     struct mu_timezone *tz, char **endp);
+
+  /* Common datetime formats: */
+#define MU_DATETIME_FROM         "%a %b %e %H:%M:%S %Y"
+/* Length of an envelope date in C locale,
+   not counting the terminating nul character */
+#define MU_DATETIME_FROM_LENGTH 24
+
+#define MU_DATETIME_IMAP         "%d-%b-%Y %H:%M:%S %z"
+#define MU_DATETIME_INTERNALDATE "%d-%b-%Y%$ %H:%M:%S %z"
+
+  /* RFC2822 date.  Scan format contains considerable allowances which would
+     stun formatting functions, therefore two distinct formats are provided:
+     one for outputting and one for scanning: */
+#define MU_DATETIME_FORM_RFC822  "%a, %e %b %Y %H:%M:%S %z"
+#define MU_DATETIME_SCAN_RFC822  "%[%a, %]%e %b %Y %H:%M%[:%S%] %z"
+
+#endif
diff --git a/include/mailutils/envelope.h b/include/mailutils/envelope.h
index 246cfd5..6125971 100644
--- a/include/mailutils/envelope.h
+++ b/include/mailutils/envelope.h
@@ -51,12 +51,6 @@ int mu_envelope_set_destroy (mu_envelope_t envelope,
                             int (*_destroy) (mu_envelope_t),
                             void *owner);
 
-/* mu_strftime format for envelope dates */
-#define MU_ENVELOPE_DATE_FORMAT "%a %b %d %H:%M:%S %Y"
-/* Length of an envelope date in C locale, 
-   not counting the terminating nul character */
-#define MU_ENVELOPE_DATE_LENGTH 24
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mailutils/imap.h b/include/mailutils/imap.h
index b3cf521..b247676 100644
--- a/include/mailutils/imap.h
+++ b/include/mailutils/imap.h
@@ -21,7 +21,7 @@
 #include <mailutils/iterator.h>
 #include <mailutils/debug.h>
 #include <mailutils/stream.h>
-#include <mailutils/util.h>
+#include <mailutils/datetime.h>
 #include <mailutils/kwd.h>
 
 #ifdef __cplusplus
diff --git a/include/mailutils/imapio.h b/include/mailutils/imapio.h
index 3a4b1e3..e6d7594 100644
--- a/include/mailutils/imapio.h
+++ b/include/mailutils/imapio.h
@@ -22,7 +22,7 @@ extern "C" {
 #endif
 
 # include <mailutils/types.h>
-# include <mailutils/util.h>  
+# include <mailutils/datetime.h>  
 # include <time.h>
 
 #define MU_IMAPIO_CLIENT 0
diff --git a/include/mailutils/mailutils.h b/include/mailutils/mailutils.h
index 08a2fc0..eb2a616 100644
--- a/include/mailutils/mailutils.h
+++ b/include/mailutils/mailutils.h
@@ -25,6 +25,7 @@
 #include <mailutils/attribute.h>
 #include <mailutils/auth.h>
 #include <mailutils/body.h>
+#include <mailutils/datetime.h>
 #include <mailutils/debug.h>
 #include <mailutils/envelope.h>
 #include <mailutils/errno.h>
diff --git a/include/mailutils/parse822.h b/include/mailutils/parse822.h
index 353ed3e..c73abc6 100644
--- a/include/mailutils/parse822.h
+++ b/include/mailutils/parse822.h
@@ -24,7 +24,7 @@
 #define _MAILUTILS_PARSE822_H
 
 #include <mailutils/types.h>
-#include <mailutils/util.h>
+#include <mailutils/datetime.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -131,7 +131,7 @@ extern int mu_parse822_date      (const char **p, const 
char *e, int *day,
 extern int mu_parse822_time      (const char **p, const char *e, int *h,
                                  int *m, int *s, int *tz, const char 
**tz_name);
 extern int mu_parse822_date_time (const char **p, const char *e,
-                                 struct tm *tm, mu_timezone *tz);
+                                 struct tm *tm, struct mu_timezone *tz);
 
 
 #ifdef __cplusplus
diff --git a/include/mailutils/util.h b/include/mailutils/util.h
index e6f4b89..237ff3f 100644
--- a/include/mailutils/util.h
+++ b/include/mailutils/util.h
@@ -21,8 +21,6 @@
 
 /* A collection of utility routines that don't belong somewhere else. */
 
-#include <time.h>
-
 #include <mailutils/list.h>
 #include <mailutils/types.h>
 
@@ -47,42 +45,6 @@ void mu_str_url_decode_inline (char *str);
 int mu_str_url_decode (char **ptr, const char *s);
 
   /* ----------------------- */
-  /* Date & time functions   */
-  /* ----------------------- */
-struct mu_timezone
-{
-  int utc_offset;  /* Seconds east of UTC. */
-
-  const char *tz_name;
-    /* Nickname for this timezone, if known. It is always considered
-       to be a pointer to static string, so will never be freed. */
-};
-
-typedef struct mu_timezone mu_timezone;
-
-int mu_parse_date (const char *p, time_t *rettime, const time_t *now);
-
-time_t mu_utc_offset (void);
-time_t mu_tm2time (struct tm *timeptr, mu_timezone *tz);
-size_t mu_strftime (char *s, size_t max, const char *format, struct tm *tm);
-
-int mu_c_streamftime (mu_stream_t str, const char *fmt, struct tm *tm,
-                     struct mu_timezone *tz);
-int mu_scan_datetime (const char *input, const char *fmt, struct tm *tm,
-                     struct mu_timezone *tz, char **endp);
-
-  /* Common datetime formats: */
-#define MU_DATETIME_FROM         "%a %b %e %H:%M:%S %Y"
-#define MU_DATETIME_IMAP         "%d-%b-%Y %H:%M:%S %z"
-#define MU_DATETIME_INTERNALDATE "%d-%b-%Y%$ %H:%M:%S %z"
-
-  /* RFC2822 date.  Scan format contains considerable allowances which would
-     stun formatting functions, therefore two distinct formats are provided:
-     one for outputting and one for scanning: */
-#define MU_DATETIME_FORM_RFC822  "%a, %e %b %Y %H:%M:%S %z"  
-#define MU_DATETIME_SCAN_RFC822  "%[%a, %]%e %b %Y %H:%M%[:%S%] %z"
-  
-  /* ----------------------- */
   /* File & path names.      */
   /* ----------------------- */
 char *mu_get_homedir (void);
diff --git a/libmailutils/Makefile.am b/libmailutils/Makefile.am
index b321382..c01b321 100644
--- a/libmailutils/Makefile.am
+++ b/libmailutils/Makefile.am
@@ -19,7 +19,7 @@
 SUBDIRS = \
  auth base address list sockaddr cidr cfg diag\
  filter mailbox mailer mime server string stream stdstream\
- property url imapio . tests 
+ property url imapio datetime . tests 
 
 lib_LTLIBRARIES = libmailutils.la
 
@@ -33,6 +33,7 @@ libmailutils_la_LIBADD = \
  sockaddr/libsockaddr.la\
  cidr/libcidr.la\
  cfg/libcfg.la\
+ datetime/libdatetime.la\
  diag/libdiag.la\
  filter/libfilter.la\
  imapio/libimapio.la\
diff --git a/libmailutils/base/Makefile.am b/libmailutils/base/Makefile.am
index a2e5ac5..4b9a375 100644
--- a/libmailutils/base/Makefile.am
+++ b/libmailutils/base/Makefile.am
@@ -26,7 +26,6 @@ libbase_la_SOURCES = \
  assoc.c\
  filesafety.c\
  daemon.c\
- date.c\
  fdwait.c\
  fgetpwent.c\
  filename.c\
@@ -61,7 +60,6 @@ libbase_la_SOURCES = \
  sha1.c\
  secret.c\
  spawnvp.c\
- strftime.c\
  symlink.c\
  tempfile.c\
  ticket.c\
diff --git a/libmailutils/base/amd.c b/libmailutils/base/amd.c
index bf08f50..769d9c5 100644
--- a/libmailutils/base/amd.c
+++ b/libmailutils/base/amd.c
@@ -63,6 +63,7 @@
 #include <mailutils/locker.h>
 #include <mailutils/message.h>
 #include <mailutils/util.h>
+#include <mailutils/datetime.h>
 #include <mailutils/property.h>
 #include <mailutils/stream.h>
 #include <mailutils/url.h>
diff --git a/libmailutils/base/date.c b/libmailutils/base/date.c
deleted file mode 100644
index b5c157b..0000000
--- a/libmailutils/base/date.c
+++ /dev/null
@@ -1,1162 +0,0 @@
-/* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 1999, 2000, 2001, 2002, 2007, 2009, 2010, 2011 Free
-   Software Foundation, Inc.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 3 of the License, or (at your option) any later version.
-
-   This library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General
-   Public License along with this library.  If not, see
-   <http://www.gnu.org/licenses/>. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <mailutils/diag.h>
-#include <mailutils/util.h>
-#include <mailutils/stream.h>
-#include <mailutils/errno.h>
-#include <mailutils/cstr.h>
-#include <mailutils/cctype.h>
-
-#define SECS_PER_DAY 86400
-#define ADJUSTMENT -719162L
-
-/* Julian day is the number of days since Jan 1, 4713 BC (ouch!).
-   Eg. Jan 1, 1900 is: */
-#define  JULIAN_1900    1721425L
-
-/* Computes the number of days elapsed since January, 1 1900 to the
-   January, 1 of the given year */
-static unsigned
-jan1st (int year)
-{
-  year--;               /* Do not consider the current year */
-  return  year * 365L
-               + year/4L    /* Years divisible by 4 are leap years */
-               + year/400L  /* Years divisible by 400 are always leap years */
-               - year/100L; /* Years divisible by 100 but not 400 aren't */
-}
-
-static int  month_start[]=
-    {    0, 31, 59,  90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
-     /* Jan Feb Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec
-         31  28  31   30   31   30   31   31   30   31   30   31
-     */
-
-#define leap_year(y) ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0))
-
-static int
-dayofyear (int year, int month, int day)
-{
-  int  leap, month_days;
-
-  if (year < 0 || month < 0 || month > 11)
-    return -1;
-    
-  leap = leap_year (year);
-  
-  month_days = month_start[month + 1] - month_start[month]
-               + ((month == 2) ? leap : 0);
-
-  if (day < 0 || day > month_days)
-    return -1;  /* Illegal Date */
-
-  if (month <= 2)
-    leap = 0;
-
-  return month_start[month] + day + leap;
-}
-
-/* Returns number of days in a given year */
-static int
-year_days (int year)
-{
-  return dayofyear (year, 11, 31);
-}
-
-static int
-julianday (unsigned *pd, int year, int month, int day)
-{
-  int total = dayofyear (year, month, day);
-  if (total == -1)
-    return -1;
-  *pd = JULIAN_1900 + total + jan1st (year);
-  return 0;
-}
-
-static int
-dayofweek (int year, int month, int day)
-{
-  unsigned jd;
-
-  if (julianday (&jd, year, month, day))
-    return -1;
-
-  /* January 1, 1900 was Monday, hence +1 */
-  return (jd + 1) % 7;
-}
-
-#define ISO_8601_START_WDAY 1 /* Monday */
-#define ISO_8601_MAX_WDAY   4 /* Thursday */
-#define MAXDAYS 366 /* Max. number of days in a year */
-#define ISO_8601_OFF ((MAXDAYS / 7 + 2) * 7)
-
-int
-ISO_8601_weekdays (int yday, int wday)
-{
-  return (yday
-         - (yday - wday + ISO_8601_MAX_WDAY + ISO_8601_OFF) % 7
-         + ISO_8601_MAX_WDAY - ISO_8601_START_WDAY);
-}
-
-/* Convert struct tm into time_t, taking into account timezone offset. */
-/* FIXME: It does not take DST into account */
-time_t
-mu_tm2time (struct tm *tm, mu_timezone *tz)
-{
-  time_t t;
-  int day;
-  
-  day = dayofyear (tm->tm_year, tm->tm_mon, tm->tm_mday - 1);
-  if (day == -1)
-    return -1;
-  t = (day + ADJUSTMENT + jan1st (1900 + tm->tm_year)) * SECS_PER_DAY
-            + (tm->tm_hour * 60 + tm->tm_min) * 60 + tm->tm_sec
-       - (tz ? tz->utc_offset : 0);
-  return t;
-}
-
-/* Convert time 0 at UTC to our localtime, that tells us the offset
-   of our current timezone from UTC. */
-time_t
-mu_utc_offset (void)
-{
-  time_t t = 0;
-  struct tm *tm = gmtime (&t);
-
-  return - mktime (tm);
-}
-
-static const char *short_month[] =
-{
-  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-static const char *full_month[] =
-{
-  "January", "February", "March", "April",
-  "May", "June", "July", "August",
-  "September", "October", "November", "December"
-};
-
-static const char *short_wday[] =
-{
-  "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
-};
-
-static const char *full_wday[] =
-{
-  "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
-  "Friday", "Saturday"
-};
-
-int
-mu_c_streamftime (mu_stream_t str, const char *fmt, struct tm *input_tm,
-                 struct mu_timezone *tz)
-{
-  int rc = 0;
-  struct tm tm;
-
-  /* Copy input TM because it might have been received from gmtime and
-     the fmt might result in further calls to gmtime which will clobber
-     it. */
-  tm = *input_tm;
-  while (*fmt && rc == 0)
-    {
-      size_t len = strcspn (fmt, "%");
-      if (len)
-       {
-         rc = mu_stream_write (str, fmt, len, NULL);
-         if (rc)
-           break;
-       }
-
-      fmt += len;
-
-    restart:
-      if (!*fmt || !*++fmt)
-       break;
-
-      switch (*fmt)
-       {
-       case 'a':
-         /* The abbreviated weekday name. */
-         if (tm.tm_wday < 0 || tm.tm_wday > 6)
-           rc = ERANGE;
-         else
-           rc = mu_stream_write (str, short_wday[tm.tm_wday],
-                                 strlen (short_wday[tm.tm_wday]), NULL);
-         break;
-         
-       case 'A':
-         /* The full weekday name. */
-         if (tm.tm_wday < 0 || tm.tm_wday > 6)
-           rc = ERANGE;
-         else
-           rc = mu_stream_write (str, full_wday[tm.tm_wday],
-                                 strlen (full_wday[tm.tm_wday]), NULL);
-         break;
-         
-       case 'b':
-       case 'h':
-         /* The abbreviated month name. */
-         if (tm.tm_mon < 0 || tm.tm_mon > 11)
-           rc = ERANGE;
-         else
-           rc = mu_stream_write (str, short_month[tm.tm_mon],
-                                 strlen (short_month[tm.tm_mon]), NULL);
-         break;
-         
-       case 'B':
-         /* The full month name. */
-         if (tm.tm_mon < 0 || tm.tm_mon > 11)
-           rc = ERANGE;
-         else
-           rc = mu_stream_write (str, full_month[tm.tm_mon],
-                                 strlen (full_month[tm.tm_mon]), NULL);
-         break;
-         
-       case 'c':
-         /* The preferred date and time representation. */
-         rc = mu_c_streamftime (str, "%a %b %e %H:%M:%S %Y", &tm, tz);
-         break;
-           
-       case 'C':
-         /* The century number (year/100) as a 2-digit integer. */
-         rc = mu_stream_printf (str, "%02d", (tm.tm_year + 1900) / 100);
-         break;
-         
-       case 'd':
-         /* The day of the month as a decimal number (range 01 to 31). */
-         if (tm.tm_mday < 1 || tm.tm_mday > 31)
-           rc = ERANGE;
-         else
-           rc = mu_stream_printf (str, "%02d", tm.tm_mday);
-         break;
-         
-       case 'D':
-         /* Equivalent to %m/%d/%y. */
-         rc = mu_c_streamftime (str, "%m/%d/%y", &tm, tz);
-         break;
-         
-       case 'e':
-         /* Like %d, the day of the month as a decimal number, but a leading
-            zero is replaced by a space. */
-         if (tm.tm_mday < 1 || tm.tm_mday > 31)
-           rc = ERANGE;
-         else
-           rc = mu_stream_printf (str, "%2d", tm.tm_mday);
-         break;
-         
-       case 'E':
-         /* Modifier. The Single Unix Specification mentions %Ec, %EC, %Ex,
-            %EX, %Ey, and %EY, which are supposed to use a corresponding
-            locale-dependent alternative representation.
-            A no-op in POSIX locale */
-         goto restart;
-         
-       case 'F':
-         /* Equivalent to %Y-%m-%d (the ISO 8601 date format). */
-         rc = mu_c_streamftime (str, "%Y-%m-%d", &tm, tz);
-         break;
-                 
-       case 'V':
-         /* The ISO 8601:1988 week number of the current year as a decimal
-            number range 01 to 53, where week 1 is the first week that has
-            at least 4 days in the current year, and with Monday as the
-            first day of the week.
-         */
-       case 'G':
-         /* The ISO 8601 year with century as a decimal number.  The 4-digit
-            year corresponding to the ISO week number (see  %V).  This has
-            the same format and value as %y, except that if the ISO week
-            number belongs to the previous or next year, that year is used
-            instead.
-         */
-       case 'g':
-         /* Like  %G, but without century, that is, with a 2-digit year
-            (00-99). */
-         {
-           int year = tm.tm_year + 1900;
-           int days = ISO_8601_weekdays (tm.tm_yday, tm.tm_wday);
-
-           if (days < 0)
-             {
-               days = ISO_8601_weekdays (tm.tm_yday + year_days (year - 1),
-                                         tm.tm_wday);
-               year--;
-             }
-           else
-             {
-               int d = ISO_8601_weekdays (tm.tm_yday - year_days (year),
-                                          tm.tm_wday);
-               if (d >= 0)
-                 {
-                   year++;
-                   days = d;
-                 }
-             }
-
-           switch (*fmt)
-             {
-             case 'V':
-               rc = mu_stream_printf (str, "%02d", days / 7 + 1);
-               break;
-
-             case 'G':
-               rc = mu_stream_printf (str, "%4d", year);
-               break;
-
-             case 'g':
-               rc = mu_stream_printf (str, "%02d", year % 100);
-             }
-         }
-         break;
-         
-       case 'H':
-         /* The hour as a decimal number using a 24-hour clock (range 00 to
-            23). */
-         rc = mu_stream_printf (str, "%02d", tm.tm_hour);
-         break;
-         
-       case 'I':
-         /* The hour as a decimal number using a 12-hour clock (range 01 to
-            12). */
-         {
-           unsigned n = tm.tm_hour % 12;
-           rc = mu_stream_printf (str, "%02d", n == 0 ? 12 : n);
-         }
-         break;
-
-       case 'j':
-         /* The day of the year as a decimal number (range 001 to 366). */
-         rc = mu_stream_printf (str, "%03d", tm.tm_yday + 1);
-         break;
-         
-       case 'k':
-         /* The hour (24-hour clock) as a decimal number (range 0 to 23);
-            single digits are preceded by a blank. */
-         rc = mu_stream_printf (str, "%2d", tm.tm_hour);
-         break;
-         
-       case 'l':
-         /* The hour (12-hour clock) as a decimal number (range 1 to 12);
-            single digits are preceded by a blank. */
-         {
-           unsigned n = tm.tm_hour % 12;
-           rc = mu_stream_printf (str, "%2d", n == 0 ? 12 : n);
-         }
-         break;
-         
-       case 'm':
-         /* The month as a decimal number (range 01 to 12). */
-         rc = mu_stream_printf (str, "%02d", tm.tm_mon + 1);
-         break;
-                                  
-       case 'M':
-         /* The minute as a decimal number (range 00 to 59). */
-         rc = mu_stream_printf (str, "%02d", tm.tm_min);
-         break;
-         
-       case 'n':
-         /* A newline character. */
-         rc = mu_stream_write (str, "\n", 1, NULL);
-         break;
-         
-       case 'O':
-         /* Modifier.  The Single Unix Specification mentions %Od, %Oe, %OH,
-            %OI, %Om, %OM, %OS, %Ou, %OU, %OV, %Ow, %OW, and %Oy, which are
-            supposed to use alternative numeric symbols.
-
-            Hardly of any use for our purposes, hence a no-op. */
-         goto restart;
-         
-       case 'p':
-         /* Either "AM" or "PM" according to the given time value.
-            Noon is treated as "PM" and midnight as "AM". */
-         rc = mu_stream_write (str,
-                               tm.tm_hour < 12 ? "AM" : "PM",
-                               2, NULL);
-         break;
-                               
-       case 'P':
-         /* Like %p but in lowercase: "am" or "pm". */
-         rc = mu_stream_write (str,
-                               tm.tm_hour < 12 ? "am" : "pm",
-                               2, NULL);
-         break;
-         
-       case 'r':
-         /* The time in a.m. or p.m. notation, i.e. %I:%M:%S %p. */
-         rc = mu_c_streamftime (str, "%I:%M:%S %p", &tm, tz);
-         break;
-         
-       case 'R':
-         /* The time in 24-hour notation (%H:%M) */
-         rc = mu_c_streamftime (str, "%H:%M", &tm, tz);
-         break;
-         
-       case 's':
-         /* The number of seconds since the Epoch */
-         rc = mu_stream_printf (str, "%lu",
-                                (unsigned long) mu_tm2time (&tm, tz));
-         break;
-         
-       case 'S':
-         /* The second as a decimal number (range 00 to 60) */
-         rc = mu_stream_printf (str, "%02d", tm.tm_sec);
-         break;
-         
-       case 't':
-         /* A tab character. */
-         rc = mu_stream_write (str, "\t", 1, NULL);
-         break;
-         
-       case 'T':
-         /* The time in 24-hour notation (%H:%M:%S) */
-         rc = mu_c_streamftime (str, "%H:%M:%S", &tm, tz);
-         break;
-         
-       case 'u':
-         /* The day of the week as a decimal, range 1 to 7, Monday being 1.
-          */
-         rc = mu_stream_printf (str, "%1d",
-                                tm.tm_wday == 0 ? 7 : tm.tm_wday);
-         break;
-         
-       case 'U':
-         /* The week number of the current year as a decimal number, range
-            00 to 53, starting with the first Sunday as the first day of
-            week 01.
-         */
-         rc = mu_stream_printf (str, "%02d",
-                                (tm.tm_yday - tm.tm_wday + 7) / 7);
-         break;
-         
-       case 'w':
-         /* The day of the week as a decimal, range 0 to 6, Sunday being 0.
-          */
-         rc = mu_stream_printf (str, "%01d", tm.tm_wday);
-         break;
-         
-       case 'W':
-         /* The week number of the current year as a decimal number, range
-            00 to 53, starting with the first Monday as the first day of
-            week 01. */
-         rc = mu_stream_printf (str, "%02d", 
-                        (tm.tm_yday - (tm.tm_wday - 1 + 7) % 7 + 7) / 7);
-         break;
-
-         /* The preferred date representation without the time:
-            equivalent to %D */
-       case 'x':
-         rc = mu_c_streamftime (str, "%m/%d/%y", &tm, tz);
-         break;
-         
-       case 'X':
-         /* The preferred date representation without the date */
-         rc = mu_c_streamftime (str, "%H:%M:%S", &tm, tz);
-         break;
-
-       case 'y':
-         /* The year as a decimal number without a century (range 00 to 99).
-          */
-         rc = mu_stream_printf (str, "%02d", (tm.tm_year + 1900) % 100);
-         break;
-         
-       case 'Y':
-         /* The year as a decimal number including the century. */
-         rc = mu_stream_printf (str, "%d", tm.tm_year + 1900);
-         break;
-         
-       case 'z':
-       case 'Z':
-         /* The time-zone as hour offset from GMT, for formatting RFC-822
-            dates (e.g. "%a, %d %b %Y %H:%M:%S %z") */
-         {
-           int utc_off = tz ? tz->utc_offset : mu_utc_offset ();
-           int sign;
-           if (utc_off < 0)
-             {
-               sign = '-';
-               utc_off = - utc_off;
-             }
-           else
-             sign = '+';
-           utc_off /= 60;
-           rc = mu_stream_printf (str, "%c%02u%02u", sign,
-                                  utc_off / 60, utc_off % 60);
-         }
-         break;
-         
-       case '%':
-         /* A literal '%' character. */
-         rc = mu_stream_write (str, "%", 1, NULL);
-         break;
-
-       case '$':
-         /* Ignored for compatibilty with mu_scan_datetime */
-         break;
-         
-       case '+':
-         /* Not supported (date and time in date(1) format. */
-       default:
-         rc = mu_stream_write (str, fmt-1, 2, NULL);
-         break;
-       }
-      fmt++;
-    }
-  /* Restore input tm */
-  *input_tm = tm;
-  return rc;
-}
-
-static int
-_mu_short_weekday_string (const char *str)
-{
-  int i;
-  
-  for (i = 0; i < 7; i++)
-    {
-      if (mu_c_strncasecmp (str, short_wday[i], 3) == 0)
-       return i;
-    }
-  return -1;
-}
-
-static int
-_mu_full_weekday_string (const char *str, char **endp)
-{
-  int i;
-  
-  for (i = 0; i < 7; i++)
-    {
-      if (mu_c_strcasecmp (str, full_wday[i]) == 0)
-       {
-         if (endp)
-           *endp = (char*) (str + strlen (full_wday[i]));
-         return i;
-       }
-    }
-  return -1;
-}
-
-
-static int
-_mu_short_month_string (const char *str)
-{  
-  int i;
-  
-  for (i = 0; i < 12; i++)
-    {
-      if (mu_c_strncasecmp (str, short_month[i], 3) == 0)
-       return i;
-    }
-  return -1;
-}
-
-static int
-_mu_full_month_string (const char *str, char **endp)
-{  
-  int i;
-  
-  for (i = 0; i < 12; i++)
-    {
-      if (mu_c_strcasecmp (str, full_month[i]) == 0)
-       {
-         if (endp)
-           *endp = (char*) (str + strlen (full_month[i]));
-         return i;
-       }
-    }
-  return -1;
-}
-
-int
-get_num (const char *str, char **endp, int ndig, int minval, int maxval,
-        int *pn)
-{
-  int x = 0;
-  int i;
-  
-  errno = 0;
-  for (i = 0; i < ndig && *str && mu_isdigit (*str); str++, i++)
-    x = x * 10 + *str - '0';
-
-  *endp = (char*) str;
-  if (i == 0)
-    return -1;
-  else if (pn)
-    *pn = i;
-  else if (i != ndig)
-    return -1;
-  if (x < minval || x > maxval)
-    return -1;
-  return x;
-}
-
-#define DT_YEAR  0x01
-#define DT_MONTH 0x02
-#define DT_MDAY  0x04
-#define DT_WDAY  0x08
-#define DT_HOUR  0x10
-#define DT_MIN   0x20
-#define DT_SEC   0x40
-
-#define ST_NON   -1
-#define ST_OPT   0
-#define ST_ALT   1
-
-struct save_input
-{
-  int state;
-  const char *input;
-};
-
-static int
-push_input (mu_list_t *plist, int state, const char *input)
-{
-  mu_list_t list = *plist;
-  struct save_input *inp = malloc (sizeof (*inp));
-  if (!inp)
-    return ENOMEM;
-  if (!list)
-    {
-      int rc = mu_list_create (&list);
-      if (rc)
-       {
-         free (inp);
-         return rc;
-       }
-      mu_list_set_destroy_item (list, mu_list_free_item);
-      *plist = list;
-    }
-  inp->state = state;
-  inp->input = input;
-  return mu_list_push (list, (void*)inp);
-}
-
-static int
-peek_state (mu_list_t list, int *state, const char **input)
-{
-  int rc;
-  struct save_input *inp;
-
-  rc = mu_list_tail (list, (void**)&inp);
-  if (rc)
-    return rc;
-  *state = inp->state;
-  if (input)
-    *input = inp->input;
-  return 0;
-}      
-
-static int
-pop_input (mu_list_t list, int *state, const char **input)
-{
-  int rc;
-  struct save_input *inp;
-
-  rc = mu_list_pop (list, (void**)&inp);
-  if (rc)
-    return rc;
-  *state = inp->state;
-  if (input)
-    *input = inp->input;
-  return 0;
-}
-
-static int
-bracket_to_state (int c)
-{
-  switch (c)
-    {
-    case '[':
-    case ']':
-      return ST_OPT;
-    case '(':
-    case ')':
-      return ST_ALT;
-    }
-  return ST_NON;
-}
-
-static int
-state_to_closing_bracket (int st)
-{
-  switch (st)
-    {
-    case ST_OPT:
-      return ']';
-    case ST_ALT:
-      return ')';
-    }
-  return '?';
-}
-
-static int
-scan_recovery (const char *fmt, mu_list_t *plist, int skip_alt,
-              const char **endp,
-              const char **input)
-{
-  int c, rc = 0;
-  int nesting_level = 1;
-  int st;
-  const char *p;
-  
-  while (*fmt)
-    {
-      c = *fmt++;
-      
-      if (c == '%')
-       {
-         c = *fmt++;
-         if (!c)
-           {
-             mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
-                       ("%s:%d: error in format: %% at the end of input",
-                        __FILE__, __LINE__));
-             rc = MU_ERR_FORMAT;
-             break;
-           }
-             
-         switch (c)
-           {
-           case '[':
-           case '(':
-             nesting_level++;
-             rc = push_input (plist, bracket_to_state (c), NULL);
-             break;
-             
-           case ')':
-           case ']':
-             rc = pop_input (*plist, &st, &p);
-             if (rc || st != bracket_to_state (c))
-               {
-                 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
-                           ("%s:%d: error in format: %%%c out of context",
-                            __FILE__, __LINE__, c));
-                 rc = MU_ERR_FORMAT;
-                 break;
-               }
-             if (--nesting_level == 0)
-               {
-                 *endp = fmt;
-                 if (skip_alt)
-                   return 0;
-                 *input = p;
-                 if (st == ST_ALT)
-                   {
-                     if (*fmt == '%' && (fmt[1] == '|' || fmt[1] == ']'))
-                       return 0;
-                     return MU_ERR_PARSE; /* No match found */
-                   }
-                 return 0;
-               }
-             break;
-
-           case '|':
-             if (skip_alt)
-               continue;
-             if (nesting_level == 1)
-               {
-                 *endp = fmt;
-                 return peek_state (*plist, &st, input);
-               }
-             break;
-
-           case '\\':
-             if (*++fmt == 0)
-               {
-                 peek_state (*plist, &st, NULL);
-                 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
-                           ("%s:%d: error in format: missing closing %%%c",
-                            __FILE__, __LINE__,
-                            state_to_closing_bracket (st)));
-                 return MU_ERR_FORMAT;           
-               }
-           }
-       }
-    }
-  
-  peek_state (*plist, &st, NULL);
-  mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
-           ("%s:%d: error in format: missing closing %%%c",
-            __FILE__, __LINE__,
-            state_to_closing_bracket (st)));
-  return MU_ERR_FORMAT;                  
-}
-
-int
-mu_scan_datetime (const char *input, const char *fmt,
-                 struct tm *tm, struct mu_timezone *tz, char **endp)
-{
-  int rc = 0;
-  char *p;
-  int n;
-  int c;
-  int st;
-  int recovery = 0;
-  int eof_ok = 0;
-  int datetime_parts = 0;
-  mu_list_t save_input_list = NULL;
-  
-  memset (tm, 0, sizeof *tm);
-#ifdef HAVE_STRUCT_TM_TM_ISDST
-  tm->tm_isdst = -1;   /* unknown. */
-#endif
-  /* provide default timezone, in case it is not supplied in input */
-  if (tz)
-    {
-      memset (tz, 0, sizeof *tz);
-      tz->utc_offset = mu_utc_offset ();
-    }
-
-  /* Skip leading whitespace */
-  input = mu_str_skip_class (input, MU_CTYPE_BLANK);
-  for (; *fmt && rc == 0; fmt++)
-    {
-      if (mu_isspace (*fmt))
-       {
-         fmt = mu_str_skip_class (fmt, MU_CTYPE_BLANK);
-         input = mu_str_skip_class (input, MU_CTYPE_BLANK);
-         if (!*fmt)
-           break;
-       }
-      eof_ok = 0;
-      
-      if (*fmt == '%')
-       {
-         c = *++fmt;
-         if (!c)
-           {
-             mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
-                       ("%s:%d: error in format: %% at the end of input",
-                        __FILE__, __LINE__));
-             rc = MU_ERR_FORMAT;
-             break;
-           }
-         
-         switch (c)
-           {
-           case 'a':
-             /* The abbreviated weekday name. */
-             n = _mu_short_weekday_string (input);
-             if (n == -1)
-               rc = MU_ERR_PARSE;
-             else
-               {
-                 tm->tm_wday = n;
-                 datetime_parts |= DT_WDAY;
-                 input += 3;
-               }
-             break;
-                 
-           case 'A':
-             /* The full weekday name. */
-             n = _mu_full_weekday_string (input, &p);
-             if (n == -1)
-               rc = MU_ERR_PARSE;
-             else
-               {
-                 tm->tm_wday = n;
-                 datetime_parts |= DT_WDAY;
-                 input = p;
-               }
-             break;
-             
-           case 'b':
-             /* The abbreviated month name. */
-             n = _mu_short_month_string (input);
-             if (n == -1)
-               rc = MU_ERR_PARSE;
-             else
-               {
-                 tm->tm_mon = n;
-                 datetime_parts |= DT_MONTH;
-                 input += 3;
-               }
-             break;
-
-           case 'B':
-             /* The full month name. */
-             n = _mu_full_month_string (input, &p);
-             if (n == -1)
-               rc = MU_ERR_PARSE;
-             else
-               {
-                 tm->tm_mon = n;
-                 datetime_parts |= DT_MONTH;
-                 input = p;
-               }
-             break;
-             
-           case 'd':
-             /* The day of the month as a decimal number (range 01 to 31). */
-             n = get_num (input, &p, 2, 1, 31, NULL);
-             if (n == -1)
-               rc = MU_ERR_PARSE;
-             else
-               {
-                 tm->tm_mday = n;
-                 datetime_parts |= DT_MDAY;
-                 input = p;
-               }
-             break;
-             
-           case 'e':
-             /* Like %d, the day of the month as a decimal number, but a
-                leading zero is replaced by a space. */
-             {
-               int ndig;
-               
-               n = get_num (input, &p, 2, 1, 31, &ndig);
-               if (n == -1)
-                 rc = MU_ERR_PARSE;
-               else
-                 {
-                   tm->tm_mday = n;
-                   datetime_parts |= DT_MDAY;
-                   input = p;
-                 }
-             }
-             break;
-             
-           case 'H':
-             /* The hour as a decimal number using a 24-hour clock (range
-                00 to 23). */
-             n = get_num (input, &p, 2, 0, 23, NULL);
-             if (n == -1)
-               rc = MU_ERR_PARSE;
-             else
-               {
-                 tm->tm_hour = n;
-                 datetime_parts |= DT_HOUR;
-                 input = p;
-               }
-             break;
-             
-           case 'm':
-             /* The month as a decimal number (range 01 to 12). */
-             n = get_num (input, &p, 2, 1, 12, NULL);
-             if (n == -1)
-               rc = MU_ERR_PARSE;
-             else
-               {
-                 tm->tm_mon = n - 1;
-                 datetime_parts |= DT_MONTH;
-                 input = p;
-               }
-             break;
-             
-           case 'M':
-             /* The minute as a decimal number (range 00 to 59). */
-             n = get_num (input, &p, 2, 0, 59, NULL);
-             if (n == -1)
-               rc = MU_ERR_PARSE;
-             else
-               {
-                 tm->tm_min = n;
-                 datetime_parts |= DT_MIN;
-                 input = p;
-               }
-             break;
-             
-           case 'S':
-             /* The second as a decimal number (range 00 to 60) */
-             n = get_num (input, &p, 2, 0, 60, NULL);
-             if (n == -1)
-               rc = MU_ERR_PARSE;
-             else
-               {
-                 tm->tm_sec = n;
-                 datetime_parts |= DT_SEC;
-                 input = p;
-               }
-             break;
-             
-           case 'Y':
-             /* The year as a decimal number including the century. */
-             errno = 0;
-             n = strtoul (input, &p, 10);
-             if (errno || p == input)
-               rc = MU_ERR_PARSE;
-             else
-               {
-                 tm->tm_year = n - 1900;
-                 datetime_parts |= DT_YEAR;
-                 input = p;
-               }
-             break;
-                 
-           case 'z':
-             /* The time-zone as hour offset from GMT */
-             {
-               int sign = 1;
-               int hr;
-               
-               if (*input == '+')
-                 input++;
-               else if (*input == '-')
-                 {
-                   input++;
-                   sign = -1;
-                 }
-               n = get_num (input, &p, 2, 0, 11, NULL);
-               if (n == -1)
-                 rc = MU_ERR_PARSE;
-               else
-                 {
-                   input = p;
-                   hr = n;
-                   n = get_num (input, &p, 2, 0, 59, NULL);
-                   if (n == -1)
-                     rc = MU_ERR_PARSE;
-                   else
-                     {
-                       input = p;
-                       if (tz)
-                         tz->utc_offset = sign * (hr * 60 + n) * 60;
-                     }
-                 }
-             }
-             break;
-                     
-           case '%':
-             if (*input == '%')
-               input++;
-             else
-               rc = MU_ERR_PARSE;
-             break;
-
-             rc = push_input (&save_input_list, ST_ALT, (void*)input);
-             break;
-             
-           case '(':
-           case '[':
-             rc = push_input (&save_input_list, bracket_to_state (c),
-                              (void*)input);
-             break;
-
-           case ')':
-           case ']':
-             if (pop_input (save_input_list, &st, NULL))
-               {
-                 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
-                           ("%s:%d: error in format: unbalanced %%%c near %s",
-                            __FILE__, __LINE__, c, fmt));
-                 rc = MU_ERR_FORMAT;
-               }
-             else if (st != bracket_to_state (c))
-               {
-                 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
-                           ("%s:%d: error in format: %%%c out of context",
-                            __FILE__, __LINE__, c));
-                 rc = MU_ERR_FORMAT;
-               }
-             break;
-
-           case '|':
-             rc = scan_recovery (fmt, &save_input_list, 1, &fmt, NULL);
-             if (rc == 0)
-               fmt--;
-             break;
-             
-           case '$':
-             eof_ok = 1;
-             break;
-
-           case '\\':
-             c = *++fmt;
-             if (!c)
-               {
-                 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
-                           ("%s:%d: error in format: %% at the end of input",
-                            __FILE__, __LINE__));
-                 rc = MU_ERR_FORMAT;
-               }
-             else if (c == *input)
-               input++;
-             else
-               rc = MU_ERR_PARSE;
-             break;
-
-           case '?':
-             input++;
-             break;
-             
-           default:
-             mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
-                       ("%s:%d: error in format: unrecognized conversion type"
-                        " near %s",
-                        __FILE__, __LINE__, fmt));
-             rc = MU_ERR_FORMAT;
-             break;
-           }
-
-         if (eof_ok && rc == 0 && *input == 0)
-           break;
-       }
-      else if (!recovery && *input != *fmt)
-       rc = MU_ERR_PARSE;
-      else
-       input++;
-
-      if (rc == MU_ERR_PARSE && !mu_list_is_empty (save_input_list))
-       {
-         rc = scan_recovery (fmt, &save_input_list, 0, &fmt, &input);
-         if (rc == 0)
-           --fmt;
-       }
-    }
-
-  if (!mu_list_is_empty (save_input_list))
-    {
-      mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
-               ("%s:%d: error in format: closing bracket missing",
-                __FILE__, __LINE__));
-      rc = MU_ERR_FORMAT;
-    }
-  mu_list_destroy (&save_input_list);
-  
-  if (rc == 0 && recovery)
-    rc = MU_ERR_PARSE;
-  
-  if (!eof_ok && rc == 0 && *input == 0 && *fmt)
-    rc = MU_ERR_PARSE;
-
-  if ((datetime_parts & (DT_YEAR|DT_MONTH|DT_MDAY)) ==
-      (DT_YEAR|DT_MONTH|DT_MDAY))
-    {
-      if (!(datetime_parts & DT_WDAY))
-       tm->tm_wday = dayofweek (tm->tm_year + 1900, tm->tm_mon, tm->tm_mday);
-      tm->tm_yday = dayofyear (tm->tm_year + 1900, tm->tm_mon, tm->tm_mday);
-    }
-  
-  if (endp)
-    *endp = (char*) input;
-  
-  return rc;
-}
diff --git a/libmailutils/base/msgid.c b/libmailutils/base/msgid.c
index 0207cb8..8683810 100644
--- a/libmailutils/base/msgid.c
+++ b/libmailutils/base/msgid.c
@@ -28,6 +28,7 @@
 #include <mailutils/cctype.h>
 #include <mailutils/message.h>
 #include <mailutils/header.h>
+#include <mailutils/datetime.h>
 #include <mailutils/util.h>
 #include <mailutils/io.h>
 #include <mailutils/envelope.h>
diff --git a/libmailutils/cidr/Makefile.am b/libmailutils/datetime/Makefile.am
similarity index 83%
copy from libmailutils/cidr/Makefile.am
copy to libmailutils/datetime/Makefile.am
index 408806f..f9a4f45 100644
--- a/libmailutils/cidr/Makefile.am
+++ b/libmailutils/datetime/Makefile.am
@@ -15,13 +15,18 @@
 # Public License along with this library.  If not, see
 # <http://www.gnu.org/licenses/>.
 
-noinst_LTLIBRARIES = libcidr.la
+noinst_LTLIBRARIES = libdatetime.la
 
-libcidr_la_SOURCES = \
- fromsa.c\
- fromstr.c\
- match.c\
- tosa.c\
- tostr.c
+libdatetime_la_SOURCES = \
+ dow.c\
+ doy.c\
+ jd.c\
+ scantime.c\
+ streamftime.c\
+ strftime.c\
+ tab.c\
+ unixtime.c\
+ utcoff.c\
+ yd.c
 
 INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
diff --git a/libmu_dbm/close.c b/libmailutils/datetime/dow.c
similarity index 77%
copy from libmu_dbm/close.c
copy to libmailutils/datetime/dow.c
index a84574a..9f94a68 100644
--- a/libmu_dbm/close.c
+++ b/libmailutils/datetime/dow.c
@@ -18,18 +18,12 @@
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
+#include <stdlib.h>
+#include <mailutils/datetime.h>
 
-#include <mailutils/types.h>
-#include <mailutils/dbm.h>
-#include <mailutils/errno.h>
-#include "mudbm.h"
-
+/* Compute day of week (0 - Sunday) */
 int
-mu_dbm_close (mu_dbm_file_t db)
+mu_datetime_dayofweek (int year, int month, int day)
 {
-  DBMSYSCK (db, _dbm_close);
-  if (!db->db_descr)
-    return 0;
-  return db->db_sys->_dbm_close (db);
+  return (mu_datetime_julianday (year, month, day) + 1) % 7;
 }
-
diff --git a/libproto/imap/close.c b/libmailutils/datetime/doy.c
similarity index 52%
copy from libproto/imap/close.c
copy to libmailutils/datetime/doy.c
index a92d598..49883cd 100644
--- a/libproto/imap/close.c
+++ b/libmailutils/datetime/doy.c
@@ -18,30 +18,36 @@
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
+#include <stdlib.h>
+#include <mailutils/datetime.h>
 
-#include <mailutils/imap.h>
-#include <mailutils/sys/imap.h>
+static int  month_start[]=
+    {    0, 31, 59,  90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
+     /* Jan Feb Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec
+         31  28  31   30   31   30   31   31   30   31   30   31
+     */
 
-void
-_mu_close_handler (mu_imap_t imap)
-{
-  if (imap->resp_code == MU_IMAP_OK)
-    imap->session_state = MU_IMAP_SESSION_AUTH;
-}
+#define leap_year(y) ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0))
 
+/* Compute number of days since January 1 to the given day of year. */
 int
-mu_imap_close (mu_imap_t imap)
+mu_datetime_dayofyear (int year, int month, int day)
 {
-  static char const *command = "CLOSE";
-  static struct imap_command com = {
-    MU_IMAP_SESSION_SELECTED,
-    NULL,
-    MU_IMAP_CLIENT_CLOSE_RX,
-    0,
-    1,
-    &command,
-    _mu_close_handler
-  };
-  return mu_imap_gencom (imap, &com);
+  int  leap, month_days;
+
+  if (year < 0 || month < 1 || month > 12 || day < 1)
+    return -1;
+    
+  leap = leap_year (year);
+  
+  month_days = month_start[month] - month_start[month - 1]
+               + ((month == 2) ? leap : 0);
+
+  if (day > month_days)
+    return -1;
+
+  if (month <= 2)
+    leap = 0;
+
+  return month_start[month-1] + day + leap;
 }
-      
diff --git a/libmu_dbm/close.c b/libmailutils/datetime/jd.c
similarity index 76%
copy from libmu_dbm/close.c
copy to libmailutils/datetime/jd.c
index a84574a..39fdf80 100644
--- a/libmu_dbm/close.c
+++ b/libmailutils/datetime/jd.c
@@ -18,18 +18,15 @@
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
-
-#include <mailutils/types.h>
-#include <mailutils/dbm.h>
-#include <mailutils/errno.h>
-#include "mudbm.h"
+#include <stdlib.h>
+#include <mailutils/datetime.h>
 
 int
-mu_dbm_close (mu_dbm_file_t db)
+mu_datetime_julianday (int year, int month, int day)
 {
-  DBMSYSCK (db, _dbm_close);
-  if (!db->db_descr)
-    return 0;
-  return db->db_sys->_dbm_close (db);
-}
+  int a = (14 - month) / 12;
+  int y = year + 4800 - a;
+  int m = month + 12*a - 3;
 
+  return day + (153*m + 2)/5 + 365*y + y/4 - y/100 + y/400 - 32045; 
+}
diff --git a/libmailutils/datetime/scantime.c b/libmailutils/datetime/scantime.c
new file mode 100644
index 0000000..670052b
--- /dev/null
+++ b/libmailutils/datetime/scantime.c
@@ -0,0 +1,660 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 1999, 2000, 2001, 2002, 2007, 2009, 2010, 2011 Free
+   Software Foundation, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General
+   Public License along with this library.  If not, see
+   <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mailutils/diag.h>
+#include <mailutils/datetime.h>
+#include <mailutils/util.h>
+#include <mailutils/stream.h>
+#include <mailutils/errno.h>
+#include <mailutils/cstr.h>
+#include <mailutils/cctype.h>
+
+static int
+_mu_short_weekday_string (const char *str)
+{
+  int i;
+  
+  for (i = 0; i < 7; i++)
+    {
+      if (mu_c_strncasecmp (str, _mu_datetime_short_wday[i], 3) == 0)
+       return i;
+    }
+  return -1;
+}
+
+static int
+_mu_full_weekday_string (const char *str, char **endp)
+{
+  int i;
+  
+  for (i = 0; i < 7; i++)
+    {
+      if (mu_c_strcasecmp (str, _mu_datetime_full_wday[i]) == 0)
+       {
+         if (endp)
+           *endp = (char*) (str + strlen (_mu_datetime_full_wday[i]));
+         return i;
+       }
+    }
+  return -1;
+}
+
+static int
+_mu_short_month_string (const char *str)
+{  
+  int i;
+  
+  for (i = 0; i < 12; i++)
+    {
+      if (mu_c_strncasecmp (str, _mu_datetime_short_month[i], 3) == 0)
+       return i;
+    }
+  return -1;
+}
+
+static int
+_mu_full_month_string (const char *str, char **endp)
+{  
+  int i;
+  
+  for (i = 0; i < 12; i++)
+    {
+      if (mu_c_strcasecmp (str, _mu_datetime_full_month[i]) == 0)
+       {
+         if (endp)
+           *endp = (char*) (str + strlen (_mu_datetime_full_month[i]));
+         return i;
+       }
+    }
+  return -1;
+}
+
+int
+get_num (const char *str, char **endp, int ndig, int minval, int maxval,
+        int *pn)
+{
+  int x = 0;
+  int i;
+  
+  errno = 0;
+  for (i = 0; i < ndig && *str && mu_isdigit (*str); str++, i++)
+    x = x * 10 + *str - '0';
+
+  *endp = (char*) str;
+  if (i == 0)
+    return -1;
+  else if (pn)
+    *pn = i;
+  else if (i != ndig)
+    return -1;
+  if (x < minval || x > maxval)
+    return -1;
+  return x;
+}
+
+#define DT_YEAR  0x01
+#define DT_MONTH 0x02
+#define DT_MDAY  0x04
+#define DT_WDAY  0x08
+#define DT_HOUR  0x10
+#define DT_MIN   0x20
+#define DT_SEC   0x40
+
+#define ST_NON   -1
+#define ST_OPT   0
+#define ST_ALT   1
+
+struct save_input
+{
+  int state;
+  const char *input;
+};
+
+static int
+push_input (mu_list_t *plist, int state, const char *input)
+{
+  mu_list_t list = *plist;
+  struct save_input *inp = malloc (sizeof (*inp));
+  if (!inp)
+    return ENOMEM;
+  if (!list)
+    {
+      int rc = mu_list_create (&list);
+      if (rc)
+       {
+         free (inp);
+         return rc;
+       }
+      mu_list_set_destroy_item (list, mu_list_free_item);
+      *plist = list;
+    }
+  inp->state = state;
+  inp->input = input;
+  return mu_list_push (list, (void*)inp);
+}
+
+static int
+peek_state (mu_list_t list, int *state, const char **input)
+{
+  int rc;
+  struct save_input *inp;
+
+  rc = mu_list_tail (list, (void**)&inp);
+  if (rc)
+    return rc;
+  *state = inp->state;
+  if (input)
+    *input = inp->input;
+  return 0;
+}      
+
+static int
+pop_input (mu_list_t list, int *state, const char **input)
+{
+  int rc;
+  struct save_input *inp;
+
+  rc = mu_list_pop (list, (void**)&inp);
+  if (rc)
+    return rc;
+  *state = inp->state;
+  if (input)
+    *input = inp->input;
+  return 0;
+}
+
+static int
+bracket_to_state (int c)
+{
+  switch (c)
+    {
+    case '[':
+    case ']':
+      return ST_OPT;
+    case '(':
+    case ')':
+      return ST_ALT;
+    }
+  return ST_NON;
+}
+
+static int
+state_to_closing_bracket (int st)
+{
+  switch (st)
+    {
+    case ST_OPT:
+      return ']';
+    case ST_ALT:
+      return ')';
+    }
+  return '?';
+}
+
+static int
+scan_recovery (const char *fmt, mu_list_t *plist, int skip_alt,
+              const char **endp,
+              const char **input)
+{
+  int c, rc = 0;
+  int nesting_level = 1;
+  int st;
+  const char *p;
+  
+  while (*fmt)
+    {
+      c = *fmt++;
+      
+      if (c == '%')
+       {
+         c = *fmt++;
+         if (!c)
+           {
+             mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+                       ("%s:%d: error in format: %% at the end of input",
+                        __FILE__, __LINE__));
+             rc = MU_ERR_FORMAT;
+             break;
+           }
+             
+         switch (c)
+           {
+           case '[':
+           case '(':
+             nesting_level++;
+             rc = push_input (plist, bracket_to_state (c), NULL);
+             break;
+             
+           case ')':
+           case ']':
+             rc = pop_input (*plist, &st, &p);
+             if (rc || st != bracket_to_state (c))
+               {
+                 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+                           ("%s:%d: error in format: %%%c out of context",
+                            __FILE__, __LINE__, c));
+                 rc = MU_ERR_FORMAT;
+                 break;
+               }
+             if (--nesting_level == 0)
+               {
+                 *endp = fmt;
+                 if (skip_alt)
+                   return 0;
+                 *input = p;
+                 if (st == ST_ALT)
+                   {
+                     if (*fmt == '%' && (fmt[1] == '|' || fmt[1] == ']'))
+                       return 0;
+                     return MU_ERR_PARSE; /* No match found */
+                   }
+                 return 0;
+               }
+             break;
+
+           case '|':
+             if (skip_alt)
+               continue;
+             if (nesting_level == 1)
+               {
+                 *endp = fmt;
+                 return peek_state (*plist, &st, input);
+               }
+             break;
+
+           case '\\':
+             if (*++fmt == 0)
+               {
+                 peek_state (*plist, &st, NULL);
+                 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+                           ("%s:%d: error in format: missing closing %%%c",
+                            __FILE__, __LINE__,
+                            state_to_closing_bracket (st)));
+                 return MU_ERR_FORMAT;           
+               }
+           }
+       }
+    }
+  
+  peek_state (*plist, &st, NULL);
+  mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+           ("%s:%d: error in format: missing closing %%%c",
+            __FILE__, __LINE__,
+            state_to_closing_bracket (st)));
+  return MU_ERR_FORMAT;                  
+}
+
+int
+mu_scan_datetime (const char *input, const char *fmt,
+                 struct tm *tm, struct mu_timezone *tz, char **endp)
+{
+  int rc = 0;
+  char *p;
+  int n;
+  int c;
+  int st;
+  int recovery = 0;
+  int eof_ok = 0;
+  int datetime_parts = 0;
+  mu_list_t save_input_list = NULL;
+  
+  memset (tm, 0, sizeof *tm);
+#ifdef HAVE_STRUCT_TM_TM_ISDST
+  tm->tm_isdst = -1;   /* unknown. */
+#endif
+  /* provide default timezone, in case it is not supplied in input */
+  if (tz)
+    {
+      memset (tz, 0, sizeof *tz);
+      tz->utc_offset = mu_utc_offset ();
+    }
+
+  /* Skip leading whitespace */
+  input = mu_str_skip_class (input, MU_CTYPE_BLANK);
+  for (; *fmt && rc == 0; fmt++)
+    {
+      if (mu_isspace (*fmt))
+       {
+         fmt = mu_str_skip_class (fmt, MU_CTYPE_BLANK);
+         input = mu_str_skip_class (input, MU_CTYPE_BLANK);
+         if (!*fmt)
+           break;
+       }
+      eof_ok = 0;
+      
+      if (*fmt == '%')
+       {
+         c = *++fmt;
+         if (!c)
+           {
+             mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+                       ("%s:%d: error in format: %% at the end of input",
+                        __FILE__, __LINE__));
+             rc = MU_ERR_FORMAT;
+             break;
+           }
+         
+         switch (c)
+           {
+           case 'a':
+             /* The abbreviated weekday name. */
+             n = _mu_short_weekday_string (input);
+             if (n == -1)
+               rc = MU_ERR_PARSE;
+             else
+               {
+                 tm->tm_wday = n;
+                 datetime_parts |= DT_WDAY;
+                 input += 3;
+               }
+             break;
+                 
+           case 'A':
+             /* The full weekday name. */
+             n = _mu_full_weekday_string (input, &p);
+             if (n == -1)
+               rc = MU_ERR_PARSE;
+             else
+               {
+                 tm->tm_wday = n;
+                 datetime_parts |= DT_WDAY;
+                 input = p;
+               }
+             break;
+             
+           case 'b':
+             /* The abbreviated month name. */
+             n = _mu_short_month_string (input);
+             if (n == -1)
+               rc = MU_ERR_PARSE;
+             else
+               {
+                 tm->tm_mon = n;
+                 datetime_parts |= DT_MONTH;
+                 input += 3;
+               }
+             break;
+
+           case 'B':
+             /* The full month name. */
+             n = _mu_full_month_string (input, &p);
+             if (n == -1)
+               rc = MU_ERR_PARSE;
+             else
+               {
+                 tm->tm_mon = n;
+                 datetime_parts |= DT_MONTH;
+                 input = p;
+               }
+             break;
+             
+           case 'd':
+             /* The day of the month as a decimal number (range 01 to 31). */
+             n = get_num (input, &p, 2, 1, 31, NULL);
+             if (n == -1)
+               rc = MU_ERR_PARSE;
+             else
+               {
+                 tm->tm_mday = n;
+                 datetime_parts |= DT_MDAY;
+                 input = p;
+               }
+             break;
+             
+           case 'e':
+             /* Like %d, the day of the month as a decimal number, but a
+                leading zero is replaced by a space. */
+             {
+               int ndig;
+               
+               n = get_num (input, &p, 2, 1, 31, &ndig);
+               if (n == -1)
+                 rc = MU_ERR_PARSE;
+               else
+                 {
+                   tm->tm_mday = n;
+                   datetime_parts |= DT_MDAY;
+                   input = p;
+                 }
+             }
+             break;
+             
+           case 'H':
+             /* The hour as a decimal number using a 24-hour clock (range
+                00 to 23). */
+             n = get_num (input, &p, 2, 0, 23, NULL);
+             if (n == -1)
+               rc = MU_ERR_PARSE;
+             else
+               {
+                 tm->tm_hour = n;
+                 datetime_parts |= DT_HOUR;
+                 input = p;
+               }
+             break;
+             
+           case 'm':
+             /* The month as a decimal number (range 01 to 12). */
+             n = get_num (input, &p, 2, 1, 12, NULL);
+             if (n == -1)
+               rc = MU_ERR_PARSE;
+             else
+               {
+                 tm->tm_mon = n - 1;
+                 datetime_parts |= DT_MONTH;
+                 input = p;
+               }
+             break;
+             
+           case 'M':
+             /* The minute as a decimal number (range 00 to 59). */
+             n = get_num (input, &p, 2, 0, 59, NULL);
+             if (n == -1)
+               rc = MU_ERR_PARSE;
+             else
+               {
+                 tm->tm_min = n;
+                 datetime_parts |= DT_MIN;
+                 input = p;
+               }
+             break;
+             
+           case 'S':
+             /* The second as a decimal number (range 00 to 60) */
+             n = get_num (input, &p, 2, 0, 60, NULL);
+             if (n == -1)
+               rc = MU_ERR_PARSE;
+             else
+               {
+                 tm->tm_sec = n;
+                 datetime_parts |= DT_SEC;
+                 input = p;
+               }
+             break;
+             
+           case 'Y':
+             /* The year as a decimal number including the century. */
+             errno = 0;
+             n = strtoul (input, &p, 10);
+             if (errno || p == input)
+               rc = MU_ERR_PARSE;
+             else
+               {
+                 tm->tm_year = n - 1900;
+                 datetime_parts |= DT_YEAR;
+                 input = p;
+               }
+             break;
+                 
+           case 'z':
+             /* The time-zone as hour offset from GMT */
+             {
+               int sign = 1;
+               int hr;
+               
+               if (*input == '+')
+                 input++;
+               else if (*input == '-')
+                 {
+                   input++;
+                   sign = -1;
+                 }
+               n = get_num (input, &p, 2, 0, 11, NULL);
+               if (n == -1)
+                 rc = MU_ERR_PARSE;
+               else
+                 {
+                   input = p;
+                   hr = n;
+                   n = get_num (input, &p, 2, 0, 59, NULL);
+                   if (n == -1)
+                     rc = MU_ERR_PARSE;
+                   else
+                     {
+                       input = p;
+                       if (tz)
+                         tz->utc_offset = sign * (hr * 60 + n) * 60;
+                     }
+                 }
+             }
+             break;
+                     
+           case '%':
+             if (*input == '%')
+               input++;
+             else
+               rc = MU_ERR_PARSE;
+             break;
+
+             rc = push_input (&save_input_list, ST_ALT, (void*)input);
+             break;
+             
+           case '(':
+           case '[':
+             rc = push_input (&save_input_list, bracket_to_state (c),
+                              (void*)input);
+             break;
+
+           case ')':
+           case ']':
+             if (pop_input (save_input_list, &st, NULL))
+               {
+                 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+                           ("%s:%d: error in format: unbalanced %%%c near %s",
+                            __FILE__, __LINE__, c, fmt));
+                 rc = MU_ERR_FORMAT;
+               }
+             else if (st != bracket_to_state (c))
+               {
+                 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+                           ("%s:%d: error in format: %%%c out of context",
+                            __FILE__, __LINE__, c));
+                 rc = MU_ERR_FORMAT;
+               }
+             break;
+
+           case '|':
+             rc = scan_recovery (fmt, &save_input_list, 1, &fmt, NULL);
+             if (rc == 0)
+               fmt--;
+             break;
+             
+           case '$':
+             eof_ok = 1;
+             break;
+
+           case '\\':
+             c = *++fmt;
+             if (!c)
+               {
+                 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+                           ("%s:%d: error in format: %% at the end of input",
+                            __FILE__, __LINE__));
+                 rc = MU_ERR_FORMAT;
+               }
+             else if (c == *input)
+               input++;
+             else
+               rc = MU_ERR_PARSE;
+             break;
+
+           case '?':
+             input++;
+             break;
+             
+           default:
+             mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+                       ("%s:%d: error in format: unrecognized conversion type"
+                        " near %s",
+                        __FILE__, __LINE__, fmt));
+             rc = MU_ERR_FORMAT;
+             break;
+           }
+
+         if (eof_ok && rc == 0 && *input == 0)
+           break;
+       }
+      else if (!recovery && *input != *fmt)
+       rc = MU_ERR_PARSE;
+      else
+       input++;
+
+      if (rc == MU_ERR_PARSE && !mu_list_is_empty (save_input_list))
+       {
+         rc = scan_recovery (fmt, &save_input_list, 0, &fmt, &input);
+         if (rc == 0)
+           --fmt;
+       }
+    }
+
+  if (!mu_list_is_empty (save_input_list))
+    {
+      mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+               ("%s:%d: error in format: closing bracket missing",
+                __FILE__, __LINE__));
+      rc = MU_ERR_FORMAT;
+    }
+  mu_list_destroy (&save_input_list);
+  
+  if (rc == 0 && recovery)
+    rc = MU_ERR_PARSE;
+  
+  if (!eof_ok && rc == 0 && *input == 0 && *fmt)
+    rc = MU_ERR_PARSE;
+
+  if ((datetime_parts & (DT_YEAR|DT_MONTH|DT_MDAY)) ==
+      (DT_YEAR|DT_MONTH|DT_MDAY))
+    {
+      if (!(datetime_parts & DT_WDAY))
+       tm->tm_wday = mu_datetime_dayofweek (tm->tm_year + 1900,
+                                            tm->tm_mon + 1, tm->tm_mday);
+      tm->tm_yday = mu_datetime_dayofyear (tm->tm_year + 1900,
+                                          tm->tm_mon + 1, tm->tm_mday) - 1;
+    }
+  
+  if (endp)
+    *endp = (char*) input;
+  
+  return rc;
+}
diff --git a/libmailutils/datetime/streamftime.c 
b/libmailutils/datetime/streamftime.c
new file mode 100644
index 0000000..e67d7d4
--- /dev/null
+++ b/libmailutils/datetime/streamftime.c
@@ -0,0 +1,411 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 1999, 2000, 2001, 2002, 2007, 2009, 2010, 2011 Free
+   Software Foundation, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General
+   Public License along with this library.  If not, see
+   <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mailutils/diag.h>
+#include <mailutils/datetime.h>
+#include <mailutils/util.h>
+#include <mailutils/stream.h>
+#include <mailutils/errno.h>
+#include <mailutils/cstr.h>
+#include <mailutils/cctype.h>
+
+#define ISO_8601_START_WDAY 1 /* Monday */
+#define ISO_8601_MAX_WDAY   4 /* Thursday */
+#define MAXDAYS 366 /* Max. number of days in a year */
+#define ISO_8601_OFF ((MAXDAYS / 7 + 2) * 7)
+
+int
+ISO_8601_weekdays (int yday, int wday)
+{
+  return (yday
+         - (yday - wday + ISO_8601_MAX_WDAY + ISO_8601_OFF) % 7
+         + ISO_8601_MAX_WDAY - ISO_8601_START_WDAY);
+}
+
+int
+mu_c_streamftime (mu_stream_t str, const char *fmt, struct tm *input_tm,
+                 struct mu_timezone *tz)
+{
+  int rc = 0;
+  struct tm tm;
+
+  /* Copy input TM because it might have been received from gmtime and
+     the fmt might result in further calls to gmtime which will clobber
+     it. */
+  tm = *input_tm;
+  while (*fmt && rc == 0)
+    {
+      size_t len = strcspn (fmt, "%");
+      if (len)
+       {
+         rc = mu_stream_write (str, fmt, len, NULL);
+         if (rc)
+           break;
+       }
+
+      fmt += len;
+
+    restart:
+      if (!*fmt || !*++fmt)
+       break;
+
+      switch (*fmt)
+       {
+       case 'a':
+         /* The abbreviated weekday name. */
+         if (tm.tm_wday < 0 || tm.tm_wday > 6)
+           rc = ERANGE;
+         else
+           rc = mu_stream_write (str, _mu_datetime_short_wday[tm.tm_wday],
+                                 strlen (_mu_datetime_short_wday[tm.tm_wday]),
+                                 NULL);
+         break;
+         
+       case 'A':
+         /* The full weekday name. */
+         if (tm.tm_wday < 0 || tm.tm_wday > 6)
+           rc = ERANGE;
+         else
+           rc = mu_stream_write (str, _mu_datetime_full_wday[tm.tm_wday],
+                                 strlen (_mu_datetime_full_wday[tm.tm_wday]),
+                                 NULL);
+         break;
+         
+       case 'b':
+       case 'h':
+         /* The abbreviated month name. */
+         if (tm.tm_mon < 0 || tm.tm_mon > 11)
+           rc = ERANGE;
+         else
+           rc = mu_stream_write (str, _mu_datetime_short_month[tm.tm_mon],
+                                 strlen (_mu_datetime_short_month[tm.tm_mon]),
+                                 NULL);
+         break;
+         
+       case 'B':
+         /* The full month name. */
+         if (tm.tm_mon < 0 || tm.tm_mon > 11)
+           rc = ERANGE;
+         else
+           rc = mu_stream_write (str, _mu_datetime_full_month[tm.tm_mon],
+                                 strlen (_mu_datetime_full_month[tm.tm_mon]),
+                                 NULL);
+         break;
+         
+       case 'c':
+         /* The preferred date and time representation. */
+         rc = mu_c_streamftime (str, "%a %b %e %H:%M:%S %Y", &tm, tz);
+         break;
+           
+       case 'C':
+         /* The century number (year/100) as a 2-digit integer. */
+         rc = mu_stream_printf (str, "%02d", (tm.tm_year + 1900) / 100);
+         break;
+         
+       case 'd':
+         /* The day of the month as a decimal number (range 01 to 31). */
+         if (tm.tm_mday < 1 || tm.tm_mday > 31)
+           rc = ERANGE;
+         else
+           rc = mu_stream_printf (str, "%02d", tm.tm_mday);
+         break;
+         
+       case 'D':
+         /* Equivalent to %m/%d/%y. */
+         rc = mu_c_streamftime (str, "%m/%d/%y", &tm, tz);
+         break;
+         
+       case 'e':
+         /* Like %d, the day of the month as a decimal number, but a leading
+            zero is replaced by a space. */
+         if (tm.tm_mday < 1 || tm.tm_mday > 31)
+           rc = ERANGE;
+         else
+           rc = mu_stream_printf (str, "%2d", tm.tm_mday);
+         break;
+         
+       case 'E':
+         /* Modifier. The Single Unix Specification mentions %Ec, %EC, %Ex,
+            %EX, %Ey, and %EY, which are supposed to use a corresponding
+            locale-dependent alternative representation.
+            A no-op in POSIX locale */
+         goto restart;
+         
+       case 'F':
+         /* Equivalent to %Y-%m-%d (the ISO 8601 date format). */
+         rc = mu_c_streamftime (str, "%Y-%m-%d", &tm, tz);
+         break;
+                 
+       case 'V':
+         /* The ISO 8601:1988 week number of the current year as a decimal
+            number range 01 to 53, where week 1 is the first week that has
+            at least 4 days in the current year, and with Monday as the
+            first day of the week.
+         */
+       case 'G':
+         /* The ISO 8601 year with century as a decimal number.  The 4-digit
+            year corresponding to the ISO week number (see  %V).  This has
+            the same format and value as %y, except that if the ISO week
+            number belongs to the previous or next year, that year is used
+            instead.
+         */
+       case 'g':
+         /* Like  %G, but without century, that is, with a 2-digit year
+            (00-99). */
+         {
+           int year = tm.tm_year + 1900;
+           int days = ISO_8601_weekdays (tm.tm_yday, tm.tm_wday);
+
+           if (days < 0)
+             {
+               days = ISO_8601_weekdays (tm.tm_yday +
+                                         mu_datetime_year_days (year - 1),
+                                         tm.tm_wday);
+               year--;
+             }
+           else
+             {
+               int d = ISO_8601_weekdays (tm.tm_yday -
+                                          mu_datetime_year_days (year),
+                                          tm.tm_wday);
+               if (d >= 0)
+                 {
+                   year++;
+                   days = d;
+                 }
+             }
+
+           switch (*fmt)
+             {
+             case 'V':
+               rc = mu_stream_printf (str, "%02d", days / 7 + 1);
+               break;
+
+             case 'G':
+               rc = mu_stream_printf (str, "%4d", year);
+               break;
+
+             case 'g':
+               rc = mu_stream_printf (str, "%02d", year % 100);
+             }
+         }
+         break;
+         
+       case 'H':
+         /* The hour as a decimal number using a 24-hour clock (range 00 to
+            23). */
+         rc = mu_stream_printf (str, "%02d", tm.tm_hour);
+         break;
+         
+       case 'I':
+         /* The hour as a decimal number using a 12-hour clock (range 01 to
+            12). */
+         {
+           unsigned n = tm.tm_hour % 12;
+           rc = mu_stream_printf (str, "%02d", n == 0 ? 12 : n);
+         }
+         break;
+
+       case 'j':
+         /* The day of the year as a decimal number (range 001 to 366). */
+         rc = mu_stream_printf (str, "%03d", tm.tm_yday + 1);
+         break;
+         
+       case 'k':
+         /* The hour (24-hour clock) as a decimal number (range 0 to 23);
+            single digits are preceded by a blank. */
+         rc = mu_stream_printf (str, "%2d", tm.tm_hour);
+         break;
+         
+       case 'l':
+         /* The hour (12-hour clock) as a decimal number (range 1 to 12);
+            single digits are preceded by a blank. */
+         {
+           unsigned n = tm.tm_hour % 12;
+           rc = mu_stream_printf (str, "%2d", n == 0 ? 12 : n);
+         }
+         break;
+         
+       case 'm':
+         /* The month as a decimal number (range 01 to 12). */
+         rc = mu_stream_printf (str, "%02d", tm.tm_mon + 1);
+         break;
+                                  
+       case 'M':
+         /* The minute as a decimal number (range 00 to 59). */
+         rc = mu_stream_printf (str, "%02d", tm.tm_min);
+         break;
+         
+       case 'n':
+         /* A newline character. */
+         rc = mu_stream_write (str, "\n", 1, NULL);
+         break;
+         
+       case 'O':
+         /* Modifier.  The Single Unix Specification mentions %Od, %Oe, %OH,
+            %OI, %Om, %OM, %OS, %Ou, %OU, %OV, %Ow, %OW, and %Oy, which are
+            supposed to use alternative numeric symbols.
+
+            Hardly of any use for our purposes, hence a no-op. */
+         goto restart;
+         
+       case 'p':
+         /* Either "AM" or "PM" according to the given time value.
+            Noon is treated as "PM" and midnight as "AM". */
+         rc = mu_stream_write (str,
+                               tm.tm_hour < 12 ? "AM" : "PM",
+                               2, NULL);
+         break;
+                               
+       case 'P':
+         /* Like %p but in lowercase: "am" or "pm". */
+         rc = mu_stream_write (str,
+                               tm.tm_hour < 12 ? "am" : "pm",
+                               2, NULL);
+         break;
+         
+       case 'r':
+         /* The time in a.m. or p.m. notation, i.e. %I:%M:%S %p. */
+         rc = mu_c_streamftime (str, "%I:%M:%S %p", &tm, tz);
+         break;
+         
+       case 'R':
+         /* The time in 24-hour notation (%H:%M) */
+         rc = mu_c_streamftime (str, "%H:%M", &tm, tz);
+         break;
+         
+       case 's':
+         /* The number of seconds since the Epoch */
+         rc = mu_stream_printf (str, "%lu",
+                                (unsigned long) mu_tm2time (&tm, tz));
+         break;
+         
+       case 'S':
+         /* The second as a decimal number (range 00 to 60) */
+         rc = mu_stream_printf (str, "%02d", tm.tm_sec);
+         break;
+         
+       case 't':
+         /* A tab character. */
+         rc = mu_stream_write (str, "\t", 1, NULL);
+         break;
+         
+       case 'T':
+         /* The time in 24-hour notation (%H:%M:%S) */
+         rc = mu_c_streamftime (str, "%H:%M:%S", &tm, tz);
+         break;
+         
+       case 'u':
+         /* The day of the week as a decimal, range 1 to 7, Monday being 1.
+          */
+         rc = mu_stream_printf (str, "%1d",
+                                tm.tm_wday == 0 ? 7 : tm.tm_wday);
+         break;
+         
+       case 'U':
+         /* The week number of the current year as a decimal number, range
+            00 to 53, starting with the first Sunday as the first day of
+            week 01.
+         */
+         rc = mu_stream_printf (str, "%02d",
+                                (tm.tm_yday - tm.tm_wday + 7) / 7);
+         break;
+         
+       case 'w':
+         /* The day of the week as a decimal, range 0 to 6, Sunday being 0.
+          */
+         rc = mu_stream_printf (str, "%01d", tm.tm_wday);
+         break;
+         
+       case 'W':
+         /* The week number of the current year as a decimal number, range
+            00 to 53, starting with the first Monday as the first day of
+            week 01. */
+         rc = mu_stream_printf (str, "%02d", 
+                        (tm.tm_yday - (tm.tm_wday - 1 + 7) % 7 + 7) / 7);
+         break;
+
+         /* The preferred date representation without the time:
+            equivalent to %D */
+       case 'x':
+         rc = mu_c_streamftime (str, "%m/%d/%y", &tm, tz);
+         break;
+         
+       case 'X':
+         /* The preferred date representation without the date */
+         rc = mu_c_streamftime (str, "%H:%M:%S", &tm, tz);
+         break;
+
+       case 'y':
+         /* The year as a decimal number without a century (range 00 to 99).
+          */
+         rc = mu_stream_printf (str, "%02d", (tm.tm_year + 1900) % 100);
+         break;
+         
+       case 'Y':
+         /* The year as a decimal number including the century. */
+         rc = mu_stream_printf (str, "%d", tm.tm_year + 1900);
+         break;
+         
+       case 'z':
+       case 'Z':
+         /* The time-zone as hour offset from GMT, for formatting RFC-822
+            dates (e.g. "%a, %d %b %Y %H:%M:%S %z") */
+         {
+           int utc_off = tz ? tz->utc_offset : mu_utc_offset ();
+           int sign;
+           if (utc_off < 0)
+             {
+               sign = '-';
+               utc_off = - utc_off;
+             }
+           else
+             sign = '+';
+           utc_off /= 60;
+           rc = mu_stream_printf (str, "%c%02u%02u", sign,
+                                  utc_off / 60, utc_off % 60);
+         }
+         break;
+         
+       case '%':
+         /* A literal '%' character. */
+         rc = mu_stream_write (str, "%", 1, NULL);
+         break;
+
+       case '$':
+         /* Ignored for compatibilty with mu_scan_datetime */
+         break;
+         
+       case '+':
+         /* Not supported (date and time in date(1) format. */
+       default:
+         rc = mu_stream_write (str, fmt-1, 2, NULL);
+         break;
+       }
+      fmt++;
+    }
+  /* Restore input tm */
+  *input_tm = tm;
+  return rc;
+}
diff --git a/libmailutils/base/strftime.c b/libmailutils/datetime/strftime.c
similarity index 97%
rename from libmailutils/base/strftime.c
rename to libmailutils/datetime/strftime.c
index 5c1d89e..01b6faf 100644
--- a/libmailutils/base/strftime.c
+++ b/libmailutils/datetime/strftime.c
@@ -18,7 +18,7 @@
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
-#include <mailutils/util.h>
+#include <mailutils/datetime.h>
 #include <mailutils/stream.h>
 #include <mailutils/errno.h>
 #include <mailutils/cstr.h>
diff --git a/libmailutils/diag/muerror.c b/libmailutils/datetime/tab.c
similarity index 56%
copy from libmailutils/diag/muerror.c
copy to libmailutils/datetime/tab.c
index e8a95a6..2ff9293 100644
--- a/libmailutils/diag/muerror.c
+++ b/libmailutils/datetime/tab.c
@@ -1,6 +1,6 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 1999, 2000, 2001, 2005, 2007, 2010, 2011 Free Software
-   Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2007, 2009, 2010, 2011 Free
+   Software Foundation, Inc.
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -20,32 +20,26 @@
 # include <config.h>
 #endif
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <syslog.h>
-#include <string.h>
-#include <mailutils/error.h>
-
-
-/* Historic shortcuts for mu_diag_ functions */
-
-int
-mu_verror (const char *fmt, va_list ap)
+const char *_mu_datetime_short_month[] =
 {
-  mu_diag_voutput (MU_DIAG_ERROR, fmt, ap);
-  return 0;
-}
+  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
 
-int
-mu_error (const char *fmt, ...)
+const char *_mu_datetime_full_month[] =
 {
-  va_list ap;
-  va_start (ap, fmt);
-  mu_verror (fmt, ap);
-  va_end (ap);
-  return 0;
-}
-
-
+  "January", "February", "March", "April",
+  "May", "June", "July", "August",
+  "September", "October", "November", "December"
+};
 
+const char *_mu_datetime_short_wday[] =
+{
+  "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+};
 
+const char *_mu_datetime_full_wday[] =
+{
+  "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
+  "Friday", "Saturday"
+};
diff --git a/examples/muemail.c b/libmailutils/datetime/unixtime.c
similarity index 57%
copy from examples/muemail.c
copy to libmailutils/datetime/unixtime.c
index 39a8099..a893117 100644
--- a/examples/muemail.c
+++ b/libmailutils/datetime/unixtime.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 1999, 2000, 2001, 2007, 2010, 2011 Free Software
+   Copyright (C) 1999, 2000, 2001, 2007, 2009, 2010, 2011 Free Software
    Foundation, Inc.
 
    GNU Mailutils is free software; you can redistribute it and/or modify
@@ -18,32 +18,21 @@
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
-#include <stdlib.h>
-#include <stdio.h>
-#include <mailutils/util.h>
-#include "mailutils/libargp.h"
+#include <time.h>
+#include <mailutils/datetime.h>
 
-const char *capa[] = {
-  "address",
-  NULL
-};
+#define SECS_PER_DAY 86400
 
-int
-main (int argc, char *argv[])
-{
-  int arg = 1;
-
-  if (mu_app_init (NULL, capa, NULL, argc, argv, 0, &arg, NULL))
-    exit (1);
-
-  if (!argv[arg])
-    printf ("current user -> %s\n", mu_get_user_email (0));
-  else
-    {
-      for (; argv[arg]; arg++)
-        printf ("%s -> %s\n", argv[arg], mu_get_user_email (argv[arg]));
-    }
+#define JD_OF_EPOCH 2440588
 
-  return 0;
+/* Convert struct tm into time_t, taking into account timezone offset. */
+/* FIXME: Ignores DST */
+time_t
+mu_tm2time (struct tm *tm, struct mu_timezone *tz)
+{
+  int jd = mu_datetime_julianday (tm->tm_year + 1900, tm->tm_mon + 1,
+                                 tm->tm_mday);
+  return (jd - JD_OF_EPOCH) * SECS_PER_DAY +
+         (tm->tm_hour * 60 + tm->tm_min) * 60 + tm->tm_sec
+          - (tz ? tz->utc_offset : 0);
 }
-
diff --git a/mail/list.c b/libmailutils/datetime/utcoff.c
similarity index 67%
copy from mail/list.c
copy to libmailutils/datetime/utcoff.c
index b7ec73e..cfa3b89 100644
--- a/mail/list.c
+++ b/libmailutils/datetime/utcoff.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 1999, 2001, 2005, 2007, 2010, 2011 Free Software
+   Copyright (C) 1999, 2000, 2001, 2007, 2009, 2010, 2011 Free Software
    Foundation, Inc.
 
    GNU Mailutils is free software; you can redistribute it and/or modify
@@ -15,16 +15,18 @@
    You should have received a copy of the GNU General Public License
    along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
 
-#include "mail.h"
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <time.h>
 
-/*
- * l[ist]
- * *
- */
-
-int
-mail_list (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
+/* Convert time 0 at UTC to our localtime, that tells us the offset
+   of our current timezone from UTC. */
+time_t
+mu_utc_offset (void)
 {
-  mail_command_list ();
-  return 0;
+  time_t t = 0;
+  struct tm *tm = gmtime (&t);
+
+  return - mktime (tm);
 }
diff --git a/libmailutils/list/push.c b/libmailutils/datetime/yd.c
similarity index 79%
copy from libmailutils/list/push.c
copy to libmailutils/datetime/yd.c
index c6bead7..abdee16 100644
--- a/libmailutils/list/push.c
+++ b/libmailutils/datetime/yd.c
@@ -12,18 +12,18 @@
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General
-   Public License along with this library.  If not, see 
+   Public License along with this library.  If not, see
    <http://www.gnu.org/licenses/>. */
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
 #include <stdlib.h>
-#include <mailutils/sys/list.h>
-#include <mailutils/errno.h>
+#include <mailutils/datetime.h>
 
+/* Return number of days in year */
 int
-mu_list_push (mu_list_t list, void *item)
+mu_datetime_year_days (int year)
 {
-  return mu_list_append (list, item);
+  return mu_datetime_dayofyear (year, 12, 31);
 }
diff --git a/libmailutils/imapio/time.c b/libmailutils/imapio/time.c
index 02f0d8a..089a7db 100644
--- a/libmailutils/imapio/time.c
+++ b/libmailutils/imapio/time.c
@@ -19,7 +19,7 @@
 #include <mailutils/stream.h>
 #include <mailutils/errno.h>
 #include <mailutils/sys/imapio.h>
-#include <mailutils/util.h>
+#include <mailutils/datetime.h>
 
 int
 mu_imapio_send_time (struct _mu_imapio *io, struct tm *tm,
diff --git a/libmailutils/mailbox/msgenv.c b/libmailutils/mailbox/msgenv.c
index a478891..57f3a07 100644
--- a/libmailutils/mailbox/msgenv.c
+++ b/libmailutils/mailbox/msgenv.c
@@ -28,6 +28,7 @@
 #include <mailutils/errno.h>
 #include <mailutils/envelope.h>
 #include <mailutils/util.h>
+#include <mailutils/datetime.h>
 #include <mailutils/header.h>
 #include <mailutils/mu_auth.h>
 #include <mailutils/address.h>
@@ -49,14 +50,14 @@ message_envelope_date (mu_envelope_t envelope, char *buf, 
size_t len,
 
   if (buf == NULL || len == 0)
     {
-      n = MU_ENVELOPE_DATE_LENGTH;
+      n = MU_DATETIME_FROM_LENGTH;
     }
   else
     {
-      char tmpbuf[MU_ENVELOPE_DATE_LENGTH+1];
+      char tmpbuf[MU_DATETIME_FROM_LENGTH+1];
       t = time (NULL);
       n = mu_strftime (tmpbuf, sizeof tmpbuf, 
-                       MU_ENVELOPE_DATE_FORMAT, localtime (&t));
+                       MU_DATETIME_FROM, localtime (&t));
       n = mu_cpystr (buf, tmpbuf, len);
     }
   if (pnwrite)
diff --git a/libmailutils/stream/message_stream.c 
b/libmailutils/stream/message_stream.c
index 4bbbe9e..557ce76 100644
--- a/libmailutils/stream/message_stream.c
+++ b/libmailutils/stream/message_stream.c
@@ -36,6 +36,7 @@
 #include <mailutils/body.h>
 #include <mailutils/stream.h>
 #include <mailutils/util.h>
+#include <mailutils/datetime.h>
 #include <mailutils/errno.h>
 #include <mailutils/error.h>
 #include <mailutils/cctype.h>
@@ -291,11 +292,11 @@ _message_open (mu_stream_t stream)
        {
          struct tm *tm;
          time_t t;
-         char date[80]; /* FIXME: This size is way too big */
+         char date[MU_DATETIME_FROM_LENGTH+1];
          
-         time(&t);
-         tm = gmtime(&t);
-         mu_strftime (date, sizeof (date), "%a %b %e %H:%M:%S %Y", tm);
+         time (&t);
+         tm = gmtime (&t);
+         mu_strftime (date, sizeof (date), MU_DATETIME_FROM, tm);
          env_date = strdup (date);
        }
       
diff --git a/libmailutils/tests/scantime.at b/libmailutils/tests/scantime.at
index 2db8540..a7a6f85 100644
--- a/libmailutils/tests/scantime.at
+++ b/libmailutils/tests/scantime.at
@@ -34,30 +34,30 @@ SCANTIME([Envelope (From) time],[envelope],
 [%a %b %e %H:%M:%S %Y],
 [Tue May  3 13:25:26 2011
 Fri Nov 11 11:55:01 2011],
-[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=0
-sec=1,min=55,hour=11,mday=11,mon=10,year=111,wday=5,yday=315,tz=0
+[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=0
+sec=1,min=55,hour=11,mday=11,mon=10,year=111,wday=5,yday=314,tz=0
 ])
 
 SCANTIME([IMAP INTERNALDATE],[imap-internaldate],
 [%d-%b-%Y %H:%M:%S %z],
 [03-May-2011 13:25:26 +0100
 11-Nov-2011 11:55:01 +0100],
-[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=3600
-sec=1,min=55,hour=11,mday=11,mon=10,year=111,wday=5,yday=315,tz=3600
+[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=3600
+sec=1,min=55,hour=11,mday=11,mon=10,year=111,wday=5,yday=314,tz=3600
 ])
 
 SCANTIME([IMAP INTERNALDATE (optional time)],[imap-search],
 [%d-%b-%Y%$ %H:%M:%S %z],
 [03-May-2011 13:25:26 +0100
 03-May-2011],
-[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=3600
-sec=0,min=0,hour=0,mday=3,mon=4,year=111,wday=2,yday=123,tz=0
+[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=3600
+sec=0,min=0,hour=0,mday=3,mon=4,year=111,wday=2,yday=122,tz=0
 ])
 
 SCANTIME([RFC-822 Strict],[rfc822-strict],
 [%a, %d %b %Y %H:%M:%S %z],
 [Tue, 03 May 2011 13:25:26 +0200],
-[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
+[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
 ])
 
 SCANTIME([RFC-822],[rfc822],
@@ -66,10 +66,10 @@ SCANTIME([RFC-822],[rfc822],
 03 May 2011 13:25:26 +0200
 Tue, 03 May 2011 13:25 +0200
 03 May 2011 13:25 +0200],
-[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
-sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
-sec=0,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
-sec=0,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
+[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
+sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
+sec=0,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
+sec=0,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
 ])
 
 SCANTIME([Any char],[anychar],
@@ -78,23 +78,23 @@ SCANTIME([Any char],[anychar],
 Tue: 03 May 2011 13:25:26 +0200
 Tue; 03 May 2011 13:25:26 +0200
 Tue 03 May 2011 13:25:26 +0200],
-[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
-sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
-sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
-sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
+[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
+sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
+sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
+sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
 ])
 
 SCANTIME([Percent],[percent],
 [%d%%%b%%%Y %H:%M:%S %z],
 [03%May%2011 13:25:26 +0100],
-[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=3600
+[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=3600
 ])
 
 SCANTIME([Fixed WS],[fixws],
 [%d-%b-%Y%\ %H:%M:%S %z],
 [03-May-2011 13:25:26 +0100
 03-May-2011  13:25:26 +0100],
-[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=3600
+[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=3600
 ],
 [scantime: 2: parse failed near  13:25:26 +0100
 ])
@@ -104,15 +104,15 @@ SCANTIME([endp return],[endp],
 [Tue, 03 May 2011 13:25:26 +0100 other data
 ],
 [# 1: stopped at  other data
-sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=3600
+sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=3600
 ])
 
 SCANTIME([Optional blocks],[opt],
 [[%[%a, %]%d %b %Y %H:%M:%S %z]],
 [Tue, 03 May 2011 13:25:26 +0200
 03 May 2011 13:25:26 +0200],
-[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
-sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
+[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
+sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
 ])
 
 SCANTIME([Nested optional blocks],[nested-opt],
@@ -120,9 +120,9 @@ SCANTIME([Nested optional blocks],[nested-opt],
 [Tue, 03 May 2011 13:25:26 +0200
 Tue 03 May 2011 13:25:26 +0200
 03 May 2011 13:25:26 +0200],
-[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
-sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
-sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
+[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
+sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
+sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
 ])
 
 SCANTIME([Optional alternatives],[opt-alt],
@@ -131,9 +131,9 @@ SCANTIME([Optional alternatives],[opt-alt],
 Tue: 03 May 2011 13:25:26 +0200
 Tue 03 May 2011 13:25:26 +0200
 Tue; 03 May 2011 13:25:26 +0200],
-[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
-sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
-sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
+[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
+sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
+sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
 ],
 [scantime: 4: parse failed near ; 03 May 2011 13:25:26 +0200
 ])
@@ -145,9 +145,9 @@ Tue: 03 May 2011 13:25:26 +0200
 Tue/ 03 May 2011 13:25:26 +0200
 Tue 03 May 2011 13:25:26 +0200
 Tue; 03 May 2011 13:25:26 +0200],
-[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
-sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
-sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=123,tz=7200
+[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
+sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
+sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,yday=122,tz=7200
 ],
 [scantime: 4: parse failed near  03 May 2011 13:25:26 +0200
 scantime: 5: parse failed near ; 03 May 2011 13:25:26 +0200
diff --git a/libmailutils/tests/scantime.c b/libmailutils/tests/scantime.c
index 962a7b3..d889add 100644
--- a/libmailutils/tests/scantime.c
+++ b/libmailutils/tests/scantime.c
@@ -23,7 +23,7 @@
 #include <string.h>
 #include <mailutils/error.h>
 #include <mailutils/errno.h>
-#include <mailutils/util.h>
+#include <mailutils/datetime.h>
 #include <mailutils/stream.h>
 #include <mailutils/cctype.h>
 #include <mailutils/cstr.h>
@@ -92,8 +92,6 @@ main (int argc, char **argv)
       mu_printf 
("sec=%d,min=%d,hour=%d,mday=%d,mon=%d,year=%d,wday=%d,yday=%d,tz=%d\n",
                 tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mday, tm.tm_mon,
                 tm.tm_year, tm.tm_wday, tm.tm_yday, tz.utc_offset);
-                
-      /*mu_c_streamftime (mu_strout, "%c %z%n", &tm, &tz);*/
     }
   
   if (rc)
diff --git a/libmailutils/tests/strftime.c b/libmailutils/tests/strftime.c
index 5a57666..8866a60 100644
--- a/libmailutils/tests/strftime.c
+++ b/libmailutils/tests/strftime.c
@@ -23,7 +23,7 @@
 #include <string.h>
 #include <mailutils/error.h>
 #include <mailutils/errno.h>
-#include <mailutils/util.h>
+#include <mailutils/datetime.h>
 #include <mailutils/stream.h>
 #include <mailutils/cctype.h>
 #include <mailutils/cstr.h>
diff --git a/libmu_scm/mu_message.c b/libmu_scm/mu_message.c
index 14d8821..7f8342f 100644
--- a/libmu_scm/mu_message.c
+++ b/libmu_scm/mu_message.c
@@ -79,7 +79,7 @@ mu_scm_message_print (SCM message_smob, SCM port, 
scm_print_state * pstate)
   const char *p;
   size_t m_size = 0, m_lines = 0;
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   char datebuf[sizeof ("Mon Jan 01 00:00")]; /* Warning: length must be > 9 */
 
   mu_message_get_envelope (mum->msg, &env);
@@ -404,7 +404,7 @@ SCM_DEFINE_PUBLIC (scm_mu_message_get_envelope_date, 
"mu-message-get-envelope-da
   int status;
   const char *sdate;
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   
   SCM_ASSERT (mu_scm_is_message (mesg), mesg, SCM_ARG1, FUNC_NAME);
   msg = mu_scm_message_get (mesg);
diff --git a/libmu_scm/mu_scm.h b/libmu_scm/mu_scm.h
index 5e68e91..de946c4 100644
--- a/libmu_scm/mu_scm.h
+++ b/libmu_scm/mu_scm.h
@@ -38,6 +38,7 @@
 #include <mailutils/address.h>
 #include <mailutils/registrar.h>
 #include <mailutils/util.h>
+#include <mailutils/datetime.h>
 #include <mailutils/stream.h>
 #include <mailutils/debug.h>
 #include <mailutils/attribute.h>
diff --git a/libmu_sieve/actions.c b/libmu_sieve/actions.c
index c0a50d1..5f2ff51 100644
--- a/libmu_sieve/actions.c
+++ b/libmu_sieve/actions.c
@@ -188,7 +188,7 @@ mime_create_ds (mu_mime_t mime, mu_message_t orig)
   char datestr[80];
   time_t t = time (NULL);
   struct tm tm, *tmp;
-  mu_timezone tz;
+  struct mu_timezone tz;
   mu_envelope_t env;
   const char *p;
   
diff --git a/libproto/mbox/mbox.c b/libproto/mbox/mbox.c
index 42a35ef..559a480 100644
--- a/libproto/mbox/mbox.c
+++ b/libproto/mbox/mbox.c
@@ -29,6 +29,7 @@
 #include <mailutils/io.h>
 #include <mailutils/filter.h>
 #include <mailutils/cctype.h>
+#include <mailutils/datetime.h>
 
 #define ATTRIBUTE_IS_DELETED(flag)        (flag & MU_ATTRIBUTE_DELETED)
 #define ATTRIBUTE_IS_EQUAL(flag1, flag2)  (flag1 == flag2)
@@ -859,22 +860,23 @@ restore_date (mu_message_t msg, char **pret)
   mu_header_t hdr;
   const char *s;
   char *date = NULL;
-  time_t t;
+  struct tm tm;
+  struct mu_timezone tz;
   
   if (mu_message_get_header (msg, &hdr) == 0)
     mu_header_sget_value (hdr, MU_HEADER_DATE, &s);
 
-  if (s && mu_parse_date (s, &t, NULL))
+  if (s && mu_scan_datetime (s, MU_DATETIME_SCAN_RFC822, &tm, &tz, NULL) == 0)
     {
-      char datebuf[MU_ENVELOPE_DATE_LENGTH+1];
+      char datebuf[MU_DATETIME_FROM_LENGTH+1];
       
-      /* FIXME: 1. Preserve TZ info */
-      mu_strftime (datebuf, sizeof datebuf, MU_ENVELOPE_DATE_FORMAT,
-                  localtime (&t));
+      /* FIXME: Compensate for TZ differences. */
+      mu_strftime (datebuf, sizeof datebuf, MU_DATETIME_FROM, &tm);
       date = strdup (datebuf);
     }
   else
     {
+      time_t t;
       time (&t);
       date = strdup (ctime (&t));
     }
diff --git a/mail/from.c b/mail/from.c
index e4aeda2..ddfd952 100644
--- a/mail/from.c
+++ b/mail/from.c
@@ -208,7 +208,7 @@ hdr_date (struct header_call_args *args, void *data)
     {
       const char *p;
       struct tm tm;
-      mu_timezone tz;
+      struct mu_timezone tz;
       mu_envelope_t env;
       
       mu_message_get_envelope (args->msg, &env);
diff --git a/mail/mail.h b/mail/mail.h
index e1c9d4a..92b3582 100644
--- a/mail/mail.h
+++ b/mail/mail.h
@@ -71,6 +71,7 @@
 #include <mailutils/mailer.h>
 #include <mailutils/message.h>
 #include <mailutils/util.h>
+#include <mailutils/datetime.h>
 #include <mailutils/registrar.h>
 #include <mailutils/stream.h>
 #include <mailutils/url.h>
diff --git a/mh/mh.h b/mh/mh.h
index 81c717b..0d883b9 100644
--- a/mh/mh.h
+++ b/mh/mh.h
@@ -59,6 +59,7 @@
 #include <mailutils/prog.h>
 #include <mailutils/mh.h>
 #include <mailutils/stdstream.h>
+#include <mailutils/datetime.h>
 
 #include <mu_umaxtostr.h>
 
diff --git a/mh/mh_format.c b/mh/mh_format.c
index 0e51496..9633cdb 100644
--- a/mh/mh_format.c
+++ b/mh/mh_format.c
@@ -1160,7 +1160,7 @@ builtin_putnumf (struct mh_machine *mach)
 }
 
 static int
-_parse_date (struct mh_machine *mach, struct tm *tm, mu_timezone *tz)
+_parse_date (struct mh_machine *mach, struct tm *tm, struct mu_timezone *tz)
 {
   char *date = strobj_ptr (&mach->arg_str);
   const char *p = date;
@@ -1183,7 +1183,7 @@ static void
 builtin_sec (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   
   if (_parse_date (mach, &tm, &tz))
     return;
@@ -1196,7 +1196,7 @@ static void
 builtin_min (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   
   if (_parse_date (mach, &tm, &tz))
     return;
@@ -1209,7 +1209,7 @@ static void
 builtin_hour (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   
   if (_parse_date (mach, &tm, &tz))
     return;
@@ -1222,7 +1222,7 @@ static void
 builtin_wday (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   
   if (_parse_date (mach, &tm, &tz))
     return;
@@ -1235,7 +1235,7 @@ static void
 builtin_day (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   char buf[80];
   
   if (_parse_date (mach, &tm, &tz))
@@ -1251,7 +1251,7 @@ static void
 builtin_weekday (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   char buf[80];
   
   if (_parse_date (mach, &tm, &tz))
@@ -1268,7 +1268,7 @@ static void
 builtin_sday (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
 
   /*FIXME: more elaborate check needed */
   if (_parse_date (mach, &tm, &tz))
@@ -1282,7 +1282,7 @@ static void
 builtin_mday (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   
   if (_parse_date (mach, &tm, &tz))
     return;
@@ -1295,7 +1295,7 @@ static void
 builtin_yday (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   
   if (_parse_date (mach, &tm, &tz))
     return;
@@ -1308,7 +1308,7 @@ static void
 builtin_mon (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   
   if (_parse_date (mach, &tm, &tz))
     return;
@@ -1321,7 +1321,7 @@ static void
 builtin_month (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   char buf[80];
   
   if (_parse_date (mach, &tm, &tz))
@@ -1337,7 +1337,7 @@ static void
 builtin_lmonth (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   char buf[80];
   
   if (_parse_date (mach, &tm, &tz))
@@ -1353,7 +1353,7 @@ static void
 builtin_year (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   
   if (_parse_date (mach, &tm, &tz))
     return;
@@ -1366,7 +1366,7 @@ static void
 builtin_zone (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   
   if (_parse_date (mach, &tm, &tz))
     return;
@@ -1379,7 +1379,7 @@ static void
 builtin_tzone (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   
   if (_parse_date (mach, &tm, &tz))
     return;
@@ -1410,7 +1410,7 @@ static void
 builtin_szone (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
 
   /*FIXME: more elaborate check needed */
   if (_parse_date (mach, &tm, &tz))
@@ -1438,7 +1438,7 @@ static void
 builtin_dst (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
 
   if (_parse_date (mach, &tm, &tz))
     return;
@@ -1454,7 +1454,7 @@ static void
 builtin_clock (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
 
   if (_parse_date (mach, &tm, &tz))
     return;
@@ -1466,7 +1466,7 @@ void
 builtin_rclock (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   time_t now = time (NULL);
   
   if (_parse_date (mach, &tm, &tz))
@@ -1493,7 +1493,7 @@ static void
 date_cvt (struct mh_machine *mach, int pretty)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   char buf[80];
   int i, len;
   const char *tzname = NULL;
@@ -1567,7 +1567,7 @@ static void
 builtin_nodate (struct mh_machine *mach)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   
   mach->arg_num = _parse_date (mach, &tm, &tz);
 }
diff --git a/mh/sortm.c b/mh/sortm.c
index 841e4eb..4e6d052 100644
--- a/mh/sortm.c
+++ b/mh/sortm.c
@@ -336,7 +336,7 @@ static int
 _parse_822_date (char *date, time_t * timep)
 {
   struct tm tm;
-  mu_timezone tz;
+  struct mu_timezone tz;
   const char *p = date;
 
   if (mu_parse822_date_time (&p, date + strlen (date), &tm, &tz) == 0)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 314490e..201f63a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -133,7 +133,6 @@ libmailutils/stream/logstream.c
 libmailutils/server/ipsrv.c
 libmailutils/server/msrv.c
 
-libmailutils/mailbox/message.c
 libmailutils/mailbox/mbx_default.c
 libmailutils/mailer/mailer.c
 
diff --git a/readmsg/readmsg.c b/readmsg/readmsg.c
index 1ae2abc..367c746 100644
--- a/readmsg/readmsg.c
+++ b/readmsg/readmsg.c
@@ -179,13 +179,13 @@ print_unix_header (mu_message_t message)
   
   if (mu_envelope_sget_date (envelope, &buf))
     { 
-      char datebuf[MU_ENVELOPE_DATE_LENGTH+1];
+      char datebuf[MU_DATETIME_FROM_LENGTH+1];
       time_t t;
       struct tm *tm;
 
       t = time (NULL);
       tm = localtime (&t);
-      mu_strftime (datebuf, sizeof datebuf, "%a %b %d %H:%M:%S %Y", tm);
+      mu_strftime (datebuf, sizeof datebuf, MU_DATETIME_FROM, tm);
       buf = datebuf;
     }
 
diff --git a/readmsg/readmsg.h b/readmsg/readmsg.h
index 8bfa61f..3d29088 100644
--- a/readmsg/readmsg.h
+++ b/readmsg/readmsg.h
@@ -50,7 +50,7 @@
 #include <mailutils/error.h>
 #include <mailutils/envelope.h>
 #include <mailutils/wordsplit.h>
-#include <mailutils/util.h>
+#include <mailutils/datetime.h>
 
 int msglist (mu_mailbox_t mbox, int show_all, int argc, char **argv, int 
**set, int *n);
 


hooks/post-receive
-- 
GNU Mailutils



reply via email to

[Prev in Thread] Current Thread [Next in Thread]