def test_parse_date(self):
self.failUnlessEqual(time_format.parse_date("2010-02-21"), 1266710400)
+ def test_format_time(self):
+ self.failUnlessEqual(time_format.format_time(time.gmtime(0)), '1970-01-01 00:00:00')
+ self.failUnlessEqual(time_format.format_time(time.gmtime(60)), '1970-01-01 00:01:00')
+ self.failUnlessEqual(time_format.format_time(time.gmtime(60*60)), '1970-01-01 01:00:00')
+ seconds_per_day = 60*60*24
+ leap_years_1970_to_2014_inclusive = ((2012 - 1968) // 4)
+ self.failUnlessEqual(time_format.format_time(time.gmtime(seconds_per_day*((2015 - 1970)*365+leap_years_1970_to_2014_inclusive))), '2015-01-01 00:00:00')
+
+ def test_format_time_y2038(self):
+ seconds_per_day = 60*60*24
+ leap_years_1970_to_2047_inclusive = ((2044 - 1968) // 4)
+ self.failUnlessEqual(time_format.format_time(time.gmtime(seconds_per_day*((2048 - 1970)*365+leap_years_1970_to_2047_inclusive))), '2048-01-01 00:00:00')
+
+ test_format_time_y2038.todo = "one day we'll move beyond 32-bit time"
+
class CacheDir(unittest.TestCase):
def test_basic(self):
basedir = "test_util/CacheDir/test_basic"
import calendar, datetime, re, time
+def format_time(t):
+ return time.strftime("%Y-%m-%d %H:%M:%S", t)
+
def iso_utc_date(now=None, t=time.time):
if now is None:
now = t()
now = t()
return datetime.datetime.utcfromtimestamp(now).isoformat(sep)
-def iso_local(now=None, sep='_', t=time.time):
- if now is None:
- now = t()
- return datetime.datetime.fromtimestamp(now).isoformat(sep)
-
def iso_utc_time_to_seconds(isotime, _conversion_re=re.compile(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})[T_ ](?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2})(?P<subsecond>\.\d+)?")):
"""
The inverse of iso_utc().
+import time
import simplejson
+
from twisted.web import http, server
from twisted.python import log
from zope.interface import Interface
MustBeReadonlyError, MustNotBeUnknownRWError, SDMF_VERSION, MDMF_VERSION
from allmydata.mutable.common import UnrecoverableFileError
from allmydata.util import abbreviate
+from allmydata.util.time_format import format_time
from allmydata.util.encodingutil import to_str, quote_output
-TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
-
def get_filenode_metadata(filenode):
metadata = {'mutable': filenode.is_mutable()}
if metadata['mutable']:
req.setHeader("content-length", b"%d" % len(text))
return text
+def spaces_to_nbsp(text):
+ return unicode(text).replace(u' ', u'\u00A0')
+
+def render_time(t):
+ return spaces_to_nbsp(format_time(time.localtime(t)))
+
class WebError(Exception):
def __init__(self, text, code=http.BAD_REQUEST):
self.text = text
from foolscap.api import fireEventually
-from allmydata.util import base32, time_format
+from allmydata.util import base32
from allmydata.util.encodingutil import to_str
from allmydata.uri import from_string_dirnode
from allmydata.interfaces import IDirectoryNode, IFileNode, IFilesystemNode, \
boolean_of_arg, get_arg, get_root, parse_replace_arg, \
should_create_intermediate_directories, \
getxmlfile, RenderMixin, humanize_failure, convert_children_json, \
- get_format, get_mutable_type, get_filenode_metadata
+ get_format, get_mutable_type, get_filenode_metadata, render_time
from allmydata.web.filenode import ReplaceMeMixin, \
FileNodeHandler, PlaceHolderNodeHandler
from allmydata.web.check_results import CheckResultsRenderer, \
times = []
linkcrtime = metadata.get('tahoe', {}).get("linkcrtime")
if linkcrtime is not None:
- times.append("lcr: " + time_format.iso_local(linkcrtime))
+ times.append("lcr: " + render_time(linkcrtime))
else:
# For backwards-compatibility with links last modified by Tahoe < 1.4.0:
if "ctime" in metadata:
- ctime = time_format.iso_local(metadata["ctime"])
+ ctime = render_time(metadata["ctime"])
times.append("c: " + ctime)
linkmotime = metadata.get('tahoe', {}).get("linkmotime")
if linkmotime is not None:
if times:
times.append(T.br())
- times.append("lmo: " + time_format.iso_local(linkmotime))
+ times.append("lmo: " + render_time(linkmotime))
else:
# For backwards-compatibility with links last modified by Tahoe < 1.4.0:
if "mtime" in metadata:
- mtime = time_format.iso_local(metadata["mtime"])
+ mtime = render_time(metadata["mtime"])
if times:
times.append(T.br())
times.append("m: " + mtime)
import simplejson
from allmydata import get_package_versions_string
from allmydata.util import idlib
-from allmydata.web.common import getxmlfile, get_arg, TIME_FORMAT
+from allmydata.web.common import getxmlfile, get_arg, render_time
class IntroducerRoot(rend.Page):
# FIXME: This code is duplicated in root.py and introweb.py.
def data_rendered_at(self, ctx, data):
- return time.strftime(TIME_FORMAT, time.localtime())
+ return render_time(time.time())
def data_version(self, ctx, data):
return get_package_versions_string()
def data_import_path(self, ctx, data):
ctx.fillSlots("connection-hints",
"connection hints: " + " ".join(ad.connection_hints))
ctx.fillSlots("connected", "?")
- when_s = time.strftime("%H:%M:%S %d-%b-%Y", time.localtime(ad.when))
+ when_s = render_time(ad.when)
ctx.fillSlots("announced", when_s)
ctx.fillSlots("version", ad.version)
ctx.fillSlots("service_name", ad.service_name)
ctx.fillSlots("nickname", s.nickname)
ctx.fillSlots("tubid", s.tubid)
ctx.fillSlots("connected", s.remote_address)
- since_s = time.strftime("%H:%M:%S %d-%b-%Y", time.localtime(s.when))
+ since_s = render_time(s.when)
ctx.fillSlots("since", since_s)
ctx.fillSlots("version", s.version)
ctx.fillSlots("service_name", s.service_name)
from allmydata.web import filenode, directory, unlinked, status, operations
from allmydata.web import storage
from allmydata.web.common import abbreviate_size, getxmlfile, WebError, \
- get_arg, RenderMixin, get_format, get_mutable_type, TIME_FORMAT
+ get_arg, RenderMixin, get_format, get_mutable_type, render_time
class URIHandler(RenderMixin, rend.Page):
# FIXME: This code is duplicated in root.py and introweb.py.
def data_rendered_at(self, ctx, data):
- return time.strftime(TIME_FORMAT, time.localtime())
+ return render_time(time.time())
def data_version(self, ctx, data):
return get_package_versions_string()
def data_import_path(self, ctx, data):
ctx.fillSlots("connected", connected)
ctx.fillSlots("connected_alt", self._connectedalts[connected])
ctx.fillSlots("connected-bool", bool(rhost))
- ctx.fillSlots("since", time.strftime(TIME_FORMAT,
- time.localtime(since)))
- ctx.fillSlots("announced", time.strftime(TIME_FORMAT,
- time.localtime(announced)))
+ ctx.fillSlots("since", render_time(since))
+ ctx.fillSlots("announced", render_time(announced))
ctx.fillSlots("version", version)
ctx.fillSlots("service_name", service_name)
ctx.fillSlots("available_space", available_space)
from nevow import rend, inevow, tags as T
from allmydata.util import base32, idlib
from allmydata.web.common import getxmlfile, get_arg, \
- abbreviate_time, abbreviate_rate, abbreviate_size, plural, compute_rate
+ abbreviate_time, abbreviate_rate, abbreviate_size, plural, compute_rate, render_time
from allmydata.interfaces import IUploadStatus, IDownloadStatus, \
IPublishStatus, IRetrieveStatus, IServermapUpdaterStatus
return d
def render_started(self, ctx, data):
- TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
- started_s = time.strftime(TIME_FORMAT,
- time.localtime(data.get_started()))
+ started_s = render_time(data.get_started())
return started_s
def render_si(self, ctx, data):
return d
def render_started(self, ctx, data):
- TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
- started_s = time.strftime(TIME_FORMAT,
- time.localtime(data.get_started()))
+ started_s = render_time(data.get_started())
return started_s + " (%s)" % data.get_started()
def render_si(self, ctx, data):
docFactory = getxmlfile("download-status-timeline.xhtml")
def render_started(self, ctx, data):
- TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
- started_s = time.strftime(TIME_FORMAT,
- time.localtime(data.get_started()))
+ started_s = render_time(data.get_started())
return started_s + " (%s)" % data.get_started()
def render_si(self, ctx, data):
self.retrieve_status = data
def render_started(self, ctx, data):
- TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
- started_s = time.strftime(TIME_FORMAT,
- time.localtime(data.get_started()))
+ started_s = render_time(data.get_started())
return started_s
def render_si(self, ctx, data):
self.publish_status = data
def render_started(self, ctx, data):
- TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
- started_s = time.strftime(TIME_FORMAT,
- time.localtime(data.get_started()))
+ started_s = render_time(data.get_started())
return started_s
def render_si(self, ctx, data):
self.update_status = data
def render_started(self, ctx, data):
- TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
- started_s = time.strftime(TIME_FORMAT,
- time.localtime(data.get_started()))
+ started_s = render_time(data.get_started())
return started_s
def render_finished(self, ctx, data):
when = data.get_finished()
if not when:
return "not yet"
- TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
- started_s = time.strftime(TIME_FORMAT,
- time.localtime(data.get_finished()))
+ started_s = render_time(data.get_finished())
return started_s
def render_si(self, ctx, data):
def render_row(self, ctx, data):
s = data
- TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
- started_s = time.strftime(TIME_FORMAT,
- time.localtime(s.get_started()))
+ started_s = render_time(s.get_started())
ctx.fillSlots("started", started_s)
si_s = base32.b2a_or_none(s.get_storage_index())