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

''' 

Task Coach - Your friendly task manager 

Copyright (C) 2004-2010 Task Coach developers <developers@taskcoach.org> 

 

Task Coach is free software: you can redistribute it and/or modify 

it under the terms of the GNU General Public License as published by 

the Free Software Foundation, either version 3 of the License, or 

(at your option) any later version. 

 

Task Coach is distributed in the hope that it will be useful, 

but WITHOUT ANY WARRANTY; without even the implied warranty of 

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 

GNU General Public License for more details. 

 

You should have received a copy of the GNU General Public License 

along with this program.  If not, see <http://www.gnu.org/licenses/>. 

''' 

 

import datetime, timedelta, re 

 

class DateTime(datetime.datetime): 

 

    secondsPerMinute = 60 

    minutesPerHour = 60 

    hoursPerDay = 24 

    secondsPerHour = minutesPerHour * secondsPerMinute 

    secondsPerDay = hoursPerDay * secondsPerHour 

 

    def __new__(class_, *args, **kwargs): 

        if not args and not kwargs: 

            max = datetime.datetime.max 

            args = (max.year, max.month, max.day, 

                    max.hour, max.minute, max.second, max.microsecond) 

        return datetime.datetime.__new__(class_, *args, **kwargs) 

 

    def weeknumber(self): 

        return self.isocalendar()[1] 

 

    def weekday(self): 

        return self.isoweekday() 

 

    def toordinal(self): 

        ''' Return the ordinal number of the day, plus a fraction between 0 and 

            1 for parts of the day. ''' 

        ordinal = super(DateTime, self).toordinal() 

        seconds = self.hour * self.secondsPerHour + \ 

                  self.minute * self.secondsPerMinute + \ 

                  self.second 

        return ordinal + (seconds / float(self.secondsPerDay)) 

 

    def startOfDay(self): 

        return self.replace(hour=0, minute=0, second=0, microsecond=0) 

 

    def endOfDay(self): 

        return self.replace(hour=23, minute=59, second=59, microsecond=999999) 

 

    def endOfTomorrow(self): 

        return self.endOfDay() + timedelta.TimeDelta(days=1) 

 

    def endOfYesterday(self): 

        return self.endOfDay() - timedelta.TimeDelta(days=1) 

 

    def startOfWeek(self): 

        days = self.weekday() 

        monday = self - timedelta.TimeDelta(days=days-1) 

        return DateTime(monday.year, monday.month, monday.day) 

 

    def endOfWeek(self): 

        days = self.weekday() 

        sunday = self + timedelta.TimeDelta(days=7-days) 

        return DateTime(sunday.year, sunday.month, sunday.day).endOfDay() 

 

    def endOfWorkWeek(self): 

        days = 5 - self.weekday() 

        if days < 0: 

            days += 7 

        friday = self + timedelta.TimeDelta(days=days) 

        return DateTime(friday.year, friday.month, friday.day).endOfDay() 

 

    def startOfMonth(self): 

        return DateTime(self.year, self.month, 1) 

 

    def endOfMonth(self): 

        for lastday in [31,30,29,28]: 

            try: 

                return DateTime(self.year, self.month, lastday).endOfDay() 

            except ValueError: 

                pass 

 

    def endOfYear(self): 

        return DateTime(self.year, 12, 31).endOfDay() 

 

    def __sub__(self, other): 

        ''' Make sure substraction returns instances of the right classes. ''' 

        if self == DateTime() and isinstance(other, datetime.datetime): 

            max = timedelta.TimeDelta.max 

            return timedelta.TimeDelta(max.days, max.seconds, max.microseconds) 

        result = super(DateTime, self).__sub__(other) 

        if isinstance(result, datetime.timedelta): 

            result = timedelta.TimeDelta(result.days, result.seconds, 

                                         result.microseconds) 

        elif isinstance(result, datetime.datetime): 

            result = self.__class__(result.year, result.month, result.day, 

                                    result.hour, result.minute, result.second, 

                                    result.microsecond) 

        return result 

 

    def __add__(self, other): 

        result = super(DateTime, self).__add__(other) 

        return self.__class__(result.year, result.month, result.day, 

            result.hour, result.minute, result.second, result.microsecond) 

 

 

DateTime.max = DateTime(datetime.datetime.max.year, 12, 31).endOfDay() 

DateTime.min = DateTime(datetime.datetime.min.year, 1, 1).startOfDay() 

 

 

def parseDateTime(string, *timeDefaults): 

    if string in ('', 'None'): 

        return None 

    else: 

        args = [int(arg) for arg in re.split('[-:. ]', string)] 

        if len(args) == 3: # We parsed a date, no time 

            args.extend(timeDefaults) 

        return DateTime(*args) # pylint: disable-msg=W0142 

 

 

def Now(): 

    return DateTime.now()