Index: trac/attachment.py
===================================================================
--- trac/attachment.py	(revision 2530)
+++ trac/attachment.py	(working copy)
@@ -200,7 +200,7 @@
         'author': util.escape(attachment.author),
         'ipnr': attachment.ipnr,
         'size': util.pretty_size(attachment.size),
-        'time': util.format_datetime(attachment.time),
+        'time': util.format_datetime(attachment.time, env.config.get('i18n', 'datetime_format')),
         'href': attachment.href()
     }
     return hdf
Index: trac/db_default.py
===================================================================
--- trac/db_default.py	(revision 2530)
+++ trac/db_default.py	(working copy)
@@ -434,6 +434,9 @@
   ('timeline', 'ticket_show_details', 'false'),
   ('browser', 'hide_properties', 'svk:merge'),
   ('wiki', 'ignore_missing_pages', 'false'),
+  ('i18n', 'date_format', '%x'),
+  ('i18n', 'time_format', '%X'),
+  ('i18n', 'datetime_format', '%x %X'),
 )
 
 default_components = ('trac.About', 'trac.attachment', 
Index: trac/ticket/web_ui.py
===================================================================
--- trac/ticket/web_ui.py	(revision 2530)
+++ trac/ticket/web_ui.py	(working copy)
@@ -389,10 +389,10 @@
         req.hdf['ticket.description.formatted'] = wiki_to_html(ticket['description'],
                                                                self.env, req, db)
 
-        req.hdf['ticket.opened'] = util.format_datetime(ticket.time_created)
+        req.hdf['ticket.opened'] = util.format_datetime(ticket.time_created, self.env.config.get('i18n', 'datetime_format'))
         req.hdf['ticket.opened_delta'] = util.pretty_timedelta(ticket.time_created)
         if ticket.time_changed != ticket.time_created:
-            req.hdf['ticket.lastmod'] = util.format_datetime(ticket.time_changed)
+            req.hdf['ticket.lastmod'] = util.format_datetime(ticket.time_changed, self.env.config.get('i18n', 'datetime_format'))
             req.hdf['ticket.lastmod_delta'] = util.pretty_timedelta(ticket.time_changed)
 
         changelog = ticket.get_changelog(db=db)
@@ -402,7 +402,7 @@
         for date, author, field, old, new in changelog:
             if date != curr_date or author != curr_author:
                 changes.append({
-                    'date': util.format_datetime(date),
+                    'date': util.format_datetime(date, self.env.config.get('i18n', 'datetime_format')),
                     'author': util.escape(author),
                     'fields': {}
                 })
Index: trac/ticket/report.py
===================================================================
--- trac/ticket/report.py	(revision 2530)
+++ trac/ticket/report.py	(working copy)
@@ -351,9 +351,9 @@
                 elif column == 'report':
                     value['report_href'] = self.env.href.report(cell)
                 elif column in ['time', 'date','changetime', 'created', 'modified']:
-                    value['date'] = util.format_date(cell)
-                    value['time'] = util.format_time(cell)
-                    value['datetime'] = util.format_datetime(cell)
+                    value['date'] = util.format_date(cell, self.env.config.get('i18n', 'date_format'))
+                    value['time'] = util.format_time(cell, self.env.config.get('i18n', 'time_format'))
+                    value['datetime'] = util.format_datetime(cell, self.env.config.get('i18n', 'datetime_format'))
                     value['gmt'] = util.http_date(cell)
                 prefix = 'report.items.%d.%s' % (row_idx, str(column))
                 req.hdf[prefix] = util.escape(str(cell))
Index: trac/ticket/roadmap.py
===================================================================
--- trac/ticket/roadmap.py	(revision 2530)
+++ trac/ticket/roadmap.py	(working copy)
@@ -94,12 +94,12 @@
         hdf['description'] = wiki_to_html(milestone.description, env, req, db)
     if milestone.due:
         hdf['due'] = milestone.due
-        hdf['due_date'] = format_date(milestone.due)
+        hdf['due_date'] = format_date(milestone.due, env.config.get('i18n', 'date_format'))
         hdf['due_delta'] = pretty_timedelta(milestone.due)
         hdf['late'] = milestone.is_late
     if milestone.completed:
         hdf['completed'] = milestone.completed
-        hdf['completed_date'] = format_datetime(milestone.completed)
+        hdf['completed_date'] = format_datetime(milestone.completed, env.config.get('i18n', 'datetime_format'))
         hdf['completed_delta'] = pretty_timedelta(milestone.completed)
     return hdf
 
@@ -388,13 +388,13 @@
 
         due = req.args.get('duedate', '')
         try:
-            milestone.due = due and parse_date(due) or 0
+            milestone.due = due and parse_date(due, self.env.config.get('i18n', 'date_format')) or 0
         except ValueError, e:
             raise TracError(e, 'Invalid Date Format')
         if req.args.has_key('completed'):
             completed = req.args.get('completeddate', '')
             try:
-                milestone.completed = completed and parse_date(completed) or 0
+                milestone.completed = completed and parse_date(completed, self.env.config.get('i18n', 'datetime_format')) or 0
             except ValueError, e:
                 raise TracError(e, 'Invalid Date Format')
             if milestone.completed > time():
@@ -438,9 +438,9 @@
 
         from trac.util import get_date_format_hint, get_datetime_format_hint
         req.hdf['milestone'] = milestone_to_hdf(self.env, db, req, milestone)
-        req.hdf['milestone.date_hint'] = get_date_format_hint()
-        req.hdf['milestone.datetime_hint'] = get_datetime_format_hint()
-        req.hdf['milestone.datetime_now'] = format_datetime()
+        req.hdf['milestone.date_hint'] = get_date_format_hint(self.env.config.get('i18n', 'date_format'))
+        req.hdf['milestone.datetime_hint'] = get_datetime_format_hint(self.env.config.get('i18n', 'datetime_format'))
+        req.hdf['milestone.datetime_now'] = format_datetime(None, self.env.config.get('i18n', 'datetime_format'))
 
     def _render_view(self, req, db, milestone):
         req.hdf['title'] = 'Milestone %s' % milestone.name
Index: trac/ticket/query.py
===================================================================
--- trac/ticket/query.py	(revision 2530)
+++ trac/ticket/query.py	(working copy)
@@ -534,7 +534,7 @@
                     ticket['changed'] = True
             for field, value in ticket.items():
                 if field == 'time':
-                    ticket[field] = escape(format_datetime(value))
+                    ticket[field] = escape(format_datetime(value, self.env.config.get('i18n', 'datetime_format')))
                 elif field == 'description':
                     ticket[field] = wiki_to_html(value or '', self.env, req, db)
                 else:
Index: trac/versioncontrol/web_ui/util.py
===================================================================
--- trac/versioncontrol/web_ui/util.py	(revision 2530)
+++ trac/versioncontrol/web_ui/util.py	(working copy)
@@ -45,7 +45,7 @@
             message = '--'
         changes[rev] = {
             'date_seconds': changeset.date,
-            'date': format_datetime(changeset.date),
+            'date': format_datetime(changeset.date, env.config.get('i18n', 'datetime_format')),
             'age': pretty_timedelta(changeset.date),
             'author': changeset.author or 'anonymous',
             'message': message,
Index: trac/versioncontrol/web_ui/changeset.py
===================================================================
--- trac/versioncontrol/web_ui/changeset.py	(revision 2530)
+++ trac/versioncontrol/web_ui/changeset.py	(working copy)
@@ -153,7 +153,7 @@
         req.hdf['title'] = '[%s]' % chgset.rev
         req.hdf['changeset'] = {
             'revision': chgset.rev,
-            'time': util.format_datetime(chgset.date),
+            'time': util.format_datetime(chgset.date, self.env.config.get('i18n', 'datetime_format')),
             'author': util.escape(chgset.author or 'anonymous'),
             'message': wiki_to_html(chgset.message or '--', self.env, req,
                                     escape_newlines=True)
Index: trac/versioncontrol/web_ui/browser.py
===================================================================
--- trac/versioncontrol/web_ui/browser.py	(revision 2530)
+++ trac/versioncontrol/web_ui/browser.py	(working copy)
@@ -170,7 +170,7 @@
         req.hdf['file'] = {  
             'rev': node.rev,  
             'changeset_href': util.escape(self.env.href.changeset(node.rev)),
-            'date': util.format_datetime(changeset.date),
+            'date': util.format_datetime(changeset.date, self.env.config.get('i18n', 'datetime_format')),
             'age': util.pretty_timedelta(changeset.date),
             'author': changeset.author or 'anonymous',
             'message': wiki_to_html(changeset.message or '--', self.env, req,
Index: trac/Search.py
===================================================================
--- trac/Search.py	(revision 2530)
+++ trac/Search.py	(working copy)
@@ -183,7 +183,7 @@
             req.hdf['search.result'] = [
                 { 'href': escape(result[0]),
                   'title': result[1],
-                  'date': format_datetime(result[2]),
+                  'date': format_datetime(result[2], self.env.config.get('i18n', 'datetime_format')),
                   'author': escape(result[3]),
                   'excerpt': result[4]
                 } for result in results]
Index: trac/Timeline.py
===================================================================
--- trac/Timeline.py	(revision 2530)
+++ trac/Timeline.py	(working copy)
@@ -94,7 +94,7 @@
         t = time.localtime()
         if req.args.has_key('from'):
             try:
-                t = time.strptime(req.args.get('from'), '%x')
+                t = time.strptime(req.args.get('from'), self.env.config.get('i18n', 'date_format'))
             except:
                 pass
 
@@ -103,7 +103,7 @@
             daysback = max(0, int(req.args.get('daysback', '')))
         except ValueError:
             daysback = int(self.config.get('timeline', 'default_daysback'))
-        req.hdf['timeline.from'] = format_date(fromdate)
+        req.hdf['timeline.from'] = format_date(fromdate, self.env.config.get('i18n', 'date_format'))
         req.hdf['timeline.daysback'] = daysback
 
         available_filters = []
@@ -152,7 +152,7 @@
         for kind, href, title, date, author, message in events:
             event = {'kind': kind, 'title': title, 'href': escape(href),
                      'author': escape(author or 'anonymous'),
-                     'date': format_date(date),
+                     'date': format_date(date, self.env.config.get('i18n', 'date_format')),
                      'time': format_time(date, '%H:%M'),
                      'message': message}
 
Index: trac/wiki/web_ui.py
===================================================================
--- trac/wiki/web_ui.py	(revision 2530)
+++ trac/wiki/web_ui.py	(working copy)
@@ -241,7 +241,7 @@
         for version,t,author,comment,ipnr in page.get_history():
             if version == page.version:
                 if t:
-                    info['time'] = format_datetime(t)
+                    info['time'] = format_datetime(t, self.env.config.get('i18n', 'datetime_format'))
                     info['time_delta'] = pretty_timedelta(t)
                 info['author'] = escape(author or 'anonymous')
                 info['comment'] = escape(comment or '--')
@@ -333,7 +333,7 @@
                                                       version=version,
                                                       action='diff')),
                 'version': version,
-                'time': format_datetime(t),
+                'time': format_datetime(t, self.env.config.get('i18n', 'datetime_format')),
                 'time_delta': pretty_timedelta(t),
                 'author': escape(author),
                 'comment': wiki_to_oneliner(comment or '', self.env, db),
Index: trac/wiki/macros.py
===================================================================
--- trac/wiki/macros.py	(revision 2530)
+++ trac/wiki/macros.py	(working copy)
@@ -113,7 +113,7 @@
         prevdate = None
 
         for name, time in cursor:
-            date = format_date(time)
+            date = format_date(time, self.env.config.get('i18n', 'date_format'))
             if date != prevdate:
                 if prevdate:
                     buf.write('</ul>')
Index: trac/util.py
===================================================================
--- trac/util.py	(revision 2530)
+++ trac/util.py	(working copy)
@@ -204,17 +204,17 @@
 def format_time(t=None, format='%X', gmt=False):
     return format_datetime(t, format, gmt)
 
-def get_date_format_hint():
+def get_date_format_hint(format='%x'):
     t = time.localtime(0)
     t = (1999, 10, 29, t[3], t[4], t[5], t[6], t[7], t[8])
-    tmpl = time.strftime('%x', t)
+    tmpl = time.strftime(format, t)
     return tmpl.replace('1999', 'YYYY', 1).replace('99', 'YY', 1) \
                .replace('10', 'MM', 1).replace('29', 'DD', 1)
 
-def get_datetime_format_hint():
+def get_datetime_format_hint(format='%x %X'):
     t = time.localtime(0)
     t = (1999, 10, 29, 23, 59, 58, t[6], t[7], t[8])
-    tmpl = time.strftime('%x %X', t)
+    tmpl = time.strftime(format, t)
     return tmpl.replace('1999', 'YYYY', 1).replace('99', 'YY', 1) \
                .replace('10', 'MM', 1).replace('29', 'DD', 1) \
                .replace('23', 'hh', 1).replace('59', 'mm', 1) \
@@ -233,10 +233,10 @@
            weekdays[t.tm_wday], t.tm_mday, months[t.tm_mon - 1], t.tm_year,
            t.tm_hour, t.tm_min, t.tm_sec)
 
-def parse_date(text):
+def parse_date(text, default_format='%x %X'):
     seconds = None
     text = text.strip()
-    for format in ['%x %X', '%x, %X', '%X %x', '%X, %x', '%x', '%c',
+    for format in [default_format, '%x %X', '%x, %X', '%X %x', '%X, %x', '%x', '%c',
                    '%b %d, %Y']:
         try:
             date = time.strptime(text, format)
Index: trac/web/main.py
===================================================================
--- trac/web/main.py	(revision 2530)
+++ trac/web/main.py	(working copy)
@@ -149,7 +149,7 @@
     from trac import __version__
     hdf['trac'] = {
         'version': __version__,
-        'time': format_datetime(),
+        'time': format_datetime(None, env.config.get('i18n', 'datetime_format')),
         'time.gmt': http_date()
     }
     hdf['trac.href'] = {
