1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 "Support for dates"
24
25 __author__ = "Donald N. Allingham"
26 __revision__ = "$Revision: 7306 $"
27
28 from gettext import gettext as _
29 from _CalSdn import *
30
31
32
33
34
35
37 """Error used to report Date errors"""
39 Exception.__init__(self)
40 self.value = value
41
44
45
46
47
48
49
51 """
52 The core date handling class for GRAMPs. Supports partial dates,
53 compound dates and alternate calendars.
54 """
55
56 MOD_NONE = 0
57 MOD_BEFORE = 1
58 MOD_AFTER = 2
59 MOD_ABOUT = 3
60 MOD_RANGE = 4
61 MOD_SPAN = 5
62 MOD_TEXTONLY = 6
63
64 QUAL_NONE = 0
65 QUAL_ESTIMATED = 1
66 QUAL_CALCULATED = 2
67
68 CAL_GREGORIAN = 0
69 CAL_JULIAN = 1
70 CAL_HEBREW = 2
71 CAL_FRENCH = 3
72 CAL_PERSIAN = 4
73 CAL_ISLAMIC = 5
74
75 EMPTY = (0, 0, 0, False)
76
77 _POS_DAY = 0
78 _POS_MON = 1
79 _POS_YR = 2
80 _POS_SL = 3
81 _POS_RDAY = 4
82 _POS_RMON = 5
83 _POS_RYR = 6
84 _POS_RSL = 7
85
86 _calendar_convert = [
87 gregorian_sdn,
88 julian_sdn,
89 hebrew_sdn,
90 french_sdn,
91 persian_sdn,
92 islamic_sdn,
93 ]
94
95 _calendar_change = [
96 gregorian_ymd,
97 julian_ymd,
98 hebrew_ymd,
99 french_ymd,
100 persian_ymd,
101 islamic_ymd,
102 ]
103
104 calendar_names = ["Gregorian",
105 "Julian",
106 "Hebrew",
107 "French Republican",
108 "Persian",
109 "Islamic"]
110
111
112 ui_calendar_names = [_("Gregorian"),
113 _("Julian"),
114 _("Hebrew"),
115 _("French Republican"),
116 _("Persian"),
117 _("Islamic")]
118
120 """
121 Creates a new Date instance.
122 """
123 if source:
124 self.calendar = source.calendar
125 self.modifier = source.modifier
126 self.quality = source.quality
127 self.dateval = source.dateval
128 self.text = source.text
129 self.sortval = source.sortval
130 else:
131 self.calendar = Date.CAL_GREGORIAN
132 self.modifier = Date.MOD_NONE
133 self.quality = Date.QUAL_NONE
134 self.dateval = Date.EMPTY
135 self.text = u""
136 self.sortval = 0
137
139 """
140 Convert to a series of tuples for data storage
141 """
142 if no_text_date:
143 text = u''
144 else:
145 text = self.text
146
147 return (self.calendar, self.modifier, self.quality,
148 self.dateval, text, self.sortval)
149
151 """
152 Load from the format created by serialize
153 """
154 (self.calendar, self.modifier, self.quality,
155 self.dateval, self.text, self.sortval) = data
156 return self
157
158 - def copy(self, source):
159 """
160 Copy all the attributes of the given Date instance
161 to the present instance, without creating a new object.
162 """
163 self.calendar = source.calendar
164 self.modifier = source.modifier
165 self.quality = source.quality
166 self.dateval = source.dateval
167 self.text = source.text
168 self.sortval = source.sortval
169
171 """
172 Comparison function. Allows the usage of equality tests.
173 This allows you do run statements like 'date1 <= date2'
174 """
175 if isinstance(other, Date):
176 return cmp(self.sortval, other.sortval)
177 else:
178 return -1
179
181 """
182 Return 1 if the given Date instance is the same as the present
183 instance IN ALL REGARDS. Needed, because the __cmp__ only looks
184 at the sorting value, and ignores the modifiers/comments.
185 """
186 if self.modifier == other.modifier \
187 and self.modifier == Date.MOD_TEXTONLY:
188 value = self.text == other.text
189 else:
190 value = (self.calendar == other.calendar and
191 self.modifier == other.modifier and
192 self.quality == other.quality and
193 self.dateval == other.dateval)
194 return value
195
197 """
198 Produces a string representation of the Date object. If the
199 date is not valid, the text representation is displayed. If
200 the date is a range or a span, a string in the form of
201 'YYYY-MM-DD - YYYY-MM-DD' is returned. Otherwise, a string in
202 the form of 'YYYY-MM-DD' is returned.
203 """
204 if self.quality == Date.QUAL_ESTIMATED:
205 qual = "est "
206 elif self.quality == Date.QUAL_CALCULATED:
207 qual = "calc "
208 else:
209 qual = ""
210
211 if self.modifier == Date.MOD_BEFORE:
212 pref = "bef "
213 elif self.modifier == Date.MOD_AFTER:
214 pref = "aft "
215 elif self.modifier == Date.MOD_ABOUT:
216 pref = "abt "
217 else:
218 pref = ""
219
220 if self.calendar != Date.CAL_GREGORIAN:
221 cal = " (%s)" % Date.calendar_names[self.calendar]
222 else:
223 cal = ""
224
225 if self.modifier == Date.MOD_TEXTONLY:
226 val = self.text
227 elif self.modifier == Date.MOD_RANGE or self.modifier == Date.MOD_SPAN:
228 val = "%04d-%02d-%02d - %04d-%02d-%02d" % (
229 self.dateval[Date._POS_YR], self.dateval[Date._POS_MON],
230 self.dateval[Date._POS_DAY], self.dateval[Date._POS_RYR],
231 self.dateval[Date._POS_RMON], self.dateval[Date._POS_RDAY])
232 else:
233 val = "%04d-%02d-%02d" % (
234 self.dateval[Date._POS_YR], self.dateval[Date._POS_MON],
235 self.dateval[Date._POS_DAY])
236 return "%s%s%s%s" % (qual, pref, val, cal)
237
239 """
240 Returns the sort value of Date object. If the value is a
241 text string, 0 is returned. Otherwise, the calculated sort
242 date is returned. The sort date is rebuilt on every assignment.
243
244 The sort value is an integer representing the value. A date of
245 March 5, 1990 would have the value of 19900305.
246 """
247 return self.sortval
248
250 """
251 Returns an integer indicating the calendar selected. The valid
252 values are::
253
254 MOD_NONE = no modifier (default)
255 MOD_BEFORE = before
256 MOD_AFTER = after
257 MOD_ABOUT = about
258 MOD_RANGE = date range
259 MOD_SPAN = date span
260 MOD_TEXTONLY = text only
261 """
262 return self.modifier
263
273
275 """
276 Returns an integer indicating the calendar selected. The valid
277 values are::
278
279 QUAL_NONE = normal (default)
280 QUAL_ESTIMATED = estimated
281 QUAL_CALCULATED = calculated
282 """
283 return self.quality
284
293
295 """
296 Returns an integer indicating the calendar selected. The valid
297 values are::
298
299 CAL_GREGORIAN - Gregorian calendar
300 CAL_JULIAN - Julian calendar
301 CAL_HEBREW - Hebrew (Jewish) calendar
302 CAL_FRENCH - French Republican calendar
303 CAL_PERSIAN - Persian calendar
304 CAL_ISLAMIC - Islamic calendar
305 """
306 return self.calendar
307
316
318 """
319 Returns a tuple representing the start date. If the date is a
320 compound date (range or a span), it is the first part of the
321 compound date. If the date is a text string, a tuple of
322 (0, 0, 0, False) is returned. Otherwise, a date of (DD, MM, YY, slash)
323 is returned. If slash is True, then the date is in the form of 1530/1.
324 """
325 if self.modifier == Date.MOD_TEXTONLY:
326 val = Date.EMPTY
327 else:
328 val = self.dateval[0:4]
329 return val
330
332 """
333 Returns a tuple representing the second half of a compound date.
334 If the date is not a compound date, (including text strings) a tuple
335 of (0, 0, 0, False) is returned. Otherwise, a date of (DD, MM, YY, slash)
336 is returned. If slash is True, then the date is in the form of 1530/1.
337 """
338 if self.modifier == Date.MOD_RANGE or self.modifier == Date.MOD_SPAN:
339 val = self.dateval[4:8]
340 else:
341 val = Date.EMPTY
342 return val
343
345 """
346 Returns the item specified
347 """
348 if self.modifier == Date.