:: Главная :: Решения :: Статьи :: Проект "Русский help" :: Файловый архив :: Фотоальбом :: Ссылки ::
   Л и с о в о д ы   в с е х   с т р а н,  о б ъ е д и н я й т е с ь !!!  


Форумы  :: FAQ FoxPro

Как получить разницу двух дат в формате: лет, месяцев, дней
Дата: 25.02.08 17:32:06 ОтветитьЦитировать

Вопрос

Как получить разницу двух дат в формате: лет, месяцев, дней

Ответ

В общем случае, данный вопрос не имеет решения.

Пожалуйста, не надо сразу бросаться писать опровержения, что вот у меня есть готовый код, который это делает или вот есть ссылка на решение. Сначала дочитайте до конца, что именно подразумевается в данном случае под фразой "решения не имеет".

Проблема заключается в том, что нет однозначного определения того, что есть "месяц" и "год". Как правило, под этим подразумевают календарные месяцы. Но сложность в том, что календарный месяц - это понятие не абсолютное, а относительное. Календарный месяц - это не просто некоторое количество дней. Это количество дней, прошедших с определенной даты.

Для лучшего понимания проблемы рассмотрим простой пример.

Надо определить разницу дат между 30 января и 2 апреля одного 2008 года.

Если бы задача заключалась в определении количества дней, то все решалось бы простым вычитанием

?{^2008-04-02} - {^2008-01-30} && 63 дня

А как определить количество месяцев? Результат будет существенно зависеть от того, как именно будет определяться один месяц. Возможно несколько идеологий расчета:

Вариант 1

Прибавляем к начальной дате последовательно по одному месяцу до тех пор, пока результат не превысит конечной даты.

Под термином "месяц" в процессе прибавления подразумевается такая операция, в результате которой номер дня остается тот же самый, а номер месяца увеличивается на 1. Если у нового месяца нет такой даты, то устанавливается дата равная последнему дню нового месяца. Так работает функция GoMonth()

Это значит, что если прибавить один месяц к 30 января, то получим 29 февраля (2008 год - високосный), поскольку в феврале нет 30 числа.

Затем прибавляем к 29 февраля еще один месяц, получаем 29 марта. Прибавлять еще один месяц уже не надо, поскольку результат будет заведомо больше 2 апреля.

Между 29 марта и 2 апреля остается 4 дня. Значит, результат будет 2 месяца и 4 дня.

Заметьте, что в не високосном году результат был бы 2 месяца и 5 дней

Обратите внимание на тот факт, что если начальная дата равна 29, 30 или 31 января результат был бы один и тот же! Поскольку прибавление одного месяца давало бы все то же 29 февраля. Получается парадоксальная ситуация - количество дней разное, а результат одинаковый.


Вариант 2

Алгоритм похож на "Вариант 1", но прибавлять будем не по одному месяцу за раз, а сразу прибавим столько месяцев, чтобы оказаться как можно ближе к конечной дате. Т.е. прибавим к 30 января сразу 2 месяца и получим 30 марта.

Между 30 марта и 2 апреля остается 3 дня. Значит, результат будет 2 месяца и 3 дня.

Заметьте, что если бы конечным месяцем был бы не апрель, а март, то данный вариант расчета ничем не отличался бы от "Варианта 1".


Вариант 3

Под термином "месяц" будем понимать именно календарный месяц. Т.е. февраль - это интервал от 01 февраля до 29 февраля, март - это интервал от 01 марта до 31 марта.

В этом случае имеем 2 полных месяца - февраль и март. И "остатки" от граничных месяцев: 1 день до конца января и 2 дня апреля. Значит, результат будет 2 месяца и 3 дня.

Но в данном случае повезло. Оставшихся дней явно не хватает для полного месяца. А если бы оставшихся дней было бы, например, 40 (с 10 января по 20 апреля)? Встал бы вопрос, сколько дней надо выделить из этого количества дней, чтобы получить еще 1 месяц? Берем количество дней в январе (месяце начала периода) или в апреле (месяце конца периода)?


Вариант 4

Принимаем, что все месяцы имеют одинаковое количество дней, которое вычисляется по следующей формуле:

(365+365+365+366)/4/12 = 30.4375

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


Могут быть и другие варианты расчета.


Как видите, результат существенно зависит от того, что именно понимается под термином "месяц". Точнее, как именно этот самый месяц выделяется в заданном диапазоне. Причем, даже нельзя сказать, что один способ является "правильным", а другие "не правильные". Они все "правильные". Но в рамках определенной идеологии.

Другими словами, вопрос расчета интервала в формате "лет, месяцев, дней" заключается не столько в коде, сколько в идеологии (алгоритме) расчета. Как только будет принята определенная идеология расчета, запрограммировать ее не составит труда.

Выбор того или иного способа определения месяца, как правило, определяется той задачей, которую необходимо решить. Просто поздравить именинника (можно и несколько дней подряд - не страшно ), определить трудовой стаж или статистика в родильном отделении.

Следует еще заметить, что те же проблемы касаются и определения любых других календарных интервалов. Таких как "неделя", "квартал", "год". Т.е. прежде чем писать код, необходимо описать по каким правилам будут определяться указанные интервалы.

Вы можете поискать уже готовые примеры расчета на данном сайте или в интернете. Но всегда следует иметь в виду, что все эти примеры кодируют определенную идеологию определения месяца и года. К сожалению, как именно (по какой идеологии) происходит это определение из кода далеко не всегда видно. Поэтому, результат работы найденных примеров может оказаться далек от ожидаемых Вами. Каждый пример следует тщательно протестировать для определения его пригодности под Вашу конкретную задачу.



Исправлено: Владимир Максимов, 08.03.08 13:04
Ratings: 0 negative/2 positive


Тема Просмотров Написано Написано
  Program 4994 Владимир Максимов 01.03.05 21:02
  Как определить директорию, из которой запущена программа 8574 Владимир Максимов 22.03.05 09:41
  Как проверить факт существования переменной памяти, поля таблицы, метода формы 11271 Владимир Максимов 20.04.05 17:31
  Как работать с ini-файлами 14096 Владимир Максимов 01.05.05 11:17
  Символьные поля, переменные памяти и константы 8182 Владимир Максимов 25.09.05 12:31
  Как работать с путями доступа и именами файлов, содержащих пробелы 6108 Владимир Максимов 22.02.06 21:00
  Как вывести приложение на передний план 15839 Владимир Максимов 04.03.07 13:17
  Как получить разницу двух дат в формате: лет, месяцев, дней 9060 Владимир Максимов 25.02.08 17:32


Извините, но у вас нет прав для того, чтобы писать в этом форуме.

On-line: 43 andrewk sphinx  and Guests: 41


© 2006 Fox Club 
Яндекс.Метрика