Ruby, kinda cheating - 89, less cheaty - 140
Kinda cheating, 89
f=->d{i=((d-Time.now)/86400).ceil;["Today","#{-i} days ago","#{i} days from now"][0<=>i]}
It's a function that takes the date as an argument and returns the string.
Examples:
irb(main):036:0> f[Time.new(2013, 12, 1)]
=> "7 days ago"
irb(main):037:0> f[Time.new(2013, 12, 10)]
=> "2 days from now"
irb(main):038:0> f[Time.new(2013, 12, 8)]
=> "Today"
irb(main):039:0> f[Time.new(2011, 10, 8)]
=> "792 days ago"
Hey, you never said we couldn't use only days!
express as "x days from now" or "x weeks, y days from now", or "x years, y weeks, z days from now". [emphasis mine]
Well, I choose the first one :P Abusing the rules is so fun!
Less cheaty, 140
f=->d{t=Time.new
a=((d-t)/86400).ceil
g='from now'
a,g=-a,'ago'if a<0
a==0?'Today':"#{a/365} years, #{a%365/7} weeks, #{a%365%7} days #{g}"}
Examples:
irb(main):111:0> f[Time.new 2013, 12, 10]
=> "0 years, 0 weeks, 2 days from now"
irb(main):112:0> f[Time.new 2013, 12, 17]
=> "0 years, 1 weeks, 2 days from now"
irb(main):113:0> f[Time.new 2014, 12, 17]
=> "1 years, 1 weeks, 2 days from now"
irb(main):114:0> f[Time.new 2012, 12, 17]
=> "0 years, 50 weeks, 6 days ago"
irb(main):115:0> f[Time.new 2012, 1, 1]
=> "1 years, 48 weeks, 6 days ago"
irb(main):116:0> f[Time.new 2013, 12, 8]
=> "Today"
It said
Zero units need not be mentioned.
But you never said they cannot be mentioned.