Web Hosting Talk







View Full Version : get dates between two dates


mjfroggy
10-01-2009, 03:46 PM
Hello,

I need am trying to find code or a tutorial on how I would get the date of each sunday between two specific dates and then list them to the page in Y-m-d format

anyone know how this could be dont?
thanks

tim2718281
10-01-2009, 06:50 PM
Hello,

I need am trying to find code or a tutorial on how I would get the date of each sunday between two specific dates and then list them to the page in Y-m-d format

anyone know how this could be dont?
thanks

1) Convert the two dates to number of days "fromday" and "today") since some data in the past.

2) Loop x from "fromday" to "today" in increment of 1.

3) For each value of x, find out what day of the week it is

4) If the day of a week is a SUnday, convert x to Y-m-d format and list it.

Adam-AEC
10-01-2009, 08:49 PM
You didn't specify a language, so I did it in PHP.


<?php
// Define a constant of 1 day in seconds
define(ONE_DAY, 86400);
date_default_timezone_set('America/New_York');

// Accepts two timestamps, start and end
// Returns an array of timestamps that fall on a sunday
function sundays_in_range($start, $end) {
$days_until_sunday = date('w', $start) > 0 ? 7 - date('w', $start) : 0;
$date = $start + (ONE_DAY * $days_until_sunday);
$sundays = array();
while ($date <= $end) {
array_push($sundays, $date);
$date += (7 * ONE_DAY);
}
return $sundays;
}

// Calculate some example dates. Today, and 30 days from now
$start = time();
$end = time() + (30 * ONE_DAY);

// Single-dimension array of timestamps
print_r(sundays_in_range($start, $end));

// Loop and output Y-m-d
foreach (sundays_in_range($start, $end) as $sunday) print date("Y-m-d", $sunday) . "\n";
?>


1) Convert the two dates to number of days "fromday" and "today") since some data in the past.

2) Loop x from "fromday" to "today" in increment of 1.

3) For each value of x, find out what day of the week it is

4) If the day of a week is a SUnday, convert x to Y-m-d format and list it.
Good pseudo-code. The one thing I did differently was find the first Sunday, and then just keep adding a week to the date. I figured it was quicker this way and made the loop smaller.

mwatkins
10-01-2009, 11:40 PM
Oops, I forgot Sunday is day 6 (0 == Monday), therefore:

# python example
import datetime

def get_sundays(start, finish):
def gen_dates(start, duration):
for n in range(duration.days):
yield start + datetime.timedelta(days=n)

duration = finish - start
return [d for d in gen_dates(start, duration) if d.weekday() == 6]

Calling it returns a list of date objects:

print(get_sundays(datetime.date(2009,9,30), datetime.date(2009,10,31)))
[datetime.date(2009, 10, 4), datetime.date(2009, 10, 11), datetime.date(2009, 10, 18), datetime.date(2009, 10, 25)]

mjfroggy
10-02-2009, 10:30 AM
Hello,

Sorry I should of said in PHP. So I am using Adam-AEC's code
and changed it a bit as I want to be able to get a date format which would ultimatly be pulled from a database in YYYY-m-d format

so here is my code

//lets get each sunday within the vacation quarter
// $start has a value of 2010-01-01
// $end has a value of 2010-03-31
//the reason they are pulled from the databse is because the
//start and end dates will be different for each quarter
// Define a constant of 1 day in seconds
define(ONE_DAY, 86400);
date_default_timezone_set('America/New_York');

// Accepts two timestamps, start and end
// Returns an array of timestamps that fall on a sunday
function sundays_in_range($start, $end) {
$days_until_sunday = date('w', $start) > 0 ? 7 - date('w', $start) : 0;
$date = $start + (ONE_DAY * $days_until_sunday);
$sundays = array();
while ($date <= $end) {
array_push($sundays, $date);
$date += (7 * ONE_DAY);
}
return $sundays;
}

// Calculate some example dates. Today, and 30 days from now
$start = time($start);
$end = time($end) + (30 * ONE_DAY);

// Loop and output Y-m-d
foreach (sundays_in_range($start, $end) as $sunday) print "<option>".date("Y-m-d", $sunday)."</option>";


