Как создать банковский календарь с 30 днями в каждом месяце

Для расчета аннуитетного кредита с немецким мне нужен календарь, где каждый месяц имеет ровно 30 дней. В каждом году 360 дней. Високосных лет нет.

Проценты всегда рассчитываются на основе 30 дней (это немецкий метод расчета процентов).

Я использую Java 8. Какие возможности у меня есть с новым API java.time для выполнения моих требований?


person Daniel    schedule 02.02.2015    source источник
comment
Поиск в Интернете 360-дневного календаря java дает много результатов, хотя и не специфичных для java.time.   -  person lbalazscs    schedule 02.02.2015
comment
Можете ли вы указать больше о том, что вам нужно. На первый взгляд, вы можете использовать первое число месяца, а затем вызвать метод plusMonths() в Joda-Time (и аналогичный в java.time). Рассматривайте кредит как массив месяцев. Двухлетний кредит — это просто массив из 24 элементов. Не обращайте внимания на даты в своих расчетах. Когда вам нужна дата для 7-го месяца, сгенерируйте ее, взяв исходную дату и вызовите addMonths(7).   -  person Basil Bourque    schedule 05.02.2015


Ответы (3)


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

Strata от OpenGamma включает реализации множества подсчетов дней, включая 30E/ 360, который может быть методом, который вам нужен.

person JodaStephen    schedule 02.02.2015

В Java-8 в принципе есть два варианта реализации любого календаря:

  • Использование интерфейсов ChronoLocalDate и Chronology в качестве отправной точки
  • Использование интерфейса Temporal

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

Первой отправной точкой может быть изучение литературы и Интернета, например очень краткой Википедии. . Также важно понимать и учитывать при проектировании, что такой 360-дневный "календарь" не является календарем в строгом смысле, поскольку он не определяет уникальное и биективное сопоставление календарной даты с юлианскими днями ( несколько одинаковых дат могут принадлежать разным реальным дням! - еще одна важная причина отказаться от использования хроно-пакета). Практическим последствием будет только определение методов преобразования/фабрики, таких как

Financial360DayCalendar f360 = Financial360DayCalendar.of(LocalDate date);

но не в обратном направлении. Помимо вопроса отображения/преобразования, расчет продолжительности в днях между двумя такими датами является основным вопросом в этом «календаре». Если вы решите оба аспекта, то ваша задача выполнена. Больше материала, вероятно, не нужно, если вам не нужно форматирование. В целях форматирования вы можете рассмотреть возможность реализации интерфейса Java-8 TemporalAccessor.

Идея (неполная):

class Financial360DayCalendar {
  private final int year;
  private final int month;
  private final int dayOfMonth;

  private Financial360DayCalendar(int year, int month, int dayOfMonth) {
    this.year = year;
    this.month = month;
    this.dayOfMonth = dayOfMonth;
  }

  public static Financial360DayCalendar of(LocalDate date) {
    int year = date.getYear();
    int month = date.getMonthValue();
    int dayOfMonth = date.getDayOfMonth();

    if (dayOfMonth == 31) {
      dayOfMonth = 30;
    }

    return new Financial360DayCalendar(year, month, dayOfMonth);
  }

  public int durationInDaysUntil(Financial360DayCalendar other) {
    // check also if other is not before this instance
    // ...
    // special algorithm (handling all intervening months as 30 days long)
    int interestDays = 30 - this.dayOfMonth(); // current day excluded
    int monthDelta = other.getMonthCount() - this.getMonthCount();
    if (monthDelta > 0) {
      monthDelta--;
    }
    interestDays += (30 * monthDelta + other.dayOfMonth);
    return interestDays;
  }

  public double getYearFraction(Financial360DayCalendar other) {
    return durationInDaysUntil(other) / 360.0;
  }

  private int getMonthCount() {
    return this.year * 12 + this.month;
  }
}

Так что это скорее метод начисления процентов, а не настоящая календарная система. Вы также можете посетить этот веб-сайт (на немецком языке), чтобы узнать подробности. как рассчитать продолжительность.

person Meno Hochschild    schedule 02.02.2015

Вы должны использовать стандартный календарь, нет необходимости делать собственный. Если вам нужно рассчитать количество дней между двумя датами на основе 30-дневного месяца, используйте что-то вроде этого метода:

public int calculateDays(Date d1, Date d2) {

    int months = 0;
    int days = 0;

    months = Months.monthsBetween(new DateTime(d1), new DateTime(d2)).getMonths();

    int endOfMonth = d1.getDate() == 31 ? 31 : 30;

    if(d1.getDate() > d2.getDate()){
        days = endOfMonth - d1.getDate() + d2.getDate();
    }else{
        days = d2.getDate() - d1.getDate();
    }
    months = months * 30;
    days = months + days;

    return days;
}

Я использовал JodaTime для упрощения реализации.

person stakahop    schedule 30.12.2016