fukanchik (fukanchik) wrote,
fukanchik
fukanchik

Вчера была интересная дата

Здесь обратили внимание на очень интересный момент с датами.

  cookie.Expires = new DateTime(DateTime.Today.Year+1,
    DateTime.Today.Month,
    DateTime.Today.Day);

Синтаксически здесь всё правильно. Но есть ошибка. Она не зависит от языка программирования, вернее зависит не очевидным образом. Где же она?

Проблема в том, что в високосный год есть 29 февраля. Теперь возьмём год+1 - есть ли там 29 февраля? Что должен сделать конструктор DateTime в данном случае?

Оказалось, в библиотеках разных языков сделано по-разному.

  • Приведённый выше пример сделан в .net. Там бросается исключение.
  • Ruby:
      test=Time.mktime(today.year+1, today.month, today.day)
      => Sun Mar 01 00:00:00 +0300 2009
    
  • Java:
      Date now = new Date();
      Date y=new Date(now.getYear()+1, now.getMonth(), now.getDate());
      =>Sun Mar 01 00:00:00 MSK 2009
    
  • Ещё Java:
      Calendar c = Calendar.getInstance();
      c.set(c.get(Calendar.YEAR)+1, c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
      =>2009 2 1
    
  • Си:
      struct tm*tm;
      time_t now=time(NULL);
      time_t t;
    
      tm=localtime(&now);
      tm->tm_year++;
      t=mktime(tm);
      tm=localtime(&t);
      printf("%d %d %d\n", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
      =>  2009 3 1
    
  • Python:
      now=datetime.date.today()
      d=datetime.date(now.year+1, now.month, now.day)
      => ValueError: day is out of range for month
    
  • Javascript:
      var now=new Date();
      var v = new Date(now.getFullYear()+1, now.getMonth(), now.getDate());
      alert(v.getFullYear()+" "+v.getMonth()+" "+v.getDate());
      => 2009 2 1
    

Т.е. есть библиотеки, в которых мы получаем первое марта, а есть такие, которые бросают исключение. Наверняка есть такие, которые молча ставят 29 февраля.

Я думаю, что возвращать 1 марта неправильно:

  assert a.Year==DateTime.Today.Year
  assert a.Month==DateTime.Today.Month
  assert a.Day==DateTime.Today.Day

Обычно, программист ожидает что он либо получит именно то, что попросил, либо ошибку. В данном случае он получает неожиданное значение номера месяца и дня.

Т.е. эта ошибка примерно из той же серии что и наследование квадрата от прямоугольника.

Ещё.
  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

  • 0 comments