3 condition python while loop regarding checking if two dates are the same - python-2.x

I'm currently working on this problem of counting how many days between two dates including leap years.
However it keeps skipping the loop from the beginning, even though the two months and days aren't the same?
def daysBetweenDates(year1, month1, day1, year2, month2, day2):
day_count = 0
while (year2 != year1) and (month2 != month1) and (day2! = day 1):
# print "in loop" // tester
if (day2 != 0):
day2 = day2 - 1
day_count = day_count + 1
else:
if(month2 != 0):
month2 = month2 - 1
if month2 == (9 or 4 or 6 or 11):
day2 = 30
if month2 == 2:
day2 = 28
if (month2 == 2) and (year2 % 4):
day2 = 29
else:
day2 == 31
else:
year2 = year2 - 1
month2 = 12
#print day_count //tester
return day_count
# Test routine
def test():
test_cases = [((2012,1,1,2012,2,28), 58),
((2012,1,1,2012,3,1), 60),
((2011,6,30,2012,6,30), 366),
((2011,1,1,2012,8,8), 585 ),
((1900,1,1,1999,12,31), 36523)]
for (args, answer) in test_cases:
result = daysBetweenDates(*args)
if result != answer:
print "Test with data:", args, "failed"
else:
print "Test case passed!"
test()

Here's one way.
>>> from datetime import datetime
>>> diff = datetime(2012, 2, 28)-datetime(2012, 1, 1)
>>> diff.days
58

Related

Fastest algorithm to calculate the number of business days between two dates?

I have stumbled upon this problem couple of times before and there are some SO answers around but they are extremely slow e.g.
def businessDaysBetween(startDate: DateTime, endDate: DateTime): Seq[DateTime] = {
1 to daysBetween(startDate, endDate) map {
startDate.withFieldAdded(DurationFieldType.days(), _)
} diff holidays filter {
_.getDayOfWeek() match {
case DateTimeConstants.SUNDAY | DateTimeConstants.SATURDAY => false
case _ => true
}
}
}
def daysBetween(startDate: DateTime, endDate: DateTime) =
Days.daysBetween(startDate.toDateMidnight(), endDate.toDateMidnight()).getDays()
My question is not only how to compute the number of business days between two dates but also the fastest possible solution. Note that I only need to know the number of business days and not the actual dates.
And this is I think the fastest solution, only need to consider which day of the week the startDate represents. The complexity is O(C):
def businessDaysBetween(startDate: DateTime, endDate: DateTime): Int = {
val numDays = daysBetween(startDate, endDate)
val numHolidays: Int = startDate.getDayOfWeek match {
case DateTimeConstants.MONDAY => (numDays / 7)*2 + (if (numDays % 7 > 4) min(numDays % 7 - 4, 2) else 0)
case DateTimeConstants.TUESDAY => (numDays / 7)*2 + (if (numDays % 7 > 3) min(numDays % 7 - 3, 2) else 0)
case DateTimeConstants.WEDNESDAY => (numDays / 7)*2 + (if (numDays % 7 > 2) min(numDays % 7 - 2, 2) else 0)
case DateTimeConstants.THURSDAY => (numDays / 7)*2 + (if (numDays % 7 > 1) min(numDays % 7 - 1, 2) else 0)
case DateTimeConstants.FRIDAY => (numDays / 7)*2 + (if (numDays % 7 > 0) min(numDays % 7, 2) else 0)
case DateTimeConstants.SATURDAY => 1 + (numDays / 7)*2 + (if (numDays % 7 > 0) 1 else 0)
case DateTimeConstants.SUNDAY => 1 + (numDays / 7)*2 + (if (numDays % 7 > 5) 1 else 0)
}
numDays - numHolidays
}
Here is a slightly more readable version in my opinion with the same O(C) complexity:
def getPreviousWorkDay(d: DateTime): DateTime = {
d.withDayOfWeek(Math.min(d.getDayOfWeek, DateTimeConstants.FRIDAY)).withTimeAtStartOfDay()
}
def businessDaysBetween(startDate: DateTime, endDate: DateTime): Int = {
val workDayStart = getPreviousWorkDay(startDate)
val workDayEnd = getPreviousWorkDay(endDate)
val daysBetween = Days.daysBetween(workDayStart, workDayEnd).getDays
val weekendDaysBetween = daysBetween / 7 * 2
val additionalWeekend = if(workDayStart.getDayOfWeek > workDayEnd.getDayOfWeek) 2 else 0
daysBetween - weekendDaysBetween - additionalWeekend
}
I consider that the week starts on Monday (the default for Joda).
I also consider that between a Saturday and the following Friday there are 5 business days, whereas between a Monday and the following Friday there are only 4 business days.

