This should be pretty simple but I can't get the syntax correct. So, I have a parameter dictionary as below -
paramDict = {
StartPostingDateFilter": {
"msgPrompt": "Start date",
"dataType": "datetime",
"tableField": [{"table":"TableName",
"field":"ColumnName"}],
"value": ["2006-01-01"]
}
}
StartPostingDateFilter = paramDict['StartPriorDateFilter']['value'][0]
Now, I want to subtract one year from the "StartPriorDateFilter" user provided date value. How do I take care of it if it's a leap year? I want to achieve the below -
If, StartPostingDateFilter = '2006-01-01'
Then create new variable, NewStartPostingDateFilter = '2005-01-01'
Thanks.
You could use dateutil:
from dateutil.relativedelta import relativedelta
from dateutil import parser
d = parser.parse(StartPostingDateFilter)
print((d - relativedelta(years=1)).date())
2005-01-01
You could also use datetime and replace catching feb 29th returning the year - 1 and feb 28th if it was:
d = datetime.strptime(StartPostingDateFilter, "%Y-%m-%d")
sub = d.replace(year=d.year - 1) if (d.month != 2 and d.day) != 29 else datetime(d.year-1, 2, 28)
Related
For the function below, I am inputting a string like "6/29/2020" and "8/10/2010" and I want to get a numbers of days after Jan. 1, 2010. For example, if I input "1/29/2010", I want the integer 29 to be returned.
Currently, I have gotten "6/29/2020" to a string "2020-06-29". Now I just need help with converting that string into the days after Jan. 1, 2010.
I feel like I have posted everything needed for you to help, but if you need more information, let me know. Thank You for helping me with this problem.
def day_conversion(dates):
import datetime
i = 0
for day in dates:
day = day.split('/')
if len(day[0]) == 1:
day[0] = f"0{day[0]}"
if len(day[1]) == 1:
day[1] = f"0{day[1]}"
day = f"{day[2]}-{day[0]}-{day[1]}"
# day = date.format(day)
# from datetime import date
# day0 = date(2000, 1, 1)
# day = day - day0
dates[i] = day
i += 1
return dates
datetime has a function for parsing dates, and subtracting two datetime objects gives a timedelta object with a .days attribute:
from datetime import datetime
def days_since_jan1_2010(date):
dt = datetime.strptime(date, '%m/%d/%Y')
diff = dt - datetime(2010, 1, 1)
return diff.days
def day_conversion(dates):
return [days_since_jan1_2010(d) for d in dates]
print(day_conversion(['6/29/2020', '8/10/2010', '1/1/2010', '1/2/2010']))
Output:
[3832, 221, 0, 1]
Everything in the previous answer is correct, but just thought I'd point out that you were very nearly there if you include the commented out part in your code above except for the following points:
from datetime import date needs to come before you try to use date.
You want date.fromisoformat, not date.format.
Your code has Jan 1 2000 but you state in your question that you want the number of days from Jan 1 2010.
If you substitute the commented part of your original code for the following four lines you should get the result you are after.
from datetime import date
day = date.fromisoformat(day)
day0 = date(2010, 1, 1)
day = day - day0
I have a url that I need to send a request to using date variables. The https address takes the date variables. I'd like to assign the dates to the address string using something like the formatting operator % in Python. Does R have a similar operator or do I need to rely on paste()?
# Example variables
year = "2008"
mnth = "1"
day = "31"
This is what I would do in Python 2.7:
url = "https:.../KBOS/%s/%s/%s/DailyHistory.html" % (year, mnth, day)
Or using .format() in 3.+.
The only I'd know to do in R seems verbose and relies on paste:
url_start = "https:.../KBOS/"
url_end = "/DailyHistory.html"
paste(url_start, year, "/", mnth, "/", day, url_end)
Is there a better way of doing this?
The equivalent in R is sprintf:
year = "2008"
mnth = "1"
day = "31"
url = sprintf("https:.../KBOS/%s/%s/%s/DailyHistory.html", year, mnth, day)
#[1] "https:.../KBOS/2008/1/31/DailyHistory.html"
Also, although I think it is an overkill, you could define an operator yourself too.
`%--%` <- function(x, y) {
do.call(sprintf, c(list(x), y))
}
"https:.../KBOS/%s/%s/%s/DailyHistory.html" %--% c(year, mnth, day)
#[1] "https:.../KBOS/2008/1/31/DailyHistory.html"
As an alternative to sprintf, you might want to check out glue.
Update: In stringr 1.2.0 they've added a wrapper function of glue::glue(), str_glue()
library(glue)
year = "2008"
mnth = "1"
day = "31"
url = glue("https:.../KBOS/{year}/{mnth}/{day}/DailyHistory.html")
url
#> https:.../KBOS/2008/1/31/DailyHistory.html
The stringr package has the str_interp() function:
year = "2008"
mnth = "1"
day = "31"
stringr::str_interp("https:.../KBOS/${year}/${mnth}/${day}/DailyHistory.html")
[1] "https:.../KBOS/2008/1/31/DailyHistory.html"
or using a list (note that now numeric values are passed):
stringr::str_interp("https:.../KBOS/${year}/${mnth}/${day}/DailyHistory.html",
list(year = 2008, mnth = 1, day = 31))
[1] "https:.../KBOS/2008/1/31/DailyHistory.html"
BTW, formatting directives can also be passed, e.g., if the month fields needs to be two characters wide:
stringr::str_interp("https:.../KBOS/${year}/$[02i]{mnth}/${day}/DailyHistory.html",
list(year = 2008, mnth = 1, day = 31))
[1] "https:.../KBOS/2008/01/31/DailyHistory.html"
I must have the current year and month in datetime.
I use this:
datem = datetime.today().strftime("%Y-%m")
datem = datetime.strptime(datem, "%Y-%m")
Is there maybe another way?
Try this solution:
from datetime import datetime
currentSecond= datetime.now().second
currentMinute = datetime.now().minute
currentHour = datetime.now().hour
currentDay = datetime.now().day
currentMonth = datetime.now().month
currentYear = datetime.now().year
Use:
from datetime import datetime
today = datetime.today()
datem = datetime(today.year, today.month, 1)
I assume you want the first of the month.
Use:
from datetime import datetime
current_month = datetime.now().strftime('%m') // 02 //This is 0 padded
current_month_text = datetime.now().strftime('%h') // Feb
current_month_text = datetime.now().strftime('%B') // February
current_day = datetime.now().strftime('%d') // 23 //This is also padded
current_day_text = datetime.now().strftime('%a') // Fri
current_day_full_text = datetime.now().strftime('%A') // Friday
current_weekday_day_of_today = datetime.now().strftime('%w') //5 Where 0 is Sunday and 6 is Saturday.
current_year_full = datetime.now().strftime('%Y') // 2018
current_year_short = datetime.now().strftime('%y') // 18 without century
current_second= datetime.now().strftime('%S') //53
current_minute = datetime.now().strftime('%M') //38
current_hour = datetime.now().strftime('%H') //16 like 4pm
current_hour = datetime.now().strftime('%I') // 04 pm
current_hour_am_pm = datetime.now().strftime('%p') // 4 pm
current_microseconds = datetime.now().strftime('%f') // 623596 Rarely we need.
current_timzone = datetime.now().strftime('%Z') // UTC, EST, CST etc. (empty string if the object is naive).
Reference: 8.1.7. strftime() and strptime() Behavior
Reference: strftime() and strptime() Behavior
The above things are useful for any date parsing, not only now or today. It can be useful for any date parsing.
e.g.
my_date = "23-02-2018 00:00:00"
datetime.strptime(str(my_date),'%d-%m-%Y %H:%M:%S').strftime('%Y-%m-%d %H:%M:%S+00:00')
datetime.strptime(str(my_date),'%d-%m-%Y %H:%M:%S').strftime('%m')
And so on...
>>> from datetime import date
>>> date.today().month
2
>>> date.today().year
2020
>>> date.today().day
13
The question asks to use datetime specifically.
This is a way that uses datetime only:
from datetime import datetime
year = datetime.now().year
month = datetime.now().month
Late answer, but you can also use:
import time
ym = time.strftime("%Y-%m")
You can write the accepted answer as a one-liner using date.replace:
datem = datetime.today().replace(day=1)
You can always use a sub-string method:
import datetime;
today = str(datetime.date.today());
curr_year = int(today[:4]);
curr_month = int(today[5:7]);
This will get you the current month and year in integer format. If you want them to be strings you simply have to remove the " int " precedence while assigning values to the variables curr_year and curr_month.
using the regular expression extract the date and time from the string then convert the string date to a datetimeindex using strptime
import re
s = "Audio was recorded at 21:50:00 02/07/2019 (UTC) by device 243B1F05 at gain setting 2 while battery state was 3.6V."
t = re.search(' (\d{2}:\d{2}:\d{2} \d{2}\/\d{2}\/\d{4}) ', s).group(1)
date=datetime.datetime.strptime(t,'%H:%M:%S %m/%d/%Y')
print(type(date))
Please what's wrong with my code:
import datetime
d = "2013-W26"
r = datetime.datetime.strptime(d, "%Y-W%W")
print(r)
Display "2013-01-01 00:00:00", Thanks.
A week number is not enough to generate a date; you need a day of the week as well. Add a default:
import datetime
d = "2013-W26"
r = datetime.datetime.strptime(d + '-1', "%Y-W%W-%w")
print(r)
The -1 and -%w pattern tells the parser to pick the Monday in that week. This outputs:
2013-07-01 00:00:00
%W uses Monday as the first day of the week. While you can pick your own weekday, you may get unexpected results if you deviate from that.
See the strftime() and strptime() behaviour section in the documentation, footnote 4:
When used with the strptime() method, %U and %W are only used in calculations when the day of the week and the year are specified.
Note, if your week number is a ISO week date, you'll want to use %G-W%V-%u instead! Those directives require Python 3.6 or newer.
In Python 3.8 there is the handy datetime.date.fromisocalendar:
>>> from datetime import date
>>> date.fromisocalendar(2020, 1, 1) # (year, week, day of week)
datetime.date(2019, 12, 30, 0, 0)
In older Python versions (3.7-) the calculation can use the information from datetime.date.isocalendar to figure out the week ISO8601 compliant weeks:
from datetime import date, timedelta
def monday_of_calenderweek(year, week):
first = date(year, 1, 1)
base = 1 if first.isocalendar()[1] == 1 else 8
return first + timedelta(days=base - first.isocalendar()[2] + 7 * (week - 1))
Both works also with datetime.datetime.
To complete the other answers - if you are using ISO week numbers, this string is appropriate (to get the Monday of a given ISO week number):
import datetime
d = '2013-W26'
r = datetime.datetime.strptime(d + '-1', '%G-W%V-%u')
print(r)
%G, %V, %u are ISO equivalents of %Y, %W, %w, so this outputs:
2013-06-24 00:00:00
Availabe in Python 3.6+; from docs.
import datetime
res = datetime.datetime.strptime("2018 W30 w1", "%Y %W w%w")
print res
Adding of 1 as week day will yield exact current week start. Adding of timedelta(days=6) will gives you the week end.
datetime.datetime(2018, 7, 23)
If anyone is looking for a simple function that returns all working days (Mo-Fr) dates from a week number consider this (based on accepted answer)
import datetime
def weeknum_to_dates(weeknum):
return [datetime.datetime.strptime("2021-W"+ str(weeknum) + str(x), "%Y-W%W-%w").strftime('%d.%m.%Y') for x in range(-5,0)]
weeknum_to_dates(37)
Output:
['17.09.2021', '16.09.2021', '15.09.2021', '14.09.2021', '13.09.2021']
In case you have the yearly number of week, just add the number of weeks to the first day of the year.
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> week = 40
>>> year = 2019
>>> date = datetime.date(year,1,1)+relativedelta(weeks=+week)
>>> date
datetime.date(2019, 10, 8)
Another solution which worked for me that accepts series data as opposed to strptime only accepting single string values:
#fw_to_date
import datetime
import pandas as pd
# fw is input in format 'YYYY-WW'
# Add weekday number to string 1 = Monday
fw = fw + '-1'
# dt is output column
# Use %G-%V-%w if input is in ISO format
dt = pd.to_datetime(fw, format='%Y-%W-%w', errors='coerce')
Here's a handy function including the issue with zero-week.
How can I subtract or add 100 years to a datetime field in the database in Django?
The date is in database, I just want to directly update the field without retrieving it out to calculate and then insert.
I would use the relativedelta function of the dateutil.relativedelta package, which will give you are more accurate 'n-years ago' calculation:
from dateutil.relativedelta import relativedelta
import datetime
years_ago = datetime.datetime.now() - relativedelta(years=5)
Then simply update the date field as others have shown here.
Use timedelta. Something like this should do the trick:
import datetime
years = 100
days_per_year = 365.24
hundred_years_later = my_object.date + datetime.timedelta(days=(years*days_per_year))
The .update() method on a Django query set allows you update all values without retrieving the object from the database. You can refer to the existing value using an F() object.
Unfortunately Python's timedelta doesn't work with years, so you'll have to work out 100 years expressed in days (it's 36524.25):
MyModel.objects.update(timestamp=F('timestamp')+timedelta(days=36524.25))
Though setting the number of days in a year as 365.25 (from (365+365+365+366)/4) perfectly offsets the difference-in-days error, it would sometimes lead to unwanted results as you might cause undesirable changes in attributes other than year, especially when you are adding/subtracting 1 or a few years.
If you want to just change the year while preventing changes in other datetime's attributes, just do the algebra on the year attribute like the following:
from datetime import datetime
d = my_obj.my_datetime_field
""" subtract 100 years. """
my_obj.my_datetime_field = datetime(d.year-100, d.month, d.day, d.hour, d.minute, d.second, d.microsecond, d.tzinfo)
my_obj.save()
Hope it helps!
Subtract year from today and use this format.
x = datetime.datetime(2020 - 100, 5, 17)
import datetime
datetime.date(datetime.date.today().year - 100, datetime.date.today().month, datetime.date.today().day)
I Know it's an old question, but I had the problem to find out a good one to solve my problem, I have created this: Use plus(+) or minus(-) to handle with:
import datetime # Don't forget to import it
def subadd_date(date,years):
''' Subtract or add Years to a specific date by pre add + or - '''
if isinstance(date,datetime.datetime) and isinstance(years,int):
day,month,year = date.day , date.month , date.year
#If you want to have HOUR, MINUTE, SECOND
#With TIME:
# day,month,year,hour,minute,second = date.day, date.month,date.year,date.hour,date.minute,date.second
py = year + years # The Past / Futur Year
new_date_str = "%s-%s-%s" % (day,month,py) # New Complete Date
# With TIME : new_date_str = "%s-%s-%s %s:%s:%s" % (month,day,py,hour,minute,second)
try:
new_date = datetime.datetime.strptime(new_date_str,"%d-%m-%Y")
except ValueError: # day is out of range for month (February 29th)
new_date_str = "%s-%s-%s" % (1,month+1,py) # New Complete Date : March 1st
new_date = datetime.datetime.strptime(new_date_str,"%d-%m-%Y")
return new_date
# With TIME : return datetime.datetime.strptime(new_date_str,"%d-%m-%Y %H:%M:%Y")
return None