| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | # |
|---|
| 3 | # Copyright (C) 2003-2006 Edgewall Software |
|---|
| 4 | # Copyright (C) 2003-2004 Jonas Borgström <jonas@edgewall.com> |
|---|
| 5 | # Copyright (C) 2006 Matthew Good <trac@matt-good.net> |
|---|
| 6 | # Copyright (C) 2005-2006 Christian Boos <cboos@neuf.fr> |
|---|
| 7 | # All rights reserved. |
|---|
| 8 | # |
|---|
| 9 | # This software is licensed as described in the file COPYING, which |
|---|
| 10 | # you should have received as part of this distribution. The terms |
|---|
| 11 | # are also available at http://trac.edgewall.org/wiki/TracLicense. |
|---|
| 12 | # |
|---|
| 13 | # This software consists of voluntary contributions made by many |
|---|
| 14 | # individuals. For the exact contribution history, see the revision |
|---|
| 15 | # history and logs, available at http://trac.edgewall.org/log/. |
|---|
| 16 | # |
|---|
| 17 | # Author: Jonas Borgström <jonas@edgewall.com> |
|---|
| 18 | # Matthew Good <trac@matt-good.net> |
|---|
| 19 | |
|---|
| 20 | import locale |
|---|
| 21 | import sys |
|---|
| 22 | import time |
|---|
| 23 | |
|---|
| 24 | # Date/time utilities |
|---|
| 25 | |
|---|
| 26 | def pretty_timedelta(time1, time2=None, resolution=None): |
|---|
| 27 | """Calculate time delta (inaccurately, only for decorative purposes ;-) for |
|---|
| 28 | prettyprinting. If time1 is None, the current time is used.""" |
|---|
| 29 | if not time1: time1 = time.time() |
|---|
| 30 | if not time2: time2 = time.time() |
|---|
| 31 | if time1 > time2: |
|---|
| 32 | time2, time1 = time1, time2 |
|---|
| 33 | units = ((3600 * 24 * 365, u'년', u'년'), |
|---|
| 34 | (3600 * 24 * 30, u'달', u'달'), |
|---|
| 35 | (3600 * 24 * 7, u'주', u'주'), |
|---|
| 36 | (3600 * 24, u'일', u'일'), |
|---|
| 37 | (3600, u'시간', u'시간'), |
|---|
| 38 | (60, u'분', u'분')) |
|---|
| 39 | age_s = int(time2 - time1) |
|---|
| 40 | if resolution and age_s < resolution: |
|---|
| 41 | return '' |
|---|
| 42 | if age_s < 60: |
|---|
| 43 | return u'%i 초%s' % (age_s, age_s != 1 and '' or '') |
|---|
| 44 | for u, unit, unit_plural in units: |
|---|
| 45 | r = float(age_s) / float(u) |
|---|
| 46 | if r >= 0.9: |
|---|
| 47 | r = int(round(r)) |
|---|
| 48 | return '%d %s' % (r, r == 1 and unit or unit_plural) |
|---|
| 49 | return '' |
|---|
| 50 | |
|---|
| 51 | def format_datetime(t=None, format='%Y-%m-%d %X', gmt=False): |
|---|
| 52 | if t is None: |
|---|
| 53 | t = time.time() |
|---|
| 54 | if not isinstance(t, (list, tuple, time.struct_time)): |
|---|
| 55 | if gmt: |
|---|
| 56 | t = time.gmtime(float(t)) |
|---|
| 57 | else: |
|---|
| 58 | t = time.localtime(float(t)) |
|---|
| 59 | |
|---|
| 60 | text = time.strftime(format, t) |
|---|
| 61 | encoding = locale.getpreferredencoding() or sys.getdefaultencoding() |
|---|
| 62 | if sys.platform != 'win32': |
|---|
| 63 | encoding = locale.getlocale(locale.LC_TIME)[1] or encoding |
|---|
| 64 | # the above is broken on win32, e.g. we'd get '437' instead of 'cp437' |
|---|
| 65 | return unicode(text, encoding, 'replace') |
|---|
| 66 | |
|---|
| 67 | def format_date(t=None, format='%Y-%m-%d', gmt=False): |
|---|
| 68 | return format_datetime(t, format, gmt) |
|---|
| 69 | |
|---|
| 70 | def format_time(t=None, format='%X', gmt=False): |
|---|
| 71 | return format_datetime(t, format, gmt) |
|---|
| 72 | |
|---|
| 73 | def get_date_format_hint(): |
|---|
| 74 | t = time.localtime(0) |
|---|
| 75 | t = (1999, 10, 29, t[3], t[4], t[5], t[6], t[7], t[8]) |
|---|
| 76 | tmpl = format_date(t) |
|---|
| 77 | return tmpl.replace('1999', 'YYYY', 1).replace('99', 'YY', 1) \ |
|---|
| 78 | .replace('10', 'MM', 1).replace('29', 'DD', 1) |
|---|
| 79 | |
|---|
| 80 | def get_datetime_format_hint(): |
|---|
| 81 | t = time.localtime(0) |
|---|
| 82 | t = (1999, 10, 29, 23, 59, 58, t[6], t[7], t[8]) |
|---|
| 83 | tmpl = format_datetime(t) |
|---|
| 84 | return tmpl.replace('1999', 'YYYY', 1).replace('99', 'YY', 1) \ |
|---|
| 85 | .replace('10', 'MM', 1).replace('29', 'DD', 1) \ |
|---|
| 86 | .replace('23', 'hh', 1).replace('11', 'hh', 1) \ |
|---|
| 87 | .replace('59', 'mm', 1).replace('58', 'ss', 1) |
|---|
| 88 | |
|---|
| 89 | def http_date(t=None): |
|---|
| 90 | """Format t as a rfc822 timestamp""" |
|---|
| 91 | if t is None: |
|---|
| 92 | t = time.time() |
|---|
| 93 | if not isinstance(t, (list, tuple, time.struct_time)): |
|---|
| 94 | t = time.gmtime(float(t)) |
|---|
| 95 | weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] |
|---|
| 96 | months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', |
|---|
| 97 | 'Oct', 'Nov', 'Dec'] |
|---|
| 98 | return '%s, %02d %s %04d %02d:%02d:%02d GMT' % ( |
|---|
| 99 | weekdays[t.tm_wday], t.tm_mday, months[t.tm_mon - 1], t.tm_year, |
|---|
| 100 | t.tm_hour, t.tm_min, t.tm_sec) |
|---|
| 101 | |
|---|
| 102 | def parse_date(text): |
|---|
| 103 | seconds = None |
|---|
| 104 | text = text.strip() |
|---|
| 105 | for format in ['%x %X', '%x, %X', '%X %x', '%X, %x', '%x', '%c', |
|---|
| 106 | '%b %d, %Y', '%Y-%m-%d %X', '%Y-%m-%d']: |
|---|
| 107 | try: |
|---|
| 108 | date = time.strptime(text, format) |
|---|
| 109 | seconds = time.mktime(date) |
|---|
| 110 | break |
|---|
| 111 | except ValueError: |
|---|
| 112 | continue |
|---|
| 113 | if seconds == None: |
|---|
| 114 | raise ValueError, '%s is not a known date format.' % text |
|---|
| 115 | return seconds |
|---|