Why does my simulated annealing algorithm generate increasingly worse solutions and converge early?

Why does my program generate increasingly worse solutions and converge so early?
I've been reading up on optimization and various meta-heuristic techniques recently and I recently decided to try and implement simulated annealing as described in this post.
I believe that I understand the theory well enough.
There is an acceptance probability that is guided by the following function
math.exp(-cost_delta/temp)
where the cost delta is the difference between the "cost" of your current solution and the cost of your new randomly generated proposed solution. The greater the cost delta, the lower probability your new solution has of being accepted and as the number of iterations increases and your temperature "cools" and approaches 0, new solutions have a increasingly smaller change of being accepted.
Your cost is determined from some objective function that you either want to minimize or maximize and your objective function will change depending on your problem.
I implemented a simulated annealing function as mentioned in the post and wikipedia:
def simulated_annealing(initial_state):
current_state = initial_state
current_cost = cost_of_state(current_state)
temp = 3.0
num_iteration = 0
while current_cost > 0:
neighbour = get_random_neighbour(current_state)
neighbour_cost = cost_of_state(neighbour)
cost_delta = neighbour_cost - current_cost
if cost_delta <= 0 or random.random() < math.exp(-cost_delta/temp):
current_state = neighbour
current_cost = neighbour_cost
print('current cost: '+str(current_cost))
print('Num of iterations: '+str(num_iteration))
num_iteration += 1
if num_iteration % 500 == 0 and temp > 0.10:
temp -= 0.10
return current_state, num_iteration
as well as a function to get a random neighbor:
def get_random_neighbour(current_state):
neighbour = [house[:] for house in current_state]
i = random.randint(0, 4)
mRange = []
mRange.extend(range(0, i))
mRange.extend(range(i+1, 4))
j = random.choice(mRange)
#j = random.randint(0, 4)#.randint(opp1, opp2)
attr_idx = random.randint(0, 4)
neighbour[i][attr_idx] = neighbour[j][attr_idx]
neighbour[j][attr_idx] = neighbour[i][attr_idx]
return neighbour
and calculate the cost of the current state based on some objective function:
def cost_of_state(state):
cost = 15
for i , h in enumerate(state):
cost -= sum([
h[nat] == 'brit' and h[col] == 'red',
h[nat] == 'swede' and h[ani] == 'dog',
h[nat] == 'dane' and h[bev] == 'tea',
i< 4 and h[col] == 'green' and state[i+1][col] == 'white',
h[col] == 'green' and h[bev] == 'coffee',
h[cig] == 'pall mall' and h[ani] == 'bird',
h[col] == 'yellow' and h[cig] == 'dunhill',
i == 2 and h[bev] == 'milk',
i == 0 and h[nat] == 'norwegian',
h[cig] == 'blends' and ((i > 0 and state[i-1][ani] == 'cat') or (i < 4 and state[i+1][ani] == 'cat')),
h[ani] == 'horse' and ((i > 0 and state[i-1][cig] == 'dunhill') or (i < 4 and state[i-1][cig] == 'dunhill')),
h[cig] == 'blue master' and h[bev] == 'root beer',
h[nat] == 'german' and h[cig] == 'prince',
h[nat] == 'norwegian' and ((i > 0 and state[i-1][col] == 'blue') or (i < 4 and state[i+1][col] == 'blue')),
h[cig] == 'blends' and ((i > 0 and state[i-1][bev] == 'water') or (i < 4 and state[i+1][bev] == 'water')),
])
return cost
as well as the code to test/run everything:
nationalities = ['dane', 'brit', 'swede', 'norwegian', 'german']
colors = ['yellow', 'red', 'white', 'green', 'blue']
animals = ['horse', 'cat', 'bird', 'fish', 'dog']
beverages = ['water', 'tea', 'milk', 'coffee', 'root beer']
cigars = ['pall mall', 'prince', 'blue master', 'dunhill', 'blends']
attributes = [nationalities, colors, animals, beverages, cigars]
num_houses = 5
nat = 0
col = 1
ani = 2
bev = 3
cig = 4
initial = []
for i in range(0, num_houses):
initial.append([attr[i] for attr in attributes])
random.seed(100)
solution, iterations = simulated_annealing(initial)
for house in solution:
print(house)
print('Number of iterations:', iterations)
Now, my problem is that when I run everything, I only see a few state changes when I actually run my program. Below you can see the output that I get from the first 10 iterations.
current cost: 11
Num of iterations: 0
current cost: 11
Num of iterations: 1
current cost: 11
Num of iterations: 2
current cost: 10
Num of iterations: 3
current cost: 10
Num of iterations: 4
current cost: 10
Num of iterations: 5
current cost: 10
Num of iterations: 6
current cost: 11
Num of iterations: 7
current cost: 11
Num of iterations: 8
current cost: 11
Num of iterations: 9
current cost: 11
Num of iterations: 10
current cost: 11
and by the time I get to iteration 65, my solutions are actually getting worse and things seem to stall:
urrent cost: 12
Num of iterations: 63
current cost: 12
Num of iterations: 64
current cost: 13
Num of iterations: 65
current cost: 13

