the floor function takes keyword arguments with arbitrary values for the time intervals, making the function more flexible
updated ceil function so it operates like C's ceil function. This means that datetimes that are already on a boundary are returned
added one final ceil test