Don't shadow the system() function
[oweals/gnunet.git] / src / util / time.c
index b82a1ba7c794b18847eab142e3f94386d89009f4..01a3cddd5adac5e316b9c0ac7cfea6d068b6f101 100644 (file)
@@ -1,10 +1,10 @@
 /*
      This file is part of GNUnet.
 /*
      This file is part of GNUnet.
-     (C) 2001, 2002, 2006, 2009 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2001-2013 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
@@ -24,7 +24,7 @@
  * @brief functions for handling time and time arithmetic
  */
 #include "platform.h"
  * @brief functions for handling time and time arithmetic
  */
 #include "platform.h"
-#include "gnunet_time_lib.h"
+#include "gnunet_util_lib.h"
 
 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
 
 
 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
 
@@ -45,6 +45,18 @@ GNUNET_TIME_set_offset (long long offset)
 }
 
 
 }
 
 
+/**
+ * Get the timestamp offset for this instance.
+ *
+ * @return the offset we currently skew the locale time by
+ */
+long long
+GNUNET_TIME_get_offset ()
+{
+  return timestamp_offset;
+}
+
+
 /**
  * Get the current time (works just as "time", just that we use the
  * unit of time that the cron-jobs use (and is 64 bit)).
 /**
  * Get the current time (works just as "time", just that we use the
  * unit of time that the cron-jobs use (and is 64 bit)).
@@ -58,9 +70,9 @@ GNUNET_TIME_absolute_get ()
   struct timeval tv;
 
   GETTIMEOFDAY (&tv, NULL);
   struct timeval tv;
 
   GETTIMEOFDAY (&tv, NULL);
-  ret.abs_value =
-      (uint64_t) (((uint64_t) tv.tv_sec * 1000LL) +
-                  ((uint64_t) tv.tv_usec / 1000LL)) + timestamp_offset;
+  ret.abs_value_us =
+      (uint64_t) (((uint64_t) tv.tv_sec * 1000LL * 1000LL) +
+                  ((uint64_t) tv.tv_usec)) + timestamp_offset;
   return ret;
 }
 
   return ret;
 }
 
@@ -90,7 +102,7 @@ GNUNET_TIME_absolute_get_zero_ ()
 
 
 /**
 
 
 /**
- * Return relative time of 1ms.
+ * Return relative time of 1us.
  */
 struct GNUNET_TIME_Relative
 GNUNET_TIME_relative_get_unit_ ()
  */
 struct GNUNET_TIME_Relative
 GNUNET_TIME_relative_get_unit_ ()
@@ -100,13 +112,24 @@ GNUNET_TIME_relative_get_unit_ ()
 }
 
 
 }
 
 
+/**
+ * Return relative time of 1ms.
+ */
+struct GNUNET_TIME_Relative
+GNUNET_TIME_relative_get_millisecond_ ()
+{
+  static struct GNUNET_TIME_Relative one = { 1000 };
+  return one;
+}
+
+
 /**
  * Return relative time of 1s.
  */
 struct GNUNET_TIME_Relative
 GNUNET_TIME_relative_get_second_ ()
 {
 /**
  * Return relative time of 1s.
  */
 struct GNUNET_TIME_Relative
 GNUNET_TIME_relative_get_second_ ()
 {
-  static struct GNUNET_TIME_Relative one = { 1000 };
+  static struct GNUNET_TIME_Relative one = { 1000 * 1000LL };
   return one;
 }
 
   return one;
 }
 
@@ -117,7 +140,7 @@ GNUNET_TIME_relative_get_second_ ()
 struct GNUNET_TIME_Relative
 GNUNET_TIME_relative_get_minute_ ()
 {
 struct GNUNET_TIME_Relative
 GNUNET_TIME_relative_get_minute_ ()
 {
-  static struct GNUNET_TIME_Relative one = { 60 * 1000 };
+  static struct GNUNET_TIME_Relative one = { 60 * 1000 * 1000LL };
   return one;
 }
 
   return one;
 }
 