Python 3 input and if statement

I am having some trouble with an input question that is supposed to allow the player to choose one of 5 starting races. I used the following code.
def racechoice():
players.race = input('After you get a chance to think, you choose to be...') #Here race is chosen
if players.race == "dwarf" or "Dwarf": #Race starting stats
players.race = "Dwarf"
players.level = 1
players.strength = 12
players.agility = 6
players.inteligence = 8
players.vitality = 14
elif players.race == "Orc" or "orc":
players.race = "Orc"
players.level = 1
players.strength = 14
players.agility = 10
players.inteligence = 4
players.vitality = 12
elif players.race == "elf" or "Elf":
players.level = 1
players.race = "Elf"
players.strength = 8
players.agility = 13
players.inteligence = 12
players.vitality = 7
elif players.race == "Human" or "human":
players.level = 1
players.race = "Human"
players.strength = 10
players.agility = 10
players.inteligence = 10
players.vitality = 10
elif players.race == "gnome" or "Gnome":
players.race = "Gnome"
players.strength = 5
players.agility = 11
players.intelligence = 17
players.vitality = 7
When called to display the player's stats:
def stats():
print(players.name)
print(players.race)
print("Level: "+ str(players.level) +" Strength: "+ str(players.strength) +" Agility: " + str(players.agility) +" Inteligence: "+ str(players.inteligence) +" Vitality: "+ str(players.vitality))
It comes back as Dwarf with Dwarf stats no matter what the player chooses. I'm new-ish to Python and was wondering, did I not use the if/elif statement(s) correctly?
ex) After you get a chance to think, you choose to be...Orc
Ecep
Dwarf
Level: 1 Strength: 12 Agility: 6 Inteligence: 8 Vitality: 14
There is a problem, you should do:
if players.race == "dwarf" or "players.race == Dwarf":
But even better, change your conditions to:
elif players.race.lower() == "orc":
It is also recommended that you use a class to encapsulate functionality, for example:
class Player(object):
def __init__(self, race, level, strength, agility, inteligence, vitality):
self.race = race
self.level = level
self.strength = strength
self.agility = agility
self.inteligence = inteligence
self.vitality = vitality
player = Player('Dwarf', 1, 12, 6, 8, 14)
then your racechoice function will look so:
def racechoice():
race = input('After you get a chance to think, you choose to be...')
if race.lower() == 'dwarf':
player = Player('Dwarf', 1, 12, 6, 8, 14)
elif race.lower() == 'orc':
player = Player('Orc', 1, 14, 10, 4, 12)
...
return player
You can't use or in that way. All your if/elif statements should be of the form:
if players.race == "dwarf" or players.race == "Dwarf":
"Dwarf" all by itself is considered True by Python and empty strings "" are considered False, so your first if always succeeds.