the above gives me a print out like so
2009-10-04
2009-10-11
2009-10-18
2009-10-25
2009-11-01

so the value inside the time() is being ignored??
thanks all

Adam-AEC
10-02-2009, 10:59 AM
the above gives me a print out like so
2009-10-04
2009-10-11
2009-10-18
2009-10-25
2009-11-01

so the value inside the time() is being ignored??
thanks all

You set $start and $end to a date, but it was commented out?

We can use strtotime() to parse a string and generate a timestamp. This change is untested since I'm not in front of a machine with PHP.


<?php
// Define a constant of 1 day in seconds
define(ONE_DAY, 86400);
date_default_timezone_set('America/New_York');

// Accepts two timestamps, start and end
// Returns an array of timestamps that fall on a sunday
function sundays_in_range($start, $end) {
$days_until_sunday = date('w', $start) > 0 ? 7 - date('w', $start) : 0;
$date = $start + (ONE_DAY * $days_until_sunday);
$sundays = array();
while ($date <= $end) {
array_push($sundays, $date);
$date += (7 * ONE_DAY);
}
return $sundays;
}

$start = strtotime('2010-01-01');
$end = strtotime('2010-03-31');

// Loop and output Y-m-d
foreach (sundays_in_range($start, $end) as $sunday) print date("Y-m-d", $sunday) . "\n";
?>

mattle
10-02-2009, 11:49 AM
$days_until_sunday = date('w', $start) > 0 ? 7 - date('w', $start) : 0;


Just 'cause I'm looking for an excuse to use the modulus operator today: :)


$days_until_sunday = (7 - date('w', $start)) % 7;

mjfroggy
10-02-2009, 12:39 PM
thank you mattle that worked

Adam-AEC
10-02-2009, 01:19 PM
Just 'cause I'm looking for an excuse to use the modulus operator today: :)


$days_until_sunday = (7 - date('w', $start)) % 7;


Nice approach!

mwatkins
10-05-2009, 12:14 PM
Generalizing this a little further:

#python, but not hard to translate
from datetime import date, timedelta

ONE_WEEK = timedelta(days=7)

def days_until_next(day, from_date):
return (day - from_date.weekday()) % 7

def get_dow_from_range(day_of_week, start, finish):
"""(day_of_week:int, start:date, finish:date) -> [date,]

Returns a list of all instances of "day of week" between two dates.
Note: weekday definition 0 == Monday, 6 == Sunday
"""
dow = start + timedelta(days=days_until_next(day_of_week, start))
while dow <= finish:
yield dow
dow = dow + ONE_WEEK

Ok, lets test it out:

today = date.today()
print("%s -> %s (Today)" % (today.ctime(), today.weekday()))
print("Find all Wednesdays in next six weeks:")
for d in get_dow_from_range(2, today, today + (6 * ONE_WEEK)):
print("%s -> %s" % (d.ctime(), d.weekday()))

print("Find all Sundays in November:")
for d in get_dow_from_range(6, date(2009,11,1), date(2009,11,30)):
print("%s -> %s" % (d.ctime(), d.weekday()))

Returns:

Mon Oct 5 00:00:00 2009 -> 0 (Today)
Find all Wednesdays in next six weeks:
Wed Oct 7 00:00:00 2009 -> 2
Wed Oct 14 00:00:00 2009 -> 2
Wed Oct 21 00:00:00 2009 -> 2
Wed Oct 28 00:00:00 2009 -> 2
Wed Nov 4 00:00:00 2009 -> 2
Wed Nov 11 00:00:00 2009 -> 2
Find all Sundays in November:
Sun Nov 1 00:00:00 2009 -> 6
Sun Nov 8 00:00:00 2009 -> 6
Sun Nov 15 00:00:00 2009 -> 6
Sun Nov 22 00:00:00 2009 -> 6
Sun Nov 29 00:00:00 2009 -> 6

Adam-AEC
10-05-2009, 01:28 PM
... snip ...
def days_until_next(day, from_date):
return (day - from_date.weekday()) % 7




That function extracted nicely. A very clean implementation.