How to change the date dynamically using a command in linux - python

I am writing a python code to change the date in linux system to today-1 (dynamically). I tried various combinations but, yet I am not able to succeed. I searched and I found a close proximity to my scenario in this question .
I am able to change the date if I execute the command with static value say:
date --set="$(date +'2013%m%d %H:%M')"
However, I don't want to specify hardcoded value for year i.e., 2013. Instead i want to specify something like "%y-1" i.e.,
date --set="$(date +'%y-1%m%d %H:%M')"
If I run the above command I get the following error
[root#ramesh ~]$ date --set="$(date +'%y-1%m%d %H:%M')"
date: invalid date `14-11016 13:05'

Thanks for your answer. I did not try your approach though, reason being it has to be once again dealt with formatting issues when working with arithmetic operations incase if you want to.
So, I figured out a much simpler and generalized approach
Fetch the previous_year value with this command
date --date='1 years ago'
This gives the previous year date. Now this can be used in the python program to update the system in the following way
"date --set=$(date +'%%y%%m%s %%H:%%M') % previous_year"
This method has few advantages like
I can apply this method for day and month as well like "1 days ago", "1 month ago" along with +%d, +%m, +%y values.
e.g., date --date='1 years ago' +%y
I don't have to worry about the date and month arithmetic calculation logics

date will interpret the %y-1 literally has you showed. What you need is to retrieve the current year, subtract 1 and use this value as the new year.
To get the current_year - 1 you can do:
previous_year=$((`date +'%y'`-1))
echo $previous_year
>>> 13
Now you just need to use this variable to set the new date.

Related

Organizing date format (non-Gregorian calendar) - Python 3

I have a large sales database the first column of which is the purchase date. The problem is some of these dates are entered in DD.MM.YY format, some in YY.MM.DD and some in YYYY/MM/DD. I want to make them all to same format. What is the cleanest way I can do this?
Note 1: I'm thinking of doing a series of ifs but that would be a lot of conditions so I'm wondering if there is a cleaner shortcut.
Note 2: An additional complication is that the dates are in Jalaali calender and not Gregorian. I have the function that will convert them to gregorian but I need to pass the correct year, month, day arguments to it; this is why I want to bring them all to a single format. But additionally, this means that if you offer some "Gregorian-only" solutions, like dateutil.parser, it might not work.
Immediately after posting this I found/thought of a solution myself, but instead of deleting the question I decided to post the answer in case someone else come to a similar problem.
tl;dr - I just added a century option to dateutil.parser. I didnt know how to but I found this.
Here's my end code:
from khayyam import JalaliDate
from dateutil.parser import parse, parserinfo
class MyParserInfo(parserinfo):
def convertyear(self, year, *args, **kwargs):
if year < 100:
year += 1300
return year
if __name__ == '__main__':
dt = parse("9.12.96", MyParserInfo()).date()
a=JalaliDate(dt.year, dt.month, dt.day).todate()
print(dt)
print(a)
#1396-09-12
#2017-12-03

Convert relative time in words into formatted date format in python

How to convert relative time that are expressed in humanised words like "-100 days, -6 months, -1 year, +1 year" into YYYY-MM-DD format?
I am posting my answer to help others if they need the same thing.
What I am doing is developing a CLI application, part of the process is user will input starting date and end date, but I want the user to use a relative time like the following:
(for the sake of a an example date, October 23, 2017 would be the current date)
$ cliapp.py --start_time="10 days ago" --end_time="yesterday"
10 days ago is "2017-10-13"
yesterday is "2017-10-22"
$ cliapp.py --start_time="tomorrow"
tomorrow is "2017-10-24"
to accomplish this I found dateparser module and works exactly what I need.
here is the link to it: https://dateparser.readthedocs.io/en/latest/
If you have other solution, feel free to put on comment. :)

Parse unformatted dates in Python

I have some text, taken from different websites, that I want to extract dates from. As one can imagine, the dates vary substantially in how they are formatted, and look something like:
Posted: 10/01/2014
Published on August 1st 2014
Last modified on 5th of July 2014
Posted by Dave on 10-01-14
What I want to know is if anyone knows of a Python library [or API] which would help with this - (other than e.g. regex, which will be my fallback). I could probably relatively easily remove the "posed on" parts, but getting the other stuff consistent does not look easy.
My solution using dateutil
Following Lukas's suggestion, I used the dateutil package (seemed far more flexible than Arrow), using the Fuzzy entry, which basically ignores things which are not dates.
Caution on Fuzzy parsing using dateutil
The main thing to note with this is that as noted in the thread Trouble in parsing date using dateutil if it is unable to parse a day/month/year it takes a default value (which is the current day, unless specified), and as far as i can tell there is no flag reported to indicate that it took the default.
This would result in "random text" returning today's date of 2015-4-16 which could have caused problems.
Solution
Since I really want to know when it fails, rather than fill in the date with a default value, I ended up running twice, and then seeing if it took the default on both instances - if not, then I assumed parsing correctly.
from datetime import datetime
from dateutil.parser import parse
def extract_date(text):
date = {}
date_1 = parse(text, fuzzy=True, default=datetime(2001, 01, 01))
date_2 = parse(text, fuzzy=True, default=datetime(2002, 02, 02))
if date_1.day == 1 and date_2.day ==2:
date["day"] = "XX"
else:
date["day"] = date_1.day
if date_1.month == 1 and date_2.month ==2:
date["month"] = "XX"
else:
date["month"] = date_1.month
if date_1.year == 2001 and date_2.year ==2002:
date["year"] = "XXXX"
else:
date["year"] = date_1.year
return(date)
print extract_date("Posted: by dave August 1st")
Obviously this is a bit of a botch (so if anyone has a more elegant solution -please share), but this correctly parsed the four examples i had above [where it assumed US format for the date 10/01/2014 rather than UK format], and resulted in XX being returned appropriately when missing data entered.
You could use Arrow library:
arrow.get('2013-05-05 12:30:45', ['MM/DD/YYYY', 'MM-DD-YYYY'])
Two arguments, first a str to parse and second a list of formats to try.

Python date.today shows the next day

I'm astounded by some code I wrote some time ago. For not entering in much detail i have a method that runs through some objects, wich have a date parameter. If the date parameter is equal to today's date, goes on.
I have set this in my local machine for test and have like 695 objects all with the same date, today, but when the action is run nothing happens, so i debug it to find that my expression date.today() returns datetime.date(2014, 3, 19).
This is is incorrect, as the date of my computer from the date command is Tue Mar 18 20:56:09 AST 2014.
I used from datetime import date. This is one of the more cryptic errors i have ever got. Any experience someone can share here? Thanks a lot.
The method is not timezone aware and there's no platform-independent way to make it so. What is generally done is incorporate something like pytz and call .today() as:
datetime.utcnow().replace(tzinfo = pytz.utc).strftime('%Y-%m-%d')

Looking for *existing* Python module for determining fiscal months

I'm in calendar hell, and I'm hoping there exists a Python module out there that does what I want.
I'm making a Python web app that deals with subscriptions. It's conceptually similar to a cell phone plan: You start your subscription on a certain date (say 1.13.2011), and for every billing month you have a bunch of "sessions" (phone calls), that you would be charged for.
We need to:
Know under which billing month each session falls.
Know the start time and end time of each billing month.
For example, if you signed up on 1.13.2011, and made a phone call on 1.20.2011, it would count on your first billing month. Same for a phone call on 2.10.2011. But if you were to make a phone call on 2.15.2011, it will count on your second billing month.
Regarding start and end dates: If today is 2.15.2011, then the start date of the current month is 2.13.2011 and its end date is 3.13.2011.
You may be thinking this is not so complicated, but then you have to consider that months have different lengths. The rule for handling this is that if your subscription started on the 30th of whatever month, its cutoff dates on each month would be min(30, n_days_in_that_month). This goes for 29, 30 and 31 as well.
I tried coding this, but it got too complex. What I'm looking for is a ready-made, existing module that does these things.
For the love of God don't post an answer with a sketch of an implementation! This is useless for me. I appreciate your intentions, but in calendar hell, sketches of implementations do not help. I already have a sketch of an implementation, and debugging yours will take just as long as debugging mine.
I am only interested in using an existing module that handles such calendar tasks. Do you know one?
http://labix.org/python-dateutil
Ram's edit: The dateutil.rrule.rrule class is the one that did exactly what I wanted.
Regarding start and end dates: If today is 2.15.2011, then the start date of the current month is 2.13.2011 and its end date is 3.13.2011.
You may be thinking this is not so complicated, but then you have to consider that months have different lengths. The rule for handling this is that if your subscription started on the 30th of whatever month, its cutoff dates on each month would be min(30, n_days_in_that_month). This goes for 29, 30 and 31 as well.
Its still pretty basic. Use datetime module to store datetimes, so you can easily parse out the day (e.g., if dt is a date then dt.day). A billing cycle starts on say the 29th (toughest type of case). Let billing_cycle_day=29. A billable event occurs on say the event_day=10, event_month=5. Then since event_day < billing_cycle_day you bill to event_month's bill. Otherwise you bill to the next months bill (remembering that if month=12; you have to increment the year).
So now the billing cycle will always be from the 29th to the 28th in the next month. The complication arises if say a date like 2/29/2011 doesn't exist. E.g., a billing cycle start_date should be 2/29/2011 (but it doesn't exist); in this case you just make it the first on the next month.
billing_cycle_day = 29
year, month = 2011, 2
import datetime
def create_date_or_first_of_next_month(year, month, day):
try:
return datetime.date(year, month, day)
except ValueError:
year_n, month_n = (year, month+1) if month != 12 else (year+1, 1)
return datetime.date(year_n, month_n, 1)
This problem is not as hard as you think. All you have to do is write a function that given a starting day (like 13 or 30) it returns two date objects which are the beginning and end of the current fiscal month. You have already sketched out all the details in your question. Best to include an optional todayis parameter to the function so that you specify what day to use as a reference for today. For instance, if today is the 15th of October 2011, and you specify 13, the function would assume that you mean the 13th of October 2011. But if you want to rerun June data, you would specify todayis=date(2011,06,13)
The return values (start and end) allow you to pinpoint dates that belong in this fiscal month. But if the date is before the start date and less than 29 days before the start date, then you can also pinpoint in the previous fiscal month. The same goes for the next fiscal month. This is useful because there will be a lot of situations where you process data after a few days, so you will have a mix of two fiscal months to process.

Categories