@@ -128,7 +151,7 @@ GNUNET_TIME_relative_get_minute_ ()
 struct GNUNET_TIME_Relative
 GNUNET_TIME_relative_get_hour_ ()
 {
 struct GNUNET_TIME_Relative
 GNUNET_TIME_relative_get_hour_ ()
 {
-  static struct GNUNET_TIME_Relative one = { 60 * 60 * 1000 };
+  static struct GNUNET_TIME_Relative one = { 60 * 60 * 1000 * 1000LL };
   return one;
 }
 
   return one;
 }
 
@@ -164,16 +187,16 @@ GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
 {
   struct GNUNET_TIME_Absolute ret;
 
 {
   struct GNUNET_TIME_Absolute ret;
 
-  if (rel.rel_value == UINT64_MAX)
+  if (rel.rel_value_us == UINT64_MAX)
     return GNUNET_TIME_UNIT_FOREVER_ABS;
   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
 
     return GNUNET_TIME_UNIT_FOREVER_ABS;
   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
 
-  if (rel.rel_value + now.abs_value < rel.rel_value)
+  if (rel.rel_value_us + now.abs_value_us < rel.rel_value_us)
   {
     GNUNET_break (0);           /* overflow... */
     return GNUNET_TIME_UNIT_FOREVER_ABS;
   }
   {
     GNUNET_break (0);           /* overflow... */
     return GNUNET_TIME_UNIT_FOREVER_ABS;
   }
-  ret.abs_value = rel.rel_value + now.abs_value;
+  ret.abs_value_us = rel.rel_value_us + now.abs_value_us;
   return ret;
 }
 
   return ret;
 }
 
@@ -189,7 +212,7 @@ struct GNUNET_TIME_Relative
 GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1,
                           struct GNUNET_TIME_Relative t2)
 {
 GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1,
                           struct GNUNET_TIME_Relative t2)
 {
-  return (t1.rel_value < t2.rel_value) ? t1 : t2;
+  return (t1.rel_value_us < t2.rel_value_us) ? t1 : t2;
 }
 
 
 }
 
 
@@ -204,7 +227,7 @@ struct GNUNET_TIME_Relative
 GNUNET_TIME_relative_max (struct GNUNET_TIME_Relative t1,
                           struct GNUNET_TIME_Relative t2)
 {
 GNUNET_TIME_relative_max (struct GNUNET_TIME_Relative t1,
                           struct GNUNET_TIME_Relative t2)
 {
-  return (t1.rel_value > t2.rel_value) ? t1 : t2;
+  return (t1.rel_value_us > t2.rel_value_us) ? t1 : t2;
 }
 
 
 }
 
 
@@ -220,7 +243,7 @@ struct GNUNET_TIME_Absolute
 GNUNET_TIME_absolute_min (struct GNUNET_TIME_Absolute t1,
                           struct GNUNET_TIME_Absolute t2)
 {
 GNUNET_TIME_absolute_min (struct GNUNET_TIME_Absolute t1,
                           struct GNUNET_TIME_Absolute t2)
 {
-  return (t1.abs_value < t2.abs_value) ? t1 : t2;
+  return (t1.abs_value_us < t2.abs_value_us) ? t1 : t2;
 }
 
 
 }
 
 
@@ -235,7 +258,7 @@ struct GNUNET_TIME_Absolute
 GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1,
                           struct GNUNET_TIME_Absolute t2)
 {
 GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1,
                           struct GNUNET_TIME_Absolute t2)
 {
-  return (t1.abs_value > t2.abs_value) ? t1 : t2;
+  return (t1.abs_value_us > t2.abs_value_us) ? t1 : t2;
 }
 
 
 }
 
 
@@ -250,13 +273,13 @@ GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
 {
   struct GNUNET_TIME_Relative ret;
 
 {
   struct GNUNET_TIME_Relative ret;
 
-  if (future.abs_value == UINT64_MAX)
+  if (future.abs_value_us == UINT64_MAX)
     return GNUNET_TIME_UNIT_FOREVER_REL;
   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
 
     return GNUNET_TIME_UNIT_FOREVER_REL;
   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
 
-  if (now.abs_value > future.abs_value)
+  if (now.abs_value_us > future.abs_value_us)
     return GNUNET_TIME_UNIT_ZERO;
     return GNUNET_TIME_UNIT_ZERO;
-  ret.rel_value = future.abs_value - now.abs_value;
+  ret.rel_value_us = future.abs_value_us - now.abs_value_us;
   return ret;
 }
 
   return ret;
 }
 
