Retrieving All Weekend (Saturday and Sunday) Dates for the whole year

3 views
Skip to first unread message

caritos

unread,
Aug 9, 2007, 3:49:13 PM8/9/07
to Philippine Ruby Users Group (PRUG/PhRUG)
I'm trying to create a simple elegant method that retrieves all the
weekend dates in a year.

// get current date
current_date = Date.today

//get what day of the week it is. 0 is Sunday and 6 is Saturday
what_weekday_it_is = current_date.wday

// figure out when the next Saturday and Sunday is
// added 7 to these two dates and do it 52 times.
// put these values into an array.

Is there a better way?

Peña, Botp

unread,
Aug 9, 2007, 9:31:56 PM8/9/07
to Philippine Ruby Users Group (PRUG/PhRUG)
From: caritos [mailto:ecar...@gmail.com]
# I'm trying to create a simple elegant method that retrieves all the
# weekend dates in a year.
# // get current date
# current_date = Date.today
# //get what day of the week it is. 0 is Sunday and 6 is Saturday
# what_weekday_it_is = current_date.wday
# // figure out when the next Saturday and Sunday is
# // added 7 to these two dates and do it 52 times.
# // put these values into an array.

car, puwedeng puwede yung technique mo.
eto akin style. i define weekend days, bale you can define your own weekends. malay mo wednesday weekend na rin, err should that be weekmid :) With that i loop fr beginning to end of the year (for any given year). You only do this once naman for any year (and besides it wont take a second to generate :)

sample,

C:\family\ruby>cat test2.rb
require 'we.rb'

def pwend yr=Date.today.year
wey = weekends_year(yr)
print wey.first.year
mon =9999
wey.each do |d|
if d.mon != mon
mon = d.mon
print "\n#{"%2d"%mon}:"
end
print "#{"%3d"%d.day}"
end
puts
end


pwend
pwend 2008

C:\family\ruby>ruby test2.rb
2007
1: 6 7 13 14 20 21 27 28
2: 3 4 10 11 17 18 24 25
3: 3 4 10 11 17 18 24 25 31
4: 1 7 8 14 15 21 22 28 29
5: 5 6 12 13 19 20 26 27
6: 2 3 9 10 16 17 23 24 30
7: 1 7 8 14 15 21 22 28 29
8: 4 5 11 12 18 19 25 26
9: 1 2 8 9 15 16 22 23 29 30
10: 6 7 13 14 20 21 27 28
11: 3 4 10 11 17 18 24 25
12: 1 2 8 9 15 16 22 23 29 30
2008
1: 5 6 12 13 19 20 26 27
2: 2 3 9 10 16 17 23 24
3: 1 2 8 9 15 16 22 23 29 30
4: 5 6 12 13 19 20 26 27
5: 3 4 10 11 17 18 24 25 31
6: 1 7 8 14 15 21 22 28 29
7: 5 6 12 13 19 20 26 27
8: 2 3 9 10 16 17 23 24 30 31
9: 6 7 13 14 20 21 27 28
10: 4 5 11 12 18 19 25 26
11: 1 2 8 9 15 16 22 23 29 30
12: 6 7 13 14 20 21 27 28

C:\family\ruby>cat we.rb
require 'date'
WEEKENDS = [0,6] # 0 Sunday, 6 Saturday
FIRSTDAY = 1
FIRSTMON = 1

def weekends_year yr=Date.today.year
d = Date.civil(yr,FIRSTMON,FIRSTDAY)
wends = []
while d.year == yr
wends << d if WEEKENDS.include? d.wday
d += 1
end
wends
end


if __FILE__ == $0
require 'test/unit'
class Test_wends_year < Test::Unit::TestCase
def test_all_weekends
weekends_year.each do |d|
assert WEEKENDS.include?(d.wday)
end
end
def test_some
assert weekends_year.size > 96 # singit :)
assert WEEKENDS.include?(weekends_year.first.wday)
assert WEEKENDS.include?(weekends_year[1].wday)
assert WEEKENDS.include?(weekends_year[2].wday)
assert WEEKENDS.include?(weekends_year[20].wday)
assert WEEKENDS.include?(weekends_year[33].wday)
assert WEEKENDS.include?(weekends_year.last.wday)
end
end
end


C:\family\ruby>ruby we.rb
Loaded suite we
Started
..
Finished in 1.641 seconds.

2 tests, 111 assertions, 0 failures, 0 errors

C:\family\ruby>

paki test lang, car. na test ko pero sa akin lang.

salamat -botp


