summaryrefslogtreecommitdiffstats
path: root/func/yaml/timestamp.py
blob: 5c522f6e500c2c1ff8e9ceea4137153c1e026bca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
"""
pyyaml legacy
Copyright (c) 2001 Steve Howell and Friends; All Rights Reserved
(see open source license information in docs/ directory)
"""


import time, re, string
from types import ListType, TupleType

PRIVATE_NOTICE = """
  This module is considered to be private implementation
  details and is subject to change.  Please only use the
  objects and methods exported to the top level yaml package.
"""

#
# Time specific operations
#

_splitTime = re.compile('\-|\s|T|t|:|\.|Z')
matchTime = re.compile(\
          '\d+-\d+-\d+([\s|T|t]\d+:\d+:\d+.\d+(Z|(\s?[\-|\+]\d+:\d+)))?')

def _parseTime(val):
    if not matchTime.match(val): raise ValueError(val)
    tpl = _splitTime.split(val)
    if not(tpl): raise ValueError(val)
    siz = len(tpl)
    sec = 0
    if 3 == siz:
       tpl += [0,0,0,0,0,-1]
    elif 7 == siz:
       tpl.append(0)
       tpl.append(-1)
    elif 8 == siz:
       if len(tpl.pop()) > 0: raise ValueError(val)
       tpl.append(0)
       tpl.append(-1)
    elif 9 == siz or 10 == siz:
       mn = int(tpl.pop())
       hr = int(tpl.pop())
       sec = (hr*60+mn)*60
       if val.find("+") > -1: sec = -sec
       if 10 == siz: tpl.pop()
       tpl.append(0)
       tpl.append(-1)
    else:
       raise ValueError(val)
    idx = 0
    while idx < 9:
       tpl[idx] = int(tpl[idx])
       idx += 1
    if tpl[1] < 1 or tpl[1] > 12: raise ValueError(val)
    if tpl[2] < 1 or tpl[2] > 31: raise ValueError(val)
    if tpl[3] > 24: raise ValueError(val)
    if tpl[4] > 61: raise ValueError(val)
    if tpl[5] > 61: raise ValueError(val)
    if tpl[0] > 2038:
        #TODO: Truncation warning
        tpl = (2038,1,18,0,0,0,0,0,-1)
    tpl = tuple(tpl)
    ret = time.mktime(tpl)
    ret = time.localtime(ret+sec)
    ret = ret[:8] + (0,)
    return ret


class _timestamp:
    def __init__(self,val=None):
        if not val:
           self.__tval = time.gmtime()
        else:
           typ = type(val)
           if ListType == typ:
               self.__tval = tuple(val)
           elif TupleType == typ:
               self.__tval = val
           else:
               self.__tval = _parseTime(val)
           if 9 != len(self.__tval): raise ValueError
    def __getitem__(self,idx): return self.__tval[idx]
    def __len__(self): return 9
    def strftime(self,format): return time.strftime(format,self.__tval)
    def mktime(self):          return time.mktime(self.__tval)
    def asctime(self):  return time.asctime(self.__tval)
    def isotime(self):
        return "%04d-%02d-%02dT%02d:%02d:%02d.00Z" % self.__tval[:6]
    def __repr__(self): return "yaml.timestamp('%s')" % self.isotime()
    def __str__(self):  return self.isotime()
    def to_yaml_implicit(self): return self.isotime()
    def __hash__(self): return hash(self.__tval[:6])
    def __cmp__(self,other):
        try:
            return cmp(self.__tval[:6],other.__tval[:6])
        except AttributeError:
            return -1

try: # inherit from mx.DateTime functionality if available
    from mx import DateTime
    class timestamp(_timestamp):
        def __init__(self,val=None):
            _timestamp.__init__(self,val)
            self.__mxdt = DateTime.mktime(self.__tval)
        def __getattr__(self, name):
              return getattr(self.__mxdt, name)
except:
    class timestamp(_timestamp): pass



def unquote(expr):
    """
        summary: >
           Simply returns the unquoted string, and the
           length of the quoted string token at the
           beginning of the expression.
    """
    tok = expr[0]
    if "'" == tok:
        idx = 1
        odd = 0
        ret = ""
        while idx < len(expr):
            chr = expr[idx]
            if "'" == chr:
                if odd: ret += chr
                odd = not odd
            else:
                if odd:
                    tok = expr[:idx]
                    break
                ret += chr
            idx += 1
        if "'" == tok: tok = expr
        return (ret,len(tok))
    if '"' == tok:
        idx = 1
        esc = 0
        while idx < len(expr):
            chr = expr[idx]
            if '"' == chr and not esc:
                tok = expr[:idx] + '"'
                break
            if '\\' == chr and not esc: esc = 1
            else: esc = 0
            idx += 1
        if '"' == tok:
            raise SyntaxError("unmatched quote: " + expr)
        ret = eval(tok)  #TODO: find better way to unquote
        return (ret,len(tok))
    return (expr,len(expr))