@@ -273,11 +296,11 @@ GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
 {
   struct GNUNET_TIME_Relative ret;
 
 {
   struct GNUNET_TIME_Relative ret;
 
-  if (end.abs_value == UINT64_MAX)
+  if (end.abs_value_us == UINT64_MAX)
     return GNUNET_TIME_UNIT_FOREVER_REL;
     return GNUNET_TIME_UNIT_FOREVER_REL;
-  if (end.abs_value < start.abs_value)
+  if (end.abs_value_us < start.abs_value_us)
     return GNUNET_TIME_UNIT_ZERO;
     return GNUNET_TIME_UNIT_ZERO;
-  ret.rel_value = end.abs_value - start.abs_value;
+  ret.rel_value_us = end.abs_value_us - start.abs_value_us;
   return ret;
 }
 
   return ret;
 }
 
@@ -294,10 +317,10 @@ GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute whence)
   struct GNUNET_TIME_Relative ret;
 
   now = GNUNET_TIME_absolute_get ();
   struct GNUNET_TIME_Relative ret;
 
   now = GNUNET_TIME_absolute_get ();
-  GNUNET_assert (whence.abs_value != UINT64_MAX);
-  if (whence.abs_value > now.abs_value)
+  GNUNET_assert (whence.abs_value_us != UINT64_MAX);
+  if (whence.abs_value_us > now.abs_value_us)
     return GNUNET_TIME_UNIT_ZERO;
     return GNUNET_TIME_UNIT_ZERO;
-  ret.rel_value = now.abs_value - whence.abs_value;
+  ret.rel_value_us = now.abs_value_us - whence.abs_value_us;
   return ret;
 }
 
   return ret;
 }
 
@@ -314,14 +337,14 @@ GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
 {
   struct GNUNET_TIME_Absolute ret;
 
 {
   struct GNUNET_TIME_Absolute ret;
 
-  if ((start.abs_value == UINT64_MAX) || (duration.rel_value == UINT64_MAX))
+  if ((start.abs_value_us == UINT64_MAX) || (duration.rel_value_us == UINT64_MAX))
     return GNUNET_TIME_UNIT_FOREVER_ABS;
     return GNUNET_TIME_UNIT_FOREVER_ABS;
-  if (start.abs_value + duration.rel_value < start.abs_value)
+  if (start.abs_value_us + duration.rel_value_us < start.abs_value_us)
   {
     GNUNET_break (0);
     return GNUNET_TIME_UNIT_FOREVER_ABS;
   }
   {
     GNUNET_break (0);
     return GNUNET_TIME_UNIT_FOREVER_ABS;
   }
-  ret.abs_value = start.abs_value + duration.rel_value;
+  ret.abs_value_us = start.abs_value_us + duration.rel_value_us;
   return ret;
 }
 
   return ret;
 }
 