How do I convert seconds since Epoch to current date and time?

I know I posted this a while ago, but I figured out the solution. I wrote this code for a game called Roblox, but I'm just posting the code here in case anyone else who has this same problem needs a solution. Anyways, here's the code:
outputTime = true -- true: will print the current time to output window. false: won't print time
createVariable = true -- true: creates variables under game.Lighting. false: won't create variables
-----------------------------------------------------------------------------------------------
--DO NOT EDIT BELOW----------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
if(createVariable) then
yearVar = Instance.new("IntValue", game.Lighting)
yearVar.Name = "Year"
yearVar.Value = 0
monthVar = Instance.new("IntValue", game.Lighting)
monthVar.Name = "Month"
monthVar.Value = 0
dayVar = Instance.new("IntValue", game.Lighting)
dayVar.Name = "Day"
dayVar.Value = 0
hourVar = Instance.new("IntValue", game.Lighting)
hourVar.Name = "Hour"
hourVar.Value = 0
minuteVar = Instance.new("IntValue", game.Lighting)
minuteVar.Name = "Minute"
minuteVar.Value = 0
secondVar = Instance.new("IntValue", game.Lighting)
secondVar.Name = "Second"
secondVar.Value = 0
dayOfWeek = Instance.new("StringValue", game.Lighting)
dayOfWeek.Name = "DayOfWeek"
dayOfWeek.Value = "Thursday"
end
function giveZero(data)
if string.len(data) <= 1 then
return "0" .. data
else
return data
end
end
function hasDecimal(value)
if not(value == math.floor(value)) then
return true
else
return false
end
end
function isLeapYear(year)
if(not hasDecimal(year / 4)) then
if(hasDecimal(year / 100)) then
return true
else
if(not hasDecimal(year / 400)) then
return true
else
return false
end
end
else
return false
end
end
local eYear = 1970
local timeStampDayOfWeak = 5
local secondsInHour = 3600
local secondsInDay = 86400
local secondsInYear = 31536000
local secondsInLeapYear = 31622400
local monthWith28 = 2419200
local monthWith29 = 2505600
local monthWith30 = 2592000
local monthWith31 = 2678400
local monthsWith30 = {4, 6, 9, 11}
local monthsWith31 = {1, 3, 5, 7, 8, 10, 12}
local daysSinceEpoch = 0
local DOWAssociates = {"Tursday", "Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday"}
while(true) do
now = tick()
year = 1970
secs = 0
daysSinceEpoch = 0
while((secs + secondsInLeapYear) < now or (secs + secondsInYear) < now) do
if(isLeapYear(year+1)) then
if((secs + secondsInLeapYear) < now) then
secs = secs + secondsInLeapYear
year = year + 1
daysSinceEpoch = daysSinceEpoch + 366
end
else
if((secs + secondsInYear) < now) then
secs = secs + secondsInYear
year = year + 1
daysSinceEpoch = daysSinceEpoch + 365
end
end
end
secondsRemaining = now - secs
monthSecs = 0
yearIsLeapYear = isLeapYear(year)
month = 1 -- January
while((monthSecs + monthWith28) < secondsRemaining or (monthSecs + monthWith30) < secondsRemaining or (monthSecs + monthWith31) < secondsRemaining) do
if(month == 1) then
if((monthSecs + monthWith31) < secondsRemaining) then
month = 2
monthSecs = monthSecs + monthWith31
daysSinceEpoch = daysSinceEpoch + 31
else
break
end
end
if(month == 2) then
if(not yearIsLeapYear) then
if((monthSecs + monthWith28) < secondsRemaining) then
month = 3
monthSecs = monthSecs + monthWith28
daysSinceEpoch = daysSinceEpoch + 28
else
break
end
else
if((monthSecs + monthWith29) < secondsRemaining) then
month = 3
monthSecs = monthSecs + monthWith29
daysSinceEpoch = daysSinceEpoch + 29
else
break
end
end
end
if(month == 3) then
if((monthSecs + monthWith31) < secondsRemaining) then
month = 4
monthSecs = monthSecs + monthWith31
daysSinceEpoch = daysSinceEpoch + 31
else
break
end
end
if(month == 4) then
if((monthSecs + monthWith30) < secondsRemaining) then
month = 5
monthSecs = monthSecs + monthWith30
daysSinceEpoch = daysSinceEpoch + 30
else
break
end
end
if(month == 5) then
if((monthSecs + monthWith31) < secondsRemaining) then
month = 6
monthSecs = monthSecs + monthWith31
daysSinceEpoch = daysSinceEpoch + 31
else
break
end
end
if(month == 6) then
if((monthSecs + monthWith30) < secondsRemaining) then
month = 7
monthSecs = monthSecs + monthWith30
daysSinceEpoch = daysSinceEpoch + 30
else
break
end
end
if(month == 7) then
if((monthSecs + monthWith31) < secondsRemaining) then
month = 8
monthSecs = monthSecs + monthWith31
daysSinceEpoch = daysSinceEpoch + 31
else
break
end
end
if(month == 8) then
if((monthSecs + monthWith31) < secondsRemaining) then
month = 9
monthSecs = monthSecs + monthWith31
daysSinceEpoch = daysSinceEpoch + 31
else
break
end
end
if(month == 9) then
if((monthSecs + monthWith30) < secondsRemaining) then
month = 10
monthSecs = monthSecs + monthWith30
daysSinceEpoch = daysSinceEpoch + 30
else
break
end
end
if(month == 10) then
if((monthSecs + monthWith31) < secondsRemaining) then
month = 11
monthSecs = monthSecs + monthWith31
daysSinceEpoch = daysSinceEpoch + 31
else
break
end
end
if(month == 11) then
if((monthSecs + monthWith30) < secondsRemaining) then
month = 12
monthSecs = monthSecs + monthWith30
daysSinceEpoch = daysSinceEpoch + 30
else
break
end
end
end
day = 1 -- 1st
daySecs = 0
daySecsRemaining = secondsRemaining - monthSecs
while((daySecs + secondsInDay) < daySecsRemaining) do
day = day + 1
daySecs = daySecs + secondsInDay
daysSinceEpoch = daysSinceEpoch + 1
end
hour = 0 -- Midnight
hourSecs = 0
hourSecsRemaining = daySecsRemaining - daySecs
while((hourSecs + secondsInHour) < hourSecsRemaining) do
hour = hour + 1
hourSecs = hourSecs + secondsInHour
end
minute = 0 -- Midnight
minuteSecs = 0
minuteSecsRemaining = hourSecsRemaining - hourSecs
while((minuteSecs + 60) < minuteSecsRemaining) do
minute = minute + 1
minuteSecs = minuteSecs + 60
end
second = math.floor(now % 60)
year = giveZero(year)
month = giveZero(month)
day = giveZero(day)
hour = giveZero(hour)
minute = giveZero(minute)
second = giveZero(second)
remanderForDOW = daysSinceEpoch % 7
DOW = DOWAssociates[remanderForDOW + 1]
if(createVariable) then
yearVar.Value = year
monthVar.Value = month
dayVar.Value = day
hourVar.Value = hour
minuteVar.Value = minute
secondVar.Value = second
dayOfWeek.Value = DOW
end
if(outputTime) then
str = "Year: " .. year .. ", Month: " .. month .. ", Day: " .. day .. ", Hour: " .. hour .. ", Minute: " .. minute .. ", Second: ".. second .. ", Day of Week: " .. DOW
print(str)
end
wait(1)
end
----ORIGINAL POST----
What are the formulas for calculating the following given no resources except the seconds since Epoch?
Here's a list of what I need:
Current Month of year Ex: 7
Current day of month Ex: 25
Current day of week Ex: Thursday (1-7 would be acceptable)
Current hour of day Ex: 22
Current minute of hour Ex: 34
Current second of minute: 07
Here is some Lua code adapted from some C code found by Google. It does not handle timezones or Daylight Saving Time and so the outputs refers to Universal Coordinated Time (UTC).
-- based on http://www.ethernut.de/api/gmtime_8c_source.html
local floor=math.floor
local DSEC=24*60*60 -- secs in a day
local YSEC=365*DSEC -- secs in a year
local LSEC=YSEC+DSEC -- secs in a leap year
local FSEC=4*YSEC+DSEC -- secs in a 4-year interval
local BASE_DOW=4 -- 1970-01-01 was a Thursday
local BASE_YEAR=1970 -- 1970 is the base year
local _days={
-1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364
}
local _lpdays={}
for i=1,2 do _lpdays[i]=_days[i] end
for i=3,13 do _lpdays[i]=_days[i]+1 end
function gmtime(t)
print(os.date("!\n%c\t%j",t),t)
local y,j,m,d,w,h,n,s
local mdays=_days
s=t
-- First calculate the number of four-year-interval, so calculation
-- of leap year will be simple. Btw, because 2000 IS a leap year and
-- 2100 is out of range, this formula is so simple.
y=floor(s/FSEC)
s=s-y*FSEC
y=y*4+BASE_YEAR -- 1970, 1974, 1978, ...
if s>=YSEC then
y=y+1 -- 1971, 1975, 1979,...
s=s-YSEC
if s>=YSEC then
y=y+1 -- 1972, 1976, 1980,... (leap years!)
s=s-YSEC
if s>=LSEC then
y=y+1 -- 1971, 1975, 1979,...
s=s-LSEC
else -- leap year
mdays=_lpdays
end
end
end
j=floor(s/DSEC)
s=s-j*DSEC
local m=1
while mdays[m]<j do m=m+1 end
m=m-1
local d=j-mdays[m]
-- Calculate day of week. Sunday is 0
w=(floor(t/DSEC)+BASE_DOW)%7
-- Calculate the time of day from the remaining seconds
h=floor(s/3600)
s=s-h*3600
n=floor(s/60)
s=s-n*60
print("y","j","m","d","w","h","n","s")
print(y,j+1,m,d,w,h,n,s)
end
local t=os.time()
gmtime(t)
t=os.time{year=1970, month=1, day=1, hour=0} gmtime(t)
t=os.time{year=1970, month=1, day=3, hour=0} gmtime(t)
t=os.time{year=1970, month=1, day=2, hour=23-3, min=59, sec=59} gmtime(t)
The formula is not simple for a few reasons, especially leap years. You should probably use the date function on this page rather than trying to calculate it yourself.
You could use luatz
x = 1234567890
t = require "luatz.timetable".new_from_timestamp ( x )
print(t.year,t.month,t.day,t.hour,t.min,t.sec,t.yday,t.wday)
-- Or just
print(t:rfc_3339())
This is how I do it.
> time0=os.time()
> time0
1571439964
> os.date("%Y%m%d%H%M%S",time0)
20191019120604
>
os.date is a standard Lua function, if passing the first argument as "%t", it will return a table containing the following fields: year (four digits), month (1--12), day (1--31), hour (0--23), min (0--59), sec (0--61), wday (weekday, Sunday is 1), yday (day of the year), and isdst (daylight saving flag, a boolean).
Give it a test:
time = os.time()
print("time since epoch: " .. time)
date = os.date("*t", time)
print("year: " .. date.year)
print("month: " .. date.month)
print("day: " .. date.day)
print("hour: " .. date.hour)
print("minute: " .. date.min)
print("second: " .. date.sec)
print("weekday: " .. date.wday)
Output:
time since epoch: 1374826427
year: 2013
month: 7
day: 26
hour: 16
minute: 13
second: 47
weekday: 6
A much faster solution would be to use my method, which I haven't really seen anyone else use because most have access to os.date()
Since I do not have access to os.date(), here is my solution:
local tabIndexOverflow = function(seed, table)
-- This subtracts values from the table from seed until an overflow
-- This can be used for probability :D
for i = 1, #table do
if seed - table[i] <= 0 then
return i, seed
end
seed = seed - table[i]
end
end
local getDate = function(unix)
-- Given unix date, return string date
assert(unix == nil or type(unix) == "number" or unix:find("/Date%((%d+)"), "Please input a valid number to \"getDate\"")
local unix = (type(unix) == "string" and unix:match("/Date%((%d+)") / 1000 or unix or os.time()) -- This is for a certain JSON compatability. It works the same even if you don't need it
local dayCount, year, days, month = function(yr) return (yr % 4 == 0 and (yr % 100 ~= 0 or yr % 400 == 0)) and 366 or 365 end, 1970, math.ceil(unix/86400)
while days >= dayCount(year) do days = days - dayCount(year) year = year + 1 end -- Calculate year and days into that year
month, days = tabIndexOverflow(days, {31,(dayCount(year) == 366 and 29 or 28),31,30,31,30,31,31,30,31,30,31}) -- Subtract from days to find current month and leftover days
-- hours = hours > 12 and hours - 12 or hours == 0 and 12 or hours -- Change to proper am or pm time
-- local period = hours > 12 and "pm" or "am"
-- Formats for you!
-- string.format("%d/%d/%04d", month, days, year)
-- string.format("%02d:%02d:%02d %s", hours, minutes, seconds, period)
return {Month = month, day = days, year = year, hours = math.floor(unix / 3600 % 24), minutes = math.floor(unix / 60 % 60), seconds = math.floor(unix % 60)}
end
You are, however, on your own when it comes to finding the day of the week. I never cared to find whether it be the day of Thor or the day of Frige.

