Determine a date starting from two integer numbers - python

Determine a date (as day, month, year) starting from two integer numbers that represent the year and the number of the day in that year.
i'm new to coding and I don't know where to start even.

If I understand correctly you can use Python datetime module to do what you need:
from datetime import datetime
print(datetime.strptime("2004-68", "%Y-%j").strftime("%d.%m.%Y"))
Result:
08.03.2004

You can start with creating algorithm in your head, or on paper.
Then you can translate it to python code.
or
you can read documentation about datetime lib in python and try to combine functions to you desired output. https://docs.python.org/3/library/datetime.html
For example:
from datetime import datetime, timedelta
year = 2004
days = 68
date = datetime(year, 1, 1) + timedelta(days=days-1)
# days-1 is needed because we already start with first day in year
print(date)
# 2004-03-08 00:00:00

year=int(input("year="))
days=int(input("number of days="))
day=int
month = days/28 + 1
m = int(month)
if ((year % 400 == 0) or
(year % 100 != 0) and
(year % 4 == 0)) :
day = days % 30
else:
day = days % 30 + 1
print(day,".", m, ".",year)
is this any good? or more preciseley is it corect? like i need this more basic aproach to the problem

Related

What date it was x amount of days ago excluding weekends in Python

As an example I want to see what the date would be if it was today - 6 days. However, I only want to count days that are weekdays. So given 8/22 the output should be 8/12 as that is 6 business days only.
Tried using the weekday function to return if it is a 5 or 6 for saturday and sunday and skipping those days but I am not having luck so far
Current code:
from datetime import datetime, timedelta
age = 6
counter = 0
difference = datetime.today() - timedelta(counter)
while counter <= age:
difference = datetime.today() - timedelta(counter)
counter = counter + 1
this code only returns the day with the weekends included as I haven't been able to figure out how to exclude the weekend. I set up the code to loop to check if it is a 5 or 6 using the weekday() function but I keep getting bad results when attempting that
from datetime import date, timedelta
def weekdays_between(startdate,stopdate):
day = startdate
daycount = 0
while day < stopdate :
if day.weekday() < 5 :
daycount += 1
day = day + timedelta(days=1)
return daycount
if __name__ == "__main__" :
day=date.today()
dayn=day + timedelta(days=45)
print(weekdays_between(day,dayn))
You can calculate the actual days difference by calculating the number of weekends past, and subtracting the date by the days difference and the days in weekend to get the result.
from datetime import datetime,timedelta
from math import ceil
def subtract_weekdays (from_date, diff):
no_of_weekends = ceil((diff - from_date.weekday())/5)
result_date = from_date - timedelta(days=diff + no_of_weekends * 2)
return result_date
print(subtract_weekdays(datetime.today(), 6))

Can I make any format mask I like for datetime Python

