From babcf632dac6fd5b50e2f4d44c5d9375982dd7fb Mon Sep 17 00:00:00 2001
From: Brian Warner <warner@allmydata.com>
Date: Wed, 18 Mar 2009 17:58:14 -0700
Subject: [PATCH] util/time_format: new routine to parse dates like 2009-03-18,
 switch expirer to use it. I'd prefer to use 18-Mar-2009, but it is
 surprisingly non-trivial to build a parser that will take UTC dates instead
 of local dates

---
 docs/proposed/garbage-collection.txt | 6 +++---
 src/allmydata/test/test_storage.py   | 6 +++++-
 src/allmydata/util/time_format.py    | 6 ++++++
 src/allmydata/web/storage.py         | 4 ++--
 4 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/docs/proposed/garbage-collection.txt b/docs/proposed/garbage-collection.txt
index 51998d67..758e1919 100644
--- a/docs/proposed/garbage-collection.txt
+++ b/docs/proposed/garbage-collection.txt
@@ -169,9 +169,9 @@ expire.cutoff_date = (date string, required if mode=date-cutoff)
  create/renew timestamp is older than the cutoff date. This string will be a
  date in the following format:
 
-  16-Jan-2009
-  02-Feb-2008
-  25-Dec-2007
+  2009-01-16   (January 16th, 2009)
+  2008-02-02
+  2007-12-25
 
  The actual cutoff time shall be midnight UTC at the beginning of the given
  day. Lease timers should naturally be generous enough to not depend upon
diff --git a/src/allmydata/test/test_storage.py b/src/allmydata/test/test_storage.py
index f3452b43..39e8806b 100644
--- a/src/allmydata/test/test_storage.py
+++ b/src/allmydata/test/test_storage.py
@@ -2020,7 +2020,7 @@ class LeaseCrawler(unittest.TestCase, pollmixin.PollMixin, WebRenderingMixin):
             s = remove_tags(html)
             self.failUnlessIn("Expiration Enabled:"
                               " expired leases will be removed", s)
-            date = time.strftime("%d-%b-%Y", time.gmtime(then))
+            date = time.strftime("%Y-%m-%d", time.gmtime(then))
             self.failUnlessIn("Leases created or last renewed before %s"
                               " will be considered expired." % date, s)
             self.failUnlessIn(" recovered: 2 shares, 2 buckets (1 mutable / 1 immutable), ", s)
@@ -2164,6 +2164,10 @@ class LeaseCrawler(unittest.TestCase, pollmixin.PollMixin, WebRenderingMixin):
         self.failUnless("no unit (like day, month, or year) in '2kumquats'"
                         in str(e), str(e))
 
+    def test_parse_date(self):
+        p = time_format.parse_date
+        self.failUnlessEqual(p("2009-03-18"), 1237334400)
+
     def test_limited_history(self):
         basedir = "storage/LeaseCrawler/limited_history"
         fileutil.make_dirs(basedir)
diff --git a/src/allmydata/util/time_format.py b/src/allmydata/util/time_format.py
index 0281b6d7..0bc39280 100644
--- a/src/allmydata/util/time_format.py
+++ b/src/allmydata/util/time_format.py
@@ -58,3 +58,9 @@ def parse_duration(s):
         raise ValueError("no unit (like day, month, or year) in '%s'" % orig)
     s = s.strip()
     return int(s) * unit
+
+def parse_date(s):
+    # return seconds-since-epoch for the UTC midnight that starts the given
+    # day
+    return iso_utc_time_to_localseconds(s + "T00:00:00")
+
diff --git a/src/allmydata/web/storage.py b/src/allmydata/web/storage.py
index 56db9026..b35839ea 100644
--- a/src/allmydata/web/storage.py
+++ b/src/allmydata/web/storage.py
@@ -138,8 +138,8 @@ class StorageStatus(rend.Page):
                         "will be considered expired."
                         % abbreviate_time(lc.override_lease_duration)]
         else:
-            assert lc.mode == "date-cutoff"
-            date = time.strftime("%d-%b-%Y", time.gmtime(lc.date_cutoff))
+            assert lc.mode == "cutoff-date"
+            date = time.strftime("%Y-%m-%d", time.gmtime(lc.cutoff_date))
             ctx.tag["Leases created or last renewed before %s "
                     "will be considered expired." % date]
         if len(lc.mode) > 2:
-- 
2.45.2