Next Friday the 13th

Windows PowerShell, 74

for($d="date $args"|iex;($d+='1').day*$d.dayofweek-65){}'{0:yyy-MM-d}'-f$d

Fairly straightforward. One perhaps confusing bit is the use of "Get-Date $args" | Invoke-Expression to get either the current date (if $args is empty) or the date specified in $args without raising an error.

72-byte variant:

for($d="date $args"|iex;($d+=9).day*$d.dayofweek-65){}'{0:yyy-MM-d}'-f$d

Takes ages, though ... this doesn't increment the datetime by a whole day each iteration but instead only 900 nanoseconds. But two bytes shorter.

67-byte variant:

for($d="date $args"|iex;($d+='1').day*$d.dayofweek-65){}'{0:d}'-f$d

This is a bit locale-sensitive; if it fails on your machine, try setting your date format to ISO-8601 beforehand. :-)

Oh, and it can be made into 65 bytes just like the 72-byte version.

History:

  • 2011-02-17 00:33 (92) First attempt.
  • 2011-02-17 00:35 (85) Improved getting an initial date.
  • 2011-02-17 00:37 (79) Compared the product instead of day and day of week individually. Admittedly stolen from Ventero.
  • 2011-02-17 00:40 (76) Pulled the first line into the for. Comparison just as subtraction instead of -eq which saves another two bytes.
  • 2011-02-17 00:53 (75) Unix date format string is a bit shorter.
  • 2011-02-17 11:42 (74) Reverted to the default date pattern but yyy-MM-d suffices (since the year is always longer than three characters and the day is always 13. Thanks to Ty Auvil for this.

Ruby, 96 75 characters

require"date"
d=Date.parse(gets||"thu")+1
d+=1 while d.wday*d.day!=65
$><<d

Takes the date from stdin. To not specify a date press ctrl-d.

Thanks very much for Ventero's help.

Ungolfed:

require "date"
# Date.parse("thu") will return this week's thursday
date = Date.parse(gets || "thu")+1
date += 1 while d.wday * d.day != 5 * 13
$stdout << date

Sample IO:

$ ruby fr13th.rb
2013-05-09
2013-09-13
$ ruby fr13th.rb
2007-06-29
2007-07-13
$ ruby fr13th.rb
2007-07-13
2008-06-13
$ ruby fr13th.rb
2011-05-13

bash, 75

until set `date +%F -d$1+day`
date -d$1|grep -q '^F.* 13'
do :
done
echo $1

This is a bit locale-sensitive; if it fails on your machine, try exporting LC_ALL=C beforehand.

$ bash fri13th.sh 2013-05-09
2013-09-13                                             
$ bash fri13th.sh 2007-06-29
2007-07-13                                             
$ bash fri13th.sh 2007-07-13
2008-06-13
$ bash fri13th.sh
2011-05-13

Tags:

Date

Code Golf