cryptonomikon

unread,
Aug 13, 2007, 5:37:36 AM8/13/07
to Philippine Ruby Users Group (PRUG/PhRUG)
ayos. how about leap years? :)


On Aug 10, 9:31 am, Peña, Botp <b...@delmonte-phil.com> wrote:
> From: caritos [mailto:ecari...@gmail.com]

Peña, Botp

unread,
Aug 13, 2007, 9:02:24 PM8/13/07
to Philippine Ruby Users Group (PRUG/PhRUG)
From: cryptonomikon [mailto:ruben...@gmail.com]
# ayos. how about leap years? :)

no problemo :) the method just simply list all dates that fall on a saturday or sunday of any year (regardless whether that year is a leap or not). Eg, let us revise our test program so that it prints leap beside the year if it is a leap year, then test it for the years 1900, 2000, 2007, 2008, 2100.


C:\family\ruby\date>cat test2.rb
require 'we.rb'

def pwend yr=Date.today.year
wey = weekends_year(yr)

print "#{yr} #{"(leap)" if wey.first.leap?}"


mon =9999
wey.each do |d|
if d.mon != mon
mon = d.mon
print "\n#{"%2d"%mon}:"
end
print "#{"%3d"%d.day}"
end
puts
end

pwend 1900
pwend 2000
pwend
pwend 2008
pwend 2100


C:\family\ruby\date>ruby test2.rb
1900


1: 6 7 13 14 20 21 27 28
2: 3 4 10 11 17 18 24 25
3: 3 4 10 11 17 18 24 25 31
4: 1 7 8 14 15 21 22 28 29
5: 5 6 12 13 19 20 26 27
6: 2 3 9 10 16 17 23 24 30
7: 1 7 8 14 15 21 22 28 29
8: 4 5 11 12 18 19 25 26
9: 1 2 8 9 15 16 22 23 29 30
10: 6 7 13 14 20 21 27 28
11: 3 4 10 11 17 18 24 25
12: 1 2 8 9 15 16 22 23 29 30

2000 (leap)
1: 1 2 8 9 15 16 22 23 29 30
2: 5 6 12 13 19 20 26 27
3: 4 5 11 12 18 19 25 26
4: 1 2 8 9 15 16 22 23 29 30
5: 6 7 13 14 20 21 27 28
6: 3 4 10 11 17 18 24 25
7: 1 2 8 9 15 16 22 23 29 30
8: 5 6 12 13 19 20 26 27
9: 2 3 9 10 16 17 23 24 30
10: 1 7 8 14 15 21 22 28 29
11: 4 5 11 12 18 19 25 26
12: 2 3 9 10 16 17 23 24 30 31


2007
1: 6 7 13 14 20 21 27 28
2: 3 4 10 11 17 18 24 25
3: 3 4 10 11 17 18 24 25 31
4: 1 7 8 14 15 21 22 28 29
5: 5 6 12 13 19 20 26 27
6: 2 3 9 10 16 17 23 24 30
7: 1 7 8 14 15 21 22 28 29
8: 4 5 11 12 18 19 25 26
9: 1 2 8 9 15 16 22 23 29 30
10: 6 7 13 14 20 21 27 28
11: 3 4 10 11 17 18 24 25
12: 1 2 8 9 15 16 22 23 29 30

2008 (leap)


1: 5 6 12 13 19 20 26 27
2: 2 3 9 10 16 17 23 24
3: 1 2 8 9 15 16 22 23 29 30
4: 5 6 12 13 19 20 26 27
5: 3 4 10 11 17 18 24 25 31
6: 1 7 8 14 15 21 22 28 29
7: 5 6 12 13 19 20 26 27
8: 2 3 9 10 16 17 23 24 30 31
9: 6 7 13 14 20 21 27 28
10: 4 5 11 12 18 19 25 26
11: 1 2 8 9 15 16 22 23 29 30
12: 6 7 13 14 20 21 27 28

2100
1: 2 3 9 10 16 17 23 24 30 31
2: 6 7 13 14 20 21 27 28
3: 6 7 13 14 20 21 27 28
4: 3 4 10 11 17 18 24 25
5: 1 2 8 9 15 16 22 23 29 30
6: 5 6 12 13 19 20 26 27
7: 3 4 10 11 17 18 24 25 31
8: 1 7 8 14 15 21 22 28 29
9: 4 5 11 12 18 19 25 26
10: 2 3 9 10 16 17 23 24 30 31
11: 6 7 13 14 20 21 27 28
12: 4 5 11 12 18 19 25 26

