2014-09-15 2 views
1

Я использую библиотеку Joda в своем приложении для Android, чтобы рассчитать продолжительность между двумя заданными датами. Использование этого приложения для расчета возраста человека. Следующий код дает следующий результат: 23 лет 11 месяцев и 6 днейБиблиотека Joda не работает должным образом

DateTime from_readable_dateTime = new DateTime(from_date_dt); 
DateTime to_readable_dateTime = new DateTime(to_date_dt); 
Period period = new Period(from_readable_dateTime, to_readable_dateTime); 

from_date_dt в этом случае 1990/01/06 и to_date_dt является 2014/09/15. (формат даты равен yyyy/mm/dd). Как я упоминал ранее, выход этого фрагмента кода с данными входами должен составлять 24 года, 7 месяцев и 20 дней, пока я получаю 23 года 11 месяцев и 6 дней. В чем проблема? Я что-то делаю неправильно, или Джода ошибочна?

UPDATE-1

я получаю 3 числа, как год, месяц и день от 3 числа сборщиков я сделать одну строку в качестве даты (начало переменной даты называется from_date_string и дата окончания назван to_date_string), я преобразовать эти две строки на сегодняшний день переменных (from_date_dt и to_date_dt):

from_date_dt = null; 
to_date_dt = null; 
diff_dt = null; 
dateFormat = new SimpleDateFormat("yyyy/mm/dd"); 
try { 
     from_date_dt = dateFormat.parse(from_date_string); 
     to_date_dt = dateFormat.parse(to_date_string); 
    } catch (ParseException e) { 
     e.printStackTrace(); 
    } 

BTW, я работаю с персидским календарем. Поскольку я не могу использовать средство выбора даты по умолчанию, я использую подборщики чисел в качестве выбора даты.

+0

Я делаю это 24 года, 8 месяцев и 9 дней. Откуда вы ожидаете 7 месяцев и 20 дней? –

+0

Какие типы 'from_date_dt' и' to_date_dt' и как они инициализируются? –

ответ

2

Стандартный тип периода, который вы неявно используете, содержит недели. Класс Period имеет другой конструктор с 3 аргументами, где вы можете указать PeriodType.yearMonthDay() в качестве третьего аргумента.

LocalDate d1 = new LocalDate(1990, 1, 6); 
LocalDate d2 = new LocalDate(2014, 9, 15); 
Period p = new Period(d1, d2, PeriodType.yearMonthDay()); 
System.out.println(p); // output: P24Y8M9D 

Чтобы объяснить результат в мелкозернистый шагов:

[1990-01-06] + 24 years = [2014-01-06] 
[2014-01-06] + 8 months = [2014-09-06] 
[2014-09-06] + 9 days = [2014-09-15] 

Еще одна вещь, чтобы рассмотреть, не используйте DateTime если ваш вход просто обычный формат даты. Вы действительно хотите учесть влияние часовых поясов? И почему вы используете SimpleDateFormat, хотя у JodaTime есть свои собственные форматиры?

UPDATE после обновленного вопроса ОП:

Теперь вопрос стал намного яснее.

Первый Следует отметить, что если вы используете подборщики номеров, то ваш исходный ввод за год, месяц и день месяца являются целыми числами. В этом случае я обычно не использовал бы форматтера, но просто передал числа конструктору LocalDate. Этот конструктор также будет автоматически проверять ввод. Сложное преобразование, которое вы пытаетесь сделать, очень подвержено ошибкам (число до строки, затем конкатенация строки до строки даты, затем разбор его по часовой пояс по умолчанию, а затем передача java.util.Date в DateTime-ctor). Этого можно избежать.

Второй отметить и самое главное: Вы пишете, что вы используете персидский календарь. Тогда причина, по которой вы не можете использовать установщик даты по умолчанию, просто состоит в том, что этот выбор даты по умолчанию не поддерживает календарные правила персидского календаря. Является ли мое предположение правильным? И вот очень плохая новость для вас: Классы Jodas НЕ поддерживают персидский календарь, особенно LocalDate или DateTime предназначены только для стандарта ISO-8601, который основан на современном пролептическом gregorian календаре.Месячные длины, например, отличаются в gregorian calendar и в персидском календаре, поэтому требуется совершенно другая арифметика календаря, которая не поддерживается Joda-Time.

Таким образом, ваши странные результаты периода, вероятно, объясняются тем фактом, что вы пытались дать пользователю определение персидского года, месяца и дня. И тогда вы пытаетесь проанализировать этот вход снисходительно (иначе Joda-Time немедленно будет жаловаться на нечетные дневные значения, например). Но последний шаг - расчет периода - должен завершиться неудачей, поскольку он основан на ISO-8601 в правилах Joda-Time, а не в персидском календаре.

Я прав? Или я неверно истолковал ваш обновленный вопрос?

Обход сложный. Если вы действительно хотите иметь расчет периода для персидского календаря, тогда вы должны построить его с нуля. Насколько я знаю, на самом деле нет библиотеки, которая поддерживает эту функцию. Руководством для написания персидского решения может быть алгоритм, обсуждаемый в этом SO-post.

UPDATE указывает на решение:

Тем временем я реализовал персидский календарь в Time4A, смотрите также эту SO-post. Поэтому, если вы можете использовать Time4A и объединить PersianCalendar с алгоритмом многоуровневого периода, упомянутым выше, это решит вашу проблему. Time4A-v3.15-2016a явно поддерживает специальные персидские календарные единицы, которые используют разные правила, чем gregorian календарные единицы.

+0

Спасибо за ваш ответ. Если я постоянно инициализирую переменные LocalDate, вывод будет правильным, но когда я начну их с переменных from_date_dt и to_date_dt, результат будет неправильным (23 11 6) –

Смежные вопросы