@@ -340,11 +363,11 @@ GNUNET_TIME_absolute_subtract (struct GNUNET_TIME_Absolute start,
 {
   struct GNUNET_TIME_Absolute ret;
 
 {
   struct GNUNET_TIME_Absolute ret;
 
-  if (start.abs_value <= duration.rel_value)
+  if (start.abs_value_us <= duration.rel_value_us)
     return GNUNET_TIME_UNIT_ZERO_ABS;
     return GNUNET_TIME_UNIT_ZERO_ABS;
-  if (start.abs_value == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value)
+  if (start.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
     return GNUNET_TIME_UNIT_FOREVER_ABS;
     return GNUNET_TIME_UNIT_FOREVER_ABS;
-  ret.abs_value = start.abs_value - duration.rel_value;
+  ret.abs_value_us = start.abs_value_us - duration.rel_value_us;
   return ret;
 }
 
   return ret;
 }
 
@@ -360,10 +383,12 @@ GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
 {
   struct GNUNET_TIME_Relative ret;
 
 {
   struct GNUNET_TIME_Relative ret;
 
-  if (factor == 0)
+  if (0 == factor)
     return GNUNET_TIME_UNIT_ZERO;
     return GNUNET_TIME_UNIT_ZERO;
-  ret.rel_value = rel.rel_value * (unsigned long long) factor;
-  if (ret.rel_value / factor != rel.rel_value)
+  if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
+    return GNUNET_TIME_UNIT_FOREVER_REL;
+  ret.rel_value_us = rel.rel_value_us * (unsigned long long) factor;
+  if (ret.rel_value_us / factor != rel.rel_value_us)
   {
     GNUNET_break (0);
     return GNUNET_TIME_UNIT_FOREVER_REL;
   {
     GNUNET_break (0);
     return GNUNET_TIME_UNIT_FOREVER_REL;
@@ -385,10 +410,10 @@ GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
 {
   struct GNUNET_TIME_Relative ret;
 
 {
   struct GNUNET_TIME_Relative ret;
 
-  if ((factor == 0) ||
-      (rel.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value))
+  if ((0 == factor) ||
+      (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us))
     return GNUNET_TIME_UNIT_FOREVER_REL;
     return GNUNET_TIME_UNIT_FOREVER_REL;
-  ret.rel_value = rel.rel_value / (unsigned long long) factor;
+  ret.rel_value_us = rel.rel_value_us / (unsigned long long) factor;
   return ret;
 }
 
   return ret;
 }
 
@@ -414,11 +439,11 @@ GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start, uint64_t finished,
   GNUNET_break (finished <= total);
   if (finished >= total)
     return GNUNET_TIME_UNIT_ZERO;
   GNUNET_break (finished <= total);
   if (finished >= total)
     return GNUNET_TIME_UNIT_ZERO;
-  if (finished == 0)
+  if (0 == finished)
     return GNUNET_TIME_UNIT_FOREVER_REL;
   dur = GNUNET_TIME_absolute_get_duration (start);
     return GNUNET_TIME_UNIT_FOREVER_REL;
   dur = GNUNET_TIME_absolute_get_duration (start);
-  exp = ((double) dur.rel_value) * ((double) total) / ((double) finished);
-  ret.rel_value = ((uint64_t) exp) - dur.rel_value;
+  exp = ((double) dur.rel_value_us) * ((double) total) / ((double) finished);
+  ret.rel_value_us = ((uint64_t) exp) - dur.rel_value_us;
   return ret;
 }
 
   return ret;
 }
 
@@ -436,14 +461,14 @@ GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
 {
   struct GNUNET_TIME_Relative ret;
 
 {
   struct GNUNET_TIME_Relative ret;
 
-  if ((a1.rel_value == UINT64_MAX) || (a2.rel_value == UINT64_MAX))
+  if ((a1.rel_value_us == UINT64_MAX) || (a2.rel_value_us == UINT64_MAX))
     return GNUNET_TIME_UNIT_FOREVER_REL;
     return GNUNET_TIME_UNIT_FOREVER_REL;
-  if (a1.rel_value + a2.rel_value < a1.rel_value)
+  if (a1.rel_value_us + a2.rel_value_us < a1.rel_value_us)
   {
     GNUNET_break (0);
     return GNUNET_TIME_UNIT_FOREVER_REL;
   }
   {
     GNUNET_break (0);
     return GNUNET_TIME_UNIT_FOREVER_REL;
   }
-  ret.rel_value = a1.rel_value + a2.rel_value;
+  ret.rel_value_us = a1.rel_value_us + a2.rel_value_us;
   return ret;
 }
 
   return ret;
 }
 
@@ -461,11 +486,11 @@ GNUNET_TIME_relative_subtract (struct GNUNET_TIME_Relative a1,
 {
   struct GNUNET_TIME_Relative ret;
 
 {
   struct GNUNET_TIME_Relative ret;
 
-  if (a2.rel_value >= a1.rel_value)
+  if (a2.rel_value_us >= a1.rel_value_us)
     return GNUNET_TIME_UNIT_ZERO;
     return GNUNET_TIME_UNIT_ZERO;
-  if (a1.rel_value == UINT64_MAX)
+  if (a1.rel_value_us == UINT64_MAX)
     return GNUNET_TIME_UNIT_FOREVER_REL;
     return GNUNET_TIME_UNIT_FOREVER_REL;
-  ret.rel_value = a1.rel_value - a2.rel_value;
+  ret.rel_value_us = a1.rel_value_us - a2.rel_value_us;
   return ret;
 }
 
   return ret;
 }
 
@@ -481,7 +506,7 @@ GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
 {
   struct GNUNET_TIME_RelativeNBO ret;
 
 {
   struct GNUNET_TIME_RelativeNBO ret;
 
-  ret.rel_value__ = GNUNET_htonll (a.rel_value);
+  ret.rel_value_us__ = GNUNET_htonll (a.rel_value_us);
   return ret;
 }
 
   return ret;
 }
 
@@ -497,7 +522,7 @@ GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
 {
   struct GNUNET_TIME_Relative ret;
 
 {
   struct GNUNET_TIME_Relative ret;
 
-  ret.rel_value = GNUNET_ntohll (a.rel_value__);
+  ret.rel_value_us = GNUNET_ntohll (a.rel_value_us__);
   return ret;
 
 }
   return ret;
 
 }
@@ -514,7 +539,7 @@ GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
 {
   struct GNUNET_TIME_AbsoluteNBO ret;
 
 {
   struct GNUNET_TIME_AbsoluteNBO ret;
 
-  ret.abs_value__ = GNUNET_htonll (a.abs_value);
+  ret.abs_value_us__ = GNUNET_htonll (a.abs_value_us);
   return ret;
 }
 
   return ret;
 }
 
@@ -530,10 +555,80 @@ GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
 {
   struct GNUNET_TIME_Absolute ret;
 
 {
   struct GNUNET_TIME_Absolute ret;
 
-  ret.abs_value = GNUNET_ntohll (a.abs_value__);
+  ret.abs_value_us = GNUNET_ntohll (a.abs_value_us__);
   return ret;
 
 }
 
 
   return ret;
 
 }
 
 
+/**
+ * Return the current year (i.e. '2011').
+ */
+unsigned int
+GNUNET_TIME_get_current_year ()
+{
+  time_t tp;
+  struct tm *t;
+
+  tp = time (NULL);
+  t = gmtime (&tp);
+  if (t == NULL)
+    return 0;
+  return t->tm_year + 1900;
+}
+
+
+/**
+ * Convert an expiration time to the respective year (rounds)
+ *
+ * @param at absolute time
+ * @return year a year (after 1970), 0 on error
+ */
+unsigned int
+GNUNET_TIME_time_to_year (struct GNUNET_TIME_Absolute at)
+{
+  struct tm *t;
+  time_t tp;
+
+  tp = at.abs_value_us / 1000LL / 1000LL;    /* microseconds to seconds */
+  t = gmtime (&tp);
+  if (t == NULL)
+    return 0;
+  return t->tm_year + 1900;
+
+}
+
+
+/**
+ * Convert a year to an expiration time of January 1st of that year.
+ *
+ * @param year a year (after 1970, please ;-)).
+ * @return absolute time for January 1st of that year.
+ */
+struct GNUNET_TIME_Absolute
+GNUNET_TIME_year_to_time (unsigned int year)
+{
+  struct GNUNET_TIME_Absolute ret;
+  time_t tp;
+  struct tm t;
+
+  memset (&t, 0, sizeof (t));
+  if (year < 1900)
+  {
+    GNUNET_break (0);
+    return GNUNET_TIME_absolute_get (); /* now */
+  }
+  t.tm_year = year - 1900;
+  t.tm_mday = 1;
+  t.tm_mon = 1;
+  t.tm_wday = 1;
+  t.tm_yday = 1;
+  tp = mktime (&t);
+  GNUNET_break (tp != (time_t) - 1);
+  ret.abs_value_us = tp * 1000LL * 1000LL;  /* seconds to microseconds */
+  return ret;
+}
+
+
+
 /* end of time.c */
 /* end of time.c */