C:\family\ruby\date>
C:\family\ruby\date>

Here we see 1900 is not a leap year, current year 2007 is not, nor is year 2100, but 2000 and 2008 are leap. Ok lang? Or do you have other concern that the method overlook?

btw, sa windows xp ko, ayaw tanggapin ng windows calendar date years below 1980 and above 2099; buti na lang may ruby :)

kind regards -botp

teem

unread,
Aug 13, 2007, 9:40:33 PM8/13/07
to cryptonomikon, Philippine Ruby Users Group (PRUG/PhRUG)
yo dudes!

given a range of years, this one returns an array of ints of years that are leap years:
(start_year..end_year).select { |p| Date::leap?(p) }

irb(main):027:0> start_year = 1980
=> 1980
irb(main):028:0> end_year = 2000
=> 2000
irb(main):029:0> v = (start_year..end_year).select { |p| Date::leap?(p) }
=> [1980, 1984, 1988, 1992, 1996, 2000]

this one returns an array of Date objects:
((start_year..end_year).select { |p| Date::leap?(p) }).collect { |c| Date.new(year=c) }

don''t have tests though. hehe

ey, just a question: since ruby is slow and it allows you to do a thing in so many ways, do you always think about the 'best' algorithm ( i.e. speed of execution or efficiency)? thanks! Pwede ba mag poll dito? hehe

cheers!
teem

Peña, Botp

unread,
Aug 13, 2007, 10:31:26 PM8/13/07
to Philippine Ruby Users Group (PRUG/PhRUG)
# print "#{yr} #{"(leap)" if wey.first.leap?}"
getting a hint fr teem, there's a class form for leap, so, that should be

print "#{yr} #{"(leap)" if Date.leap?(yr)}"

teem

unread,
Aug 13, 2007, 10:56:04 PM8/13/07
to Peña, Botp, Philippine Ruby Users Group (PRUG/PhRUG)
Ranges are very helpful in these situations, even in the first problem posted by caritos..

you can do the following:

irb(main):002:0> start_date = Date.new(year=2007, month=1, date=1)
=> #<Date: 4908203/2,0,2299161>
irb(main):003:0> start_date.to_s
=> "2007-01-01"
irb(main):004:0> end_date = Date.new(year=2007, month=12, date=31)
=> #<Date: 4908931/2,0,2299161>
irb(main):005:0> end_date.to_s
=> "2007-12-31"
irb(main):006:0> start_date..end_date
=> #<Date: 4908203/2,0,2299161>..#<Date: 4908931/2,0,2299161>

this creates a range of dates.

then, use the select method to select only the weekdays

(start_date..end_date).select { |p| [0, 6].include? p.wday }

cheers!
teem


2007/8/14, Peña, Botp <bo...@delmonte-phil.com >:

teem

unread,
Aug 13, 2007, 11:16:45 PM8/13/07
to Philippine Ruby Users Group (PRUG/PhRUG)
sorry, i meant weekends and not weekdays.

cheers!
teem

On Aug 14, 10:56 am, teem <iamt...@gmail.com> wrote:
> Ranges are very helpful in these situations, even in the first problem
> posted by caritos..
>
> you can do the following:
>
> irb(main):002:0> start_date = Date.new(year=2007, month=1, date=1)
> => #<Date: 4908203/2,0,2299161>
> irb(main):003:0> start_date.to_s
> => "2007-01-01"
> irb(main):004:0> end_date = Date.new(year=2007, month=12, date=31)
> => #<Date: 4908931/2,0,2299161>
> irb(main):005:0> end_date.to_s
> => "2007-12-31"
> irb(main):006:0> start_date..end_date
> => #<Date: 4908203/2,0,2299161>..#<Date: 4908931/2,0,2299161>
>
> this creates a range of dates.
>
> then, use the select method to select only the weekdays
>
> (start_date..end_date).select { |p| [0, 6].include? p.wday }
>
> cheers!
> teem
>

> 2007/8/14, Peña, Botp <b...@delmonte-phil.com>:

Peña, Botp

unread,
Aug 13, 2007, 11:21:33 PM8/13/07
to Philippine Ruby Users Group (PRUG/PhRUG)
From: teem [mailto:iam...@gmail.com]
# (start_date..end_date).select { |p| [0, 6].include? p.wday }

cool stuff ! that is much rubyish, imho.
thanks sa update, teem, gotta run and refactor my code again :)

kind regards -botp

Reply all
Reply to author
Forward
0 new messages