Given a date and time in a specific format can I use datetime with a format mask that suits to read in the values, when the values aren't all that typical? For example how would I create a mask that works with the following:
08264.51782528
08 = last 2 digits of year (will be within last 60 years so if the 2 digits are above current (eg. 18, then assume they're in the 20th century)
264 = number of days
51782528 = decimal representation of how far through the day (0 = midnight, 0.5 = noon, 0.999988 = 1 second to midnight the following day)
Look into timedelta.
from datetime import datetime, timedelta
# get year, day, and day_percent
if year >= 58:
year += 1900
else:
year += 2000
date = datetime(year, 1, 1) + timedelta(days=day-1) + (timedelta(days=1) * day_percent)
This assumes day 1 is the first day of the year (January 1st).

For-loop for days over years, python script for targeting data

If I want to add a loop to constrain days as well, what is the easiest way to do it, considering different length of month, leap years etc.
This is the script with years and months:
yearStart = 2010
yearEnd = 2017
monthStart = 1
monthEnd = 12
for year in list(range(yearStart, yearEnd + 1)):
for month in list(range(monthStart, monthEnd + 1)):
startDate = '%04d%02d%02d' % (year, month, 1)
numberOfDays = calendar.monthrange(year, month)[1]
lastDate = '%04d%02d%02d' % (year, month, numberOfDays)
If you want only the days then this code, using the pendulum library, is probably the easiest.
>>> import pendulum
>>> first_date = pendulum.Pendulum(2010, 1, 1)
>>> end_date = pendulum.Pendulum(2018, 1, 1)
>>> for day in pendulum.period(first_date, end_date).range('days'):
... print (day)
... break
...
2010-01-01T00:00:00+00:00
pendulum has many other nice features. For one thing, it's a drop-in replacement for datetime. Therefore, many of the properties and methods that you are familiar with using for that class will also be available to you.
You may want to use datetime in addition to calendar library. I am exactly not sure on requirements. But it appears you want the first date and last date of a given month and year. And, then loop through those dates. The following function will give you the first day and last day of each month. Then, you can loop between those two dates in whichever way you want.
import datetime
import calendar
def get_first_last_day(month, year):
date = datetime.datetime(year=year, month=month, day=1)
first_day = date.replace(day = 1)
last_day = date.replace(day = calendar.monthrange(date.year, date.month)[1])
return first_day, last_day
Adding the logic for looping through 2 dates as well.
d = first_day
delta = datetime.timedelta(days=1)
while d <= last_day:
print d.strftime("%Y-%m-%d")
d += delta

Count Dates in Python

I am trying to count the number of Friday the 13ths per year from 1950-2050 using Python (I know, a little late). I am not familiar with any date/calendar packages to use. Any thoughts?
This has a direct solution. Use sum to count the number of times where the 13th of the month is a Friday:
>>> from datetime import datetime # the function datetime from module datetime
>>> sum(datetime(year, month, 13).weekday() == 4
for year in range(1950, 2051) for month in range(1,13))
174
the datetime.date class has a weekday() function that gives you the day of the week (indexed from 0) as an integer, so Friday is 4. There's also isoweekday() that indexes days from 1, it's up to you which you prefer.
Anyway, a simple solution would be:
friday13 = 0
months = range(1,13)
for year in xrange(1950, 2051):
for month in months:
if date(year, month, 13).weekday() == 4:
friday13 += 1
Is it some kind of exercise or homework? I faintly remember of having solved it. I can give you a hint, I seem to have used Calendar.itermonthdays2 Of course there should be other ways to solve it as well.
Sounds like homework. Hint (weekday 4 is a Friday):
import datetime
print(datetime.datetime(1950,1,13).weekday())
While other solutions are clear and simple, the following one is more "calendarist". You will need the dateutil package, which is installable as a package:
from datetime import datetime
from dateutil import rrule
fr13s = list(rrule.rrule(rrule.DAILY,
dtstart=datetime(1950,1,13),
until=datetime(2050,12,13),
bymonthday=[13],
byweekday=[rrule.FR]))
# this returns a list of 174 datetime objects
You see these five arguments of rrule.rrule: Take every rrule.DAILY (day) between dtstart and until where bymonthday is 13 and byweekday is rrule.FR (Friday).
from datetime import *
from time import strptime
yil = input("yilni kiritnig:: ")
kun1 = "01/01/"+yil
kun1 = datetime.strptime(kun1, "%d/%m/%Y")
while 1:
if kun1.strftime("%A") == "Friday":
break
kun1 = kun1 + timedelta(days=1)
count = 0
while 1:
if int(kun1.strftime("%Y")) == int(yil)+1:
break
if kun1.strftime("%d") == "13":
count+=1
kun1=kun1+timedelta(days=7)
print(count)

How to calculate number of days between two given dates

If I have two dates (ex. '8/18/2008' and '9/26/2008'), what is the best way to get the number of days between these two dates?
If you have two date objects, you can just subtract them, which computes a timedelta object.
from datetime import date
d0 = date(2008, 8, 18)
d1 = date(2008, 9, 26)
delta = d1 - d0
print(delta.days)
The relevant section of the docs:
https://docs.python.org/library/datetime.html.
See this answer for another example.
Using the power of datetime:
from datetime import datetime
date_format = "%m/%d/%Y"
a = datetime.strptime('8/18/2008', date_format)
b = datetime.strptime('9/26/2008', date_format)
delta = b - a
print delta.days # that's it
Days until Christmas:
>>> import datetime
>>> today = datetime.date.today()
>>> someday = datetime.date(2008, 12, 25)
>>> diff = someday - today
>>> diff.days
86
More arithmetic here.
everyone has answered excellently using the date,
let me try to answer it using pandas
dt = pd.to_datetime('2008/08/18', format='%Y/%m/%d')
dt1 = pd.to_datetime('2008/09/26', format='%Y/%m/%d')
(dt1-dt).days
This will give the answer.
In case one of the input is dataframe column. simply use dt.days in place of days
(dt1-dt).dt.days
You want the datetime module.
>>> from datetime import datetime
>>> datetime(2008,08,18) - datetime(2008,09,26)
datetime.timedelta(4)
Another example:
>>> import datetime
>>> today = datetime.date.today()
>>> print(today)
2008-09-01
>>> last_year = datetime.date(2007, 9, 1)
>>> print(today - last_year)
366 days, 0:00:00
As pointed out here
from datetime import datetime
start_date = datetime.strptime('8/18/2008', "%m/%d/%Y")
end_date = datetime.strptime('9/26/2008', "%m/%d/%Y")
print abs((end_date-start_date).days)
It also can be easily done with arrow:
import arrow
a = arrow.get('2017-05-09')
b = arrow.get('2017-05-11')
delta = (b-a)
print delta.days
For reference: http://arrow.readthedocs.io/en/latest/
without using Lib just pure code:
#Calculate the Days between Two Date
daysOfMonths = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
def isLeapYear(year):
# Pseudo code for this algorithm is found at
# http://en.wikipedia.org/wiki/Leap_year#Algorithm
## if (year is not divisible by 4) then (it is a common Year)
#else if (year is not divisable by 100) then (ut us a leap year)
#else if (year is not disible by 400) then (it is a common year)
#else(it is aleap year)
return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
def Count_Days(year1, month1, day1):
if month1 ==2:
if isLeapYear(year1):
if day1 < daysOfMonths[month1-1]+1:
return year1, month1, day1+1
else:
if month1 ==12:
return year1+1,1,1
else:
return year1, month1 +1 , 1
else:
if day1 < daysOfMonths[month1-1]:
return year1, month1, day1+1
else:
if month1 ==12:
return year1+1,1,1
else:
return year1, month1 +1 , 1
else:
if day1 < daysOfMonths[month1-1]:
return year1, month1, day1+1
else:
if month1 ==12:
return year1+1,1,1
else:
return year1, month1 +1 , 1
def daysBetweenDates(y1, m1, d1, y2, m2, d2,end_day):
if y1 > y2:
m1,m2 = m2,m1
y1,y2 = y2,y1
d1,d2 = d2,d1
days=0
while(not(m1==m2 and y1==y2 and d1==d2)):
y1,m1,d1 = Count_Days(y1,m1,d1)
days+=1
if end_day:
days+=1
return days
# Test Case
def test():
test_cases = [((2012,1,1,2012,2,28,False), 58),
((2012,1,1,2012,3,1,False), 60),
((2011,6,30,2012,6,30,False), 366),
((2011,1,1,2012,8,8,False), 585 ),
((1994,5,15,2019,8,31,False), 9239),
((1999,3,24,2018,2,4,False), 6892),
((1999,6,24,2018,8,4,False),6981),
((1995,5,24,2018,12,15,False),8606),
((1994,8,24,2019,12,15,True),9245),
((2019,12,15,1994,8,24,True),9245),
((2019,5,15,1994,10,24,True),8970),
((1994,11,24,2019,8,15,True),9031)]
for (args, answer) in test_cases:
result = daysBetweenDates(*args)
if result != answer:
print "Test with data:", args, "failed"
else:
print "Test case passed!"
test()
For calculating dates and times, there are several options but I will write the simple way:
from datetime import timedelta, datetime, date
import dateutil.relativedelta
# current time
date_and_time = datetime.now()
date_only = date.today()
time_only = datetime.now().time()
# calculate date and time
result = date_and_time - timedelta(hours=26, minutes=25, seconds=10)
# calculate dates: years (-/+)
result = date_only - dateutil.relativedelta.relativedelta(years=10)
# months
result = date_only - dateutil.relativedelta.relativedelta(months=10)
# week
results = date_only - dateutil.relativedelta.relativedelta(weeks=1)
# days
result = date_only - dateutil.relativedelta.relativedelta(days=10)
# calculate time
result = date_and_time - timedelta(hours=26, minutes=25, seconds=10)
result.time()
Hope it helps
There is also a datetime.toordinal() method that was not mentioned yet:
import datetime
print(datetime.date(2008,9,26).toordinal() - datetime.date(2008,8,18).toordinal()) # 39
https://docs.python.org/3/library/datetime.html#datetime.date.toordinal
date.toordinal()
Return the proleptic Gregorian ordinal of the date, where January 1 of year 1 has ordinal 1. For any date object d,
date.fromordinal(d.toordinal()) == d.
Seems well suited for calculating days difference, though not as readable as timedelta.days.
from datetime import date
def d(s):
[month, day, year] = map(int, s.split('/'))
return date(year, month, day)
def days(start, end):
return (d(end) - d(start)).days
print days('8/18/2008', '9/26/2008')
This assumes, of course, that you've already verified that your dates are in the format r'\d+/\d+/\d+'.
Here are three ways to go with this problem :
from datetime import datetime
Now = datetime.now()
StartDate = datetime.strptime(str(Now.year) +'-01-01', '%Y-%m-%d')
NumberOfDays = (Now - StartDate)
print(NumberOfDays.days) # Starts at 0
print(datetime.now().timetuple().tm_yday) # Starts at 1
print(Now.strftime('%j')) # Starts at 1
If you want to code the calculation yourself, then here is a function that will return the ordinal for a given year, month and day:
def ordinal(year, month, day):
return ((year-1)*365 + (year-1)//4 - (year-1)//100 + (year-1)//400
+ [ 0,31,59,90,120,151,181,212,243,273,304,334][month - 1]
+ day
+ int(((year%4==0 and year%100!=0) or year%400==0) and month > 2))
This function is compatible with the date.toordinal method in the datetime module.
You can get the number of days of difference between two dates as follows:
print(ordinal(2021, 5, 10) - ordinal(2001, 9, 11))
Without using datetime object in python.
# A date has day 'd', month 'm' and year 'y'
class Date:
def __init__(self, d, m, y):
self.d = d
self.m = m
self.y = y
# To store number of days in all months from
# January to Dec.
monthDays = [31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 ]
# This function counts number of leap years
# before the given date
def countLeapYears(d):
years = d.y
# Check if the current year needs to be considered
# for the count of leap years or not
if (d.m <= 2) :
years-= 1
# An year is a leap year if it is a multiple of 4,
# multiple of 400 and not a multiple of 100.
return int(years / 4 - years / 100 + years / 400 )
# This function returns number of days between two
# given dates
def getDifference(dt1, dt2) :
# COUNT TOTAL NUMBER OF DAYS BEFORE FIRST DATE 'dt1'
# initialize count using years and day
n1 = dt1.y * 365 + dt1.d
# Add days for months in given date
for i in range(0, dt1.m - 1) :
n1 += monthDays[i]
# Since every leap year is of 366 days,
# Add a day for every leap year
n1 += countLeapYears(dt1)
# SIMILARLY, COUNT TOTAL NUMBER OF DAYS BEFORE 'dt2'
n2 = dt2.y * 365 + dt2.d
for i in range(0, dt2.m - 1) :
n2 += monthDays[i]
n2 += countLeapYears(dt2)
# return difference between two counts
return (n2 - n1)
# Driver program
dt1 = Date(31, 12, 2018 )
dt2 = Date(1, 1, 2019 )
print(getDifference(dt1, dt2), "days")
If you don't have a date handling library (or you suspect it has bugs in it), here's an abstract algorithm that should be easily translatable into most languages.
Perform the following calculation on each date, and then simply subtract the two results. All quotients and remainders are positive integers.
Step A. Start by identifying the parts of the date as Y (year), M (month) and D (day). These are variables that will change as we go along.
Step B. Subtract 3 from M
(so that January is -2 and December is 9).
Step C. If M is negative, add 12 to M and subtract 1 from the year Y.
(This changes the "start of the year" to 1 March, with months numbered 0 (March) through 11 (February). The reason to do this is so that the "day number within a year" doesn't change between leap years and ordinary years, and so that the "short" month is at the end of the year, so there's no following month needing special treatment.)
Step D.
Divide M by 5 to get a quotient Q₁ and remainder R₁. Add Q₁ × 153 to D. Use R₁ in the next step.
(There are 153 days in every 5 months starting from 1 March.)
Step E. Divide R₁ by 2 to get a quotient Q₂ and ignore the remainder. Add R₁ × 31 - Q₂ to D.
(Within each group of 5 months, there are 61 days in every 2 months, and within that the first of each pair of months is 31 days. It's safe to ignore the fact that Feb is shorter than 30 days because at this point you only care about the day number of 1-Feb, not of 1-Mar the following year.)
Steps D & E combined - alternative method
Before the first use, set L=[0,31,61,92,122,153,184,214,245,275,306,337]
(This is a tabulation of the cumulative number of days in the (adjusted) year before the first day of each month.)
Add L[M] to D.
Step F
Skip this step if you use Julian calendar dates rather than Gregorian calendar dates; the change-over varies between countries, but is taken as 3 Sep 1752 in most English-speaking countries, and 4 Oct 1582 in most of Europe.
You can also skip this step if you're certain that you'll never have to deal with dates outside the range 1-Mar-1900 to 28-Feb-2100, but then you must make the same choice for all dates that you process.
Divide Y by 100 to get a quotient Q₃ and remainder R₃. Divide Q₃ by 4 to get another quotient Q₄ and ignore the remainder. Add Q₄ + 36524 × Q₃ to D.
Assign R₃ to Y.
Step G.
Divide the Y by 4 to get a quotient Q₅ and ignore the remainder. Add Q₅ + 365 × Y to D.
Step H. (Optional)
You can add a constant of your choosing to D, to force a particular date to have a particular day-number.
Do the steps A~G for each date, getting D₁ and D₂.
Step I.
Subtract D₁ from D₂ to get the number of days by which D₂ is after D₁.
Lastly, a comment: exercise extreme caution dealing with dates prior to about 1760, as there was not agreement on which month was the start of the year; many places counted 1 March as the new year.

Categories

Resources