How to increment a date using Arrow? - python

I'm using the arrow module to handle datetime objects in Python. If I get current time like this:
now = arrow.now()
...how do I increment it by one day?

Update as of 2020-07-28
Increment the day
now.shift(days=1)
Decrement the day
now.shift(days=-1)
Original Answer
DEPRECATED as of 2019-08-09
https://arrow.readthedocs.io/en/stable/releases.html
0.14.5 (2019-08-09) [CHANGE] Removed deprecated replace shift functionality. Users looking to pass plural properties to the replace function to shift values should use shift instead.
0.9.0 (2016-11-27) [FIX] Separate replace & shift functions
Increment the day
now.replace(days=1)
Decrement the day
now.replace(days=-1)
I highly recommend the docs.

The docs state that shift is to be used for adding offsets:
now.shift(days=1)
The replace method with arguments like days, hours, minutes, etc. seems to work just as shift does, though replace also has day, hour, minute, etc. arguments that replace the value in given field with the provided value.
In any case, I think e.g. now.shift(hours=-1) is much clearer than now.replace.

See documentation
now = arrow.now()
oneDayFromNow = now.replace(days+=1)

Related

Python - Pandas - Difference between timestamps and period range

I am having troubles understanding the difference between a PeriodIndex and a DateTimeIndex, and when to use which. In particular, it always seemed to be more natural to me to use Periods as opposed to Timestamps, but recently I discovered that Timestamps seem to provide the same indexing capability, can be used with the timegrouper and also work better with Matplotlib's date functionalities. So I am wondering if there is every a reason to use Periods (a PeriodIndex)?
Periods can be use to check if a specific event occurs within a certain period. Basically a Period represents an interval while a Timestamp represents a point in time.
# For example, this will return True since the period is 1Day. This test cannot be done with a Timestamp.
p = pd.Period('2017-06-13')
test = pd.Timestamp('2017-06-13 22:11')
p.start_time < test < p.end_time
I believe the simplest reason for ones to use Periods/Timestamps is whether attributes from a Period and a Timestamp are needed for his/her code.

pandas groupby offsets different start

I have a simple offset question that I cannot seem to find the answer for in the other previous posts. I am trying to groupby weeks, but the default df.groupby(pd.TimeGrouper('1W')) gives me the groupby starting on Sunday.
Say for instance I want this groupby to start on Tuesday. I tried to naively add pd.DateOffset(days=2) as an additional argument but that did not seem to work.
Offset strings can include a component that specifies when the type of period should start.
In your case, you want W-Tue
df.groupby(pd.TimeGrouper('W-Tue'))

Specify a datetime.date without a day in Python

Is there a way to specify a datetime.date without a day like that:
datetime.date(year=1900, month=1, day=None)
I have a dataset with not full specified dates (sometimes only the year and the month is in it). I want to reprepsent that with a datetime.date without doing tricks.
"Beautiful is better than ugly. Explicit is better than implicit..." - Python's Philosophy
You cannot do that by built-in datetime.date. Python datetime.date doesn't have function signature as not to put the day value. Perhaps it is due to the fact that date without day (of month) is naturally an incomplete date in real life.
Additionally, since day input is seen as Integer thus it must have value. And the default integer value as 0 will cause day representation error (albeit the internal mechanism for counting datetime might work around with it), as our day in real life starts with 1. In short, datetime.date has done a pretty good job (in terms of safe of use) - consistent with its "Explicit is better than implicit philosophy" - by not letting the user to call it without specifying day (that is: by hinting what is required in the function signature as what every good programmer would do).
But, you could create your own function wrapper whenever you feel it is annoying or unnecessary too.
Edit:
or using Python's own wrapper:
monthdate = functools.partial(datetime.date, day=1) #edit by ShadowRanger
To me, what seems to be the simplest practice would be to use the current built-in with the value of day as 1.
datetime.date(1900, 1, 1)
It is a very short ,1 to be added
datetime.date represents a day in Gregorian calendar. It is immutable and therefore all values must be known at the instant it is created. You can't omit the day if you use the constructor explicitly.
I have a dataset with not full specified dates
datetime.strptime() provides the default values if necessary:
>>> from datetime import datetime
>>> datetime.strptime('2016-02', '%Y-%m').date()
datetime.date(2016, 2, 1)

Python: creating list of timestamps by minute

I am trying to figure out what the best way to create a list of timestamps in Python is, where the values for the items in the list increment by one minute. The timestamps would be by minute, and would be for the previous 24 hours. I need to create timestamps of the format "MM/dd/yyy HH:mm:ss" or to at least contain all of those measures. The timestamps will be an axis for a graph of data that I am collecting.
Calculating the times alone isn't too bad, as I could just get the current time, convert it to seconds, and change the value by one minute very easily. However, I am kind of stuck on figuring out the date aspect of it without having to do a lot of checking, which doesn't feel very Pythonic.
Is there an easier way to do this? For example, in JavaScript, you can get a Date() object, and simply subtract one minute from the value and JS will take care of figuring out if any of the other fields need to change and how they need to change.
datetime is the way to go, you might want to check out This Blog.
import datetime
import time
now = datetime.datetime.now()
print now
print now.ctime()
print now.isoformat()
print now.strftime("%Y%m%dT%H%M%S")
This would output
2003-08-05 21:36:11.590000
Tue Aug 5 21:36:11 2003
2003-08-05T21:36:11.590000
20030805T213611
You can also do subtraction with datetime and timedelta objects
now = datetime.datetime.now()
minute = timedelta(days=0,seconds=60,microseconds=0)
print now-minute
would output
2015-07-06 10:12:02.349574
You are looking for datetime and timedelta objects. See the docs.

Calculate next scheduled time based on cron spec

What's an efficient way to calculate the next run time of an event given the current time and a cron spec?
I'm looking for something other than "loop through every minute checking if it matches spec".
Examples of specs might be:
Every month, on the 1st and 15 at 15:01
At 10,20,30,40,50 mins past the hour every hour
Python code would be lovely but psuedo code or high level description would also be appreciated.
[Update] Assume the spec is already parsed and is in some reasonable format.
Just looking at it, I think you need to:
parse the chron spec to five arrays containing acceptable values for each field;
parse 'now' to a value for each field;
in order of minute, hour, {day-of-month OR day-of-week}, month-of year: find the lowest array value that matches or exceeds the current value, correcting for carry.
I don't know how to handle day-of-week and day-of-month simultaneously; I am sure there is a way, but on the other hand I don't think I've ever seen a spec that actually specified both. I think it would be sufficient to write a handler for either and throw an error if you receive both.
Edit: apparently if day-of-week and day-of-month are both specified, it is supposed to fire on both - ie if the rule is '15th, Wednesday' it will fire on every 15th and every Wednesday.
The croniter package does what you want:
import croniter
import datetime
now = datetime.datetime.now()
sched = '1 15 1,15 * *' # at 3:01pm on the 1st and 15th of every month
cron = croniter.croniter(sched, now)
for i in range(4):
nextdate = cron.get_next(datetime.datetime)
print nextdate
prints
2011-01-15 15:01:00
2011-02-01 15:01:00
2011-02-15 15:01:00
2011-03-01 15:01:00
although it would be nice if it were written as an actual iterator. Maybe I've got my next project ;-)

Categories

Resources