“2008-03-30”.to_date.to_time.tomorrow == “2008-03-30”

I wrote a very nice routine which would iterate over a few days.
Today I found my loop never ending !?! And this is very scary because the routine is a background process that needs to iterate over the last x-days.

But there's a problem when you're living in The Netherlands and you have to use daylight savings.

Try this code:


>> "2008-03-30".to_date.to_time.tomorrow.to_date
=> Sun Mar 30

WTF !! 2008-03-30 => Tomorrow => 30 March 2008 ?!?

I indeed complained, that time was passing so quickly. But I didn't mean to keep it stuck at 30 March!
Oh.. I'ts only my Rails Application...

How's this possible?

>> "2008-03-30".to_date.to_time.tomorrow
=> Sun Mar 30 23:00:00 +0200 2008

At 30-03-2008 the clock has been set back for daylight savings. Well I assume rails simply adds 24 hours with the method tomorrow. And yesterday we had 25 hours.

More info about this bug: http://dev.rubyonrails.org/ticket/2353

My temporary solution is to add some hours to tomorrow.


>> tomorrow_time = "2008-03-30".to_date.to_time.tomorrow + 12*60*60
=> Mon Mar 31 11:00:00 +0200 2008
>> tomorrow_time.to_date
=> Mon, 31 Mar 2008

Sometimes I hate Ruby on Rails!

why don't we collectively protest agianst the oppression of daylight saving time?
Well Tijn, I agree!

FreeBSD, (SuSE) Linux date differences

I wanted to retrieve yesterdays date with a format of YYYYMM
This was solved in FreeBSD like this:

date -v-1d  "+%Y%m"

(SuSE) Linux doesn't know the -v option
The same thing in Linux could be done like this:

date -d yesterday "+%Y%m"

Why the difference?

Default Date Format Horrors in Rails

How nice of rails to make it easy to change the default date format that is used when
showing a date from the database.

ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!(
:default => "%d-%m-%Y"
)

Very easy. Simple writing:

model.date.to_s

outputs the date in my format.

All seems to work well, but a few days later. TODAY!! I found out my application wasn't saving dates anymore.

The cause:

Rails uses the ":default" date definition to format the date when it builds an SQL statement. Well my MySQL version doesn't seem to understand this date format.

For now I stay away from the :default date formatter.
I've changed my custom date_picker field so now it first formats the date with the date format before showing..

Btw. I found a possible solution and a remark that this has been solved for future rails version. You can find this info at, the rails date kit.

Adding Ansi/Integer Date Support to Javascript

A very common way to store and work with dates is the usages of Integers as dates. In the integer the date is stored as YYYYMMDD. Converting from an between the different date formats is not nice if you are using normal functions. Also the Dutch date end user date format is "dd/mm/YYYY"

Well javascript prototypes to the rescue!
Inspired by the "Prototype Library" and Ruby ( on Rails ), I've managed to add nicer conversion support between different types.

Some examples of usages

20070212.to_date().to_s()  // Results in  12-02-2006
"24-02-2006".to_date()  // Results in a normal date object

var d = Date.create( 20060102 )   // Creates a Date object with the given
d.add( { months: 5, days: 2 } ).to_s() // Results in 04-06-2006

// add custom formatters with
Date.FORMATS[ 'period' ]  = function(d) {  return d.getFullYear() + "-" + d.getMonth(); }
( new Date() ).to_s( "period" )     // Results in  2007-08

var date1 = Date.create( 20070101 )
date1.diff( Date.now(), 'months')    // 8
... etc ...

Adding extra methods to the Date, String and Number objects can be done like this:

// for example the "to_s" method
Date.prototype.to_s = function( format ) {
if( !format ) format = 'default'
if( !Date.FORMATS[ format ] ) throw "Date format niet gevonden!";
return Date.FORMATS[ format ]( this );
}

// method for converting a number to a date
Number.prototype.to_date = function() {
var v = this.valueOf();
if( v == 0 ) return null;
return Date.new( v );
}

Some problems and frustrations I've encountered:

  • Stupid IE, doesn't allow to define setter en getter properties. The ECMA standard defines the following method for defining setters. The code below works in Mozilla Firefox. You can get the 'integer' date by using ( new Date() ).ansidate
    Date.prototype.ansidate getter function() { return this.getFullYear() * 10000 + (this.getMonth()+1) * 100 + this.getDate() } ;
    

    Firefox also supports the following legacy method for defining getters. This support has been there for quite a long time.

    Date.prototype.__defineGetter__( "ansidate", function() { return this.getFullYear() * 10000 + (this.getMonth()+1) * 100 + this.getDate() } )
    
  • null isn't an object so I cannot define a "to_date()" method for this object.

On request I will send you the code of the Date library. Maybe I will release it, but I needs a LOT of refinement!