2009-10-06 3 views

답변

3

이상의 기간이 필요하지만 (적어도 파이썬의 안정 버전) 작동합니다

>>> ts = datetime.datetime(1895, 10, 6, 16, 4, 5) 
>>> '{0.year}-{0.month:{1}}-{0.day:{1}} {0.hour:{1}}:{0.minute:{1}}'.format(ts, '02') 
'1895-10-06 16:04' 

str는 여전히 읽을 수있는 문자열을 생성 할 것이다 참고 :

>>> str(ts) 
'1895-10-06 16:04:05' 

편집
기본 동작을 에뮬레이션하는 가장 가까운 방법은 다음과 같이 사전을 하드 코딩하는 것입니다.

>>> d = {'%Y': '{0.year}', '%m': '{0.month:02}'} # need to include all the formats 
>>> '{%Y}-{%m}'.format(**d).format(ts) 
'1895-10' 

당신은 간단한 정규식 중괄호에 모든 형식 지정자를 동봉해야합니다 :

def ancient_fmt(ts, fmt): 
    fmt = fmt.replace('%%', '%') 
    fmt = re.sub('(%\w)', r'{\1}', fmt) 
    return fmt.format(**d).format(ts) 

def main(ts, format): 
    if ts.year < 1900: 
     return ancient_format(ts, fmt) 
    else: 
     return ts.strftime(fmt) 

: 우리는 간단한 코드에 와서

>>> re.sub('(%\w)', r'{\1}', '%Y-%m-%d %H sdf') 
'{%Y}-{%m}-{%d} {%H} sdf' 

과 끝 dstrftime table의 일부 지정자에 해당하는 키가있는 전역 사전입니다.

편집이
는 명확히하기 :이 방법은 다음 지정자에 대한 작동합니다 : 당신이 텍스트 정보를 필요로하는 경우 %Y, %m, %d, %H, %M, %S, %f, 즉, 숫자 된 것을, 당신은 바벨이나 다른 솔루션과 함께 더 좋을 것입니다.

1

babel 국제화 라이브러리에는 문제가없는 것으로 보입니다. babel.dates

+0

비표준 지정자 – SilentGhost

+0

을 사용해야한다는 점을 제외하면 문제가있는 이유는 무엇입니까? 그들이 복수형 엔티티를 필요로하기 때문에 –

+0

이 있습니다. – SilentGhost

1

캘린더는 정확히 400 년마다 동일합니다. 따라서 datetime.strftime()에 전화하기 전에 year >= 1900과 같이 400의 배수로 연도를 변경하면 충분합니다.

코드

문제와 같은 접근 방식이 무엇인지 보여줍니다

#/usr/bin/env python2.6 
import re 
import warnings 
from datetime import datetime 


def strftime(datetime_, format, force=False): 
    """`strftime()` that works for year < 1900. 

    Disregard calendars shifts. 

    >>> def f(fmt, force=False): 
    ...  return strftime(datetime(1895, 10, 6, 11, 1, 2), fmt, force) 
    >>> f('abc %Y %m %D') 
    'abc 1895 10 10/06/95' 
    >>> f('%X') 
    '11:01:02' 
    >>> f('%c') #doctest:+NORMALIZE_WHITESPACE 
    Traceback (most recent call last): 
    ValueError: '%c', '%x' produce unreliable results for year < 1900 
    use force=True to override 
    >>> f('%c', force=True) 
    'Sun Oct 6 11:01:02 1895' 
    >>> f('%x') #doctest:+NORMALIZE_WHITESPACE 
    Traceback (most recent call last): 
    ValueError: '%c', '%x' produce unreliable results for year < 1900 
    use force=True to override 
    >>> f('%x', force=True) 
    '10/06/95' 
    >>> f('%%x %%Y %Y') 
    '%x %Y 1895' 
    """ 
    year = datetime_.year 
    if year >= 1900: 
     return datetime_.strftime(format) 

    # make year larger then 1900 using 400 increment 
    assert year < 1900 
    factor = (1900 - year - 1) // 400 + 1 
    future_year = year + factor * 400 
    assert future_year > 1900 

    format = Specifier('%Y').replace_in(format, year) 
    result = datetime_.replace(year=future_year).strftime(format) 
    if any(f.ispresent_in(format) for f in map(Specifier, ['%c', '%x'])): 
     msg = "'%c', '%x' produce unreliable results for year < 1900" 
     if not force: 
      raise ValueError(msg + " use force=True to override") 
     warnings.warn(msg) 
     result = result.replace(str(future_year), str(year)) 
    assert (future_year % 100) == (year % 100) # last two digits are the same 
    return result 


class Specifier(str): 
    """Model %Y and such in `strftime`'s format string.""" 
    def __new__(cls, *args): 
     self = super(Specifier, cls).__new__(cls, *args) 
     assert self.startswith('%') 
     assert len(self) == 2 
     self._regex = re.compile(r'(%*{0})'.format(str(self))) 
     return self 

    def ispresent_in(self, format): 
     m = self._regex.search(format) 
     return m and m.group(1).count('%') & 1 # odd number of '%' 

    def replace_in(self, format, by): 
     def repl(m): 
      n = m.group(1).count('%') 
      if n & 1: # odd number of '%' 
       prefix = '%'*(n-1) if n > 0 else '' 
       return prefix + str(by) # replace format 
      else: 
       return m.group(0) # leave unchanged 
     return self._regex.sub(repl, format) 


if __name__=="__main__": 
    import doctest; doctest.testmod() 
1

그냥 재미를 위해, 나는이 해결책을 endend.

a = datetime.datetime(1322, 10, 10) 
# %Y%m%d 
''.join(map(lambda x: '{:02}'.format(getattr(a, x)), ('year', 'month', 'day'))) 
# %Y-%m-%d 
'-'.join(map(lambda x: '{:02}'.format(getattr(a, x)), ('year', 'month', 'day'))) 
# %Y%m%d%H%M%S 
''.join(map(lambda x: '{:02}'.format(getattr(a, x)), ('year', 'month', 'day', 'hour', 'minute', 'second'))) 
관련 문제