def calculateElectionDayOperator( year ): if isinstance( year, RPNDateTime ): year = year.year result = calculateNthWeekdayOfMonth( year, NOVEMBER, 1, MONDAY ) result.replace( day = result.day + 1 ) return RPNDateTime( *result.getYMD( ), dateOnly = True )
def setTimeZone( datetime, timezone ): try: tz = arrow.now( timezone ).tzinfo except: tz = arrow.now( getTimeZoneName( timezone ) ).tzinfo datetime = RPNDateTime.parseDateTime( datetime ) datetime.tzinfo = tz return datetime
def calculateAscensionThursdayOperator( year ): ''' I don't know why Ascension is 39 days after Easter instead of 40, but that's how the math works out. It's the 40th day of the Easter season. Or as John Wright says, "Catholics can't count." I think it stems from the Church being created before the number 0. ''' return RPNDateTime( *calculateEaster( year ).add( RPNMeasurement( 39, 'days' ) ).getYMD( ), dateOnly = True )
def convertToUnixTimeOperator( n ): try: result = RPNDateTime.parseDateTime( n ).timestamp except OverflowError: raise ValueError( 'out of range error' ) except TypeError: raise ValueError( 'expected time value' ) except OSError: raise ValueError( 'out of range error' ) return result
def convertFromUnixTimeOperator( n ): try: result = RPNDateTime.parseDateTime( int( n ) ).getLocalTime( ) except OverflowError: raise ValueError( 'out of range error' ) except TypeError: raise ValueError( 'expected time value' ) except OSError: raise ValueError( 'out of range error' ) return result
def calculateDSTStartOperator( year ): if isinstance( year, RPNDateTime ): year = year.year if year >= 2007: return calculateNthWeekdayOfMonth( year, MARCH, 2, SUNDAY ) if year == 1974: return RPNDateTime( 1974, JANUARY, 7, dateOnly = True ) if year >= 1967: return calculateNthWeekdayOfMonth( year, APRIL, 1, SUNDAY ) raise ValueError( 'DST was not standardized before 1967' )
def calculateDSTEndOperator( year ): if isinstance( year, RPNDateTime ): year = year.year if year >= 2007: return calculateNthWeekdayOfMonth( year, NOVEMBER, 1, SUNDAY ) if year == 1974: return RPNDateTime( 1974, DECEMBER, 31, dateOnly = True ) # technically DST never ended in 1974 if year >= 1967: return calculateNthWeekdayOfMonth( year, OCTOBER, -1, SUNDAY ) raise ValueError( 'DST was not standardized before 1967' )
def makeDateTime( n ): if isinstance( n, ( RPNGenerator, int, mpf ) ): return makeDateTime( list( n ) ) if isinstance( n[ 0 ], list ): return [ makeDateTime( i ) for i in n ] if len( n ) == 1: n.append( 1 ) if len( n ) == 2: n.append( 1 ) elif len( n ) > 7: n = n[ : 7 ] return RPNDateTime( *n )
def calculateEaster( year ): '''This algorithm comes from Gauss.''' if isinstance( year, RPNDateTime ): year = year.year else: year = int( year ) a = year % 19 b = year // 100 c = year % 100 d = ( 19 * a + b - b // 4 - ( ( b - ( b + 8 ) // 25 + 1 ) // 3 ) + 15 ) % 30 e = ( 32 + 2 * ( b % 4 ) + 2 * ( c // 4 ) - d - ( c % 4 ) ) % 7 f = d + e - 7 * ( ( a + 11 * d + 22 * e ) // 451 ) + 114 month = f // 31 day = f % 31 + 1 return RPNDateTime( year, month, day, dateOnly = True )
def calculateNthWeekdayOfMonth( year, month, nth, weekday ): if weekday > SUNDAY or weekday < MONDAY: raise ValueError( 'day of week must be 1 - 7 (Monday to Sunday)' ) if isinstance( year, RPNDateTime ): year = year.year firstDayOfWeek = arrow.Arrow( year, month, 1 ).isoweekday( ) if nth < 0: day = ( ( weekday + 1 ) - firstDayOfWeek ) % 7 while day <= getLastDayOfMonth( year, month ): day += 7 day += nth * 7 else: day = ( weekday - firstDayOfWeek + 1 ) + nth * 7 if weekday >= firstDayOfWeek: day -= 7 return RPNDateTime( year, month, day, dateOnly = True )
def makeJulianTime( n ): if isinstance( n, RPNGenerator ): return makeJulianTime( list( n ) ) if len( n ) == 1: return RPNDateTime( n[ 0 ], 1, 1 ) result = RPNDateTime( n[ 0 ], 1, 1 ).add( RPNMeasurement( n[ 1 ] - 1, 'day' ) ) if len( n ) >= 3: result = result.replace( hour = n[ 2 ] ) if len( n ) >= 4: result = result.replace( minute = n[ 3 ] ) if len( n ) >= 5: result = result.replace( second = n[ 4 ] ) if len( n ) >= 6: result = result.replace( microsecond = n[ 5 ] ) return result
def getNewYearsDayOperator( year ): return RPNDateTime( year, JANUARY, 1, dateOnly = True )
def getTodayOperator( ): now = getNow( ) return RPNDateTime( *now.getYMD( ), dateOnly = True )
def getNow( ): return RPNDateTime.now( tzinfo=getLocalTimeZone( ) )
def getYesterdayOperator( ): now = getNow( ) now = now + datetime.timedelta( days = -1 ) return RPNDateTime( *now.getYMD( ), dateOnly = True )
def getTomorrowOperator( ): now = getNow( ) now = now + datetime.timedelta( days = 1 ) return RPNDateTime( *now.getYMD( ), dateOnly = True )
def calculatePentecostSundayOperator( year ): return RPNDateTime( *( calculateEaster( year ).add( RPNMeasurement( 7, 'weeks' ) ).getYMD( ) ), dateOnly = True )
def calculateAshWednesdayOperator( year ): '''46 days before Easter (40 days, not counting Sundays)''' ashWednesday = calculateEaster( year ).add( RPNMeasurement( -46, 'day' ) ) return RPNDateTime( *ashWednesday.getYMD( ), dateOnly = True )
def calculateAdventOperator( year ): firstAdvent = getChristmasDay( year ).add( RPNMeasurement( -3, 'week' ) ) firstAdvent = firstAdvent.subtract( RPNMeasurement( getWeekday( firstAdvent ), 'day' ) ) return RPNDateTime( *firstAdvent.getYMD( ), dateOnly = True )
def getEpiphanyDayOperator( year ): return RPNDateTime( year, 1, 6, dateOnly = True )
def getChristmasDay( year ): return RPNDateTime( year, DECEMBER, 25, dateOnly = True )
def getIndependenceDayOperator( year ): return RPNDateTime( year, JULY, 4, dateOnly = True )
def getVeteransDayOperator( year ): return RPNDateTime( year, NOVEMBER, 11, dateOnly = True )
def calculateGoodFridayOperator( year ): '''2 days before Easter''' goodFriday = calculateEaster( year ).add( RPNMeasurement( -2, 'day' ) ) return RPNDateTime( *goodFriday.getYMD( ), dateOnly = True )
def calculateNthWeekdayOfYearOperator( year, nth, weekday ): ''' Monday = 1, etc., as per arrow, nth == -1 for last, etc.''' if isinstance( year, RPNDateTime ): year = year.year if nth > 0: firstDay = RPNDateTime( year, 1, 1 ) firstWeekDay = weekday - firstDay.isoweekday( ) + 1 if firstWeekDay < 1: firstWeekDay += 7 result = RPNDateTime( year, 1, firstWeekDay ).add( RPNMeasurement( nth - 1, 'week' ) ) result.setDateOnly( ) return result if nth < 0: lastDay = RPNDateTime( year, 12, 31 ) lastWeekDay = weekday - lastDay.isoweekday( ) if lastWeekDay > 0: lastWeekDay -= 7 lastWeekDay += 31 result = RPNDateTime( year, 12, lastWeekDay, dateOnly = True ).add( RPNMeasurement( ( nth + 1 ), 'week' ) ) result.setDateOnly( ) return result raise ValueError( '0th weekday makes no sense in this context' )