Calculating number of days between two dates that are in a leap year

Given two dates, what is the best method to calculate the number of days between those two dates that fall in a leap year.
For example if d1 = 12/1/2007 and d2 = 1/31/2008 then the total number of days between d1 and d2 would be 62 and the number of days that fall in a leap year would be 31.
Another example is if d1 = 12/1/2007 and d2 = 6/30/2012 then the total number of days between d1 and d2 would be 1674 and the number of days that fall in a leap year would be 548.
I already have function to calculate if a specific year is a leap year and and a function to calculate the number of days between two dates.
If anyone has such a algorithm in Delphi (Pascal) or C/C++/C# that would be greatly appreciated. Any suggestions and assistance would be great.
The solution is in python, and it shouldn't be hard to convert to any other language.
def isLeapYear(year):
if year%4 == 0:
if year%100 == 0:
if year%400 == 0:
return True
else:
return False
else:
return True
else:
return False
def daysBetweenDates(year1, month1, day1, year2, month2, day2):
cumDays = [0,31,59,90,120,151,181,212,243,273,304,334] #cumulative Days by month
leapcumDays = [0,31,60,91,121,152,182,213,244,274,305,335] # Cumulative Days by month for leap year
totdays = 0
if year1 == year2:
if isLeapYear(year1):
return (leapcumDays[month2-1] + day2) - (leapcumDays[month1-1] + day1)
else:
return (cumDays[month2-1] + day2) - (cumDays[month1-1] + day1)
if isLeapYear(year1):
totdays = totdays + 366 - (leapcumDays[month1-1] + day1)
else:
totdays = totdays + 365 - (cumDays[month1-1] + day1)
year = year1 + 1
while year < year2:
if isLeapYear(year):
totdays = totdays + 366
else:
totdays = totdays + 365
year = year + 1
if isLeapYear(year2):
totdays = totdays + (leapcumDays[month2-1] + day2)
else:
totdays = totdays + (cumDays[month2-1] + day2)
return totdays
Here's my pseudo code version using your functions for - is_leap_year, days_between. As a commenter noted, these are tricky functions to write correctly.
int leap_year_days_between(Date d1, Date d2) {
if (d1.year == d2.year) {
if (is_leap_year(d1.year) { return days_between(d1,d2); }
else { return 0; }
}
else {
Date last_day_in_year(12, 31, d1.year);
int count=0;
Date tmp = d1;
while (tmp.year < d2.year) {
if ( is_leap_year(tmp.year) ) {
count += days_between(tmp,last_day_in_year);
}
tmp = (1, 1, tmp.year+1);
}
if ( is_leap_year(d2.year) ) {
count += days_between(tmp, d2);
}
}
}
A naive approach would be:
Check your start year. If it's a leap year, count the number of days from your current day to December 31 (inclusive). If not, until your starting year equals your ending year, increment the year by 1. Then, check the year. If it is a leap year, start counting days, if not increment the year. Once the current year and ending year are the same, then check to see if the current (== ending) year is a leap year. If it is, count days in months from January to the ending month, otherwise break the algorithm. Once your current month is your ending month, count your days.

Resources