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

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

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

private Date setdaysAttendanceApprovedWithAdditionalDays(int daysAttendanceApproved2) {

    Date currentDate = new Date();
    Calendar c = Calendar.getInstance();
    c.setTime(currentDate);

    c.add(Calendar.DATE, daysAttendanceApproved2);

    Date currentDatePlusUserInput = c.getTime();
    return currentDatePlusUserInput;
}

Желаемый результат

Если пользователь вводит значение 10, то 8 мая 2020 г. плюс 10 выходными данными будет 18 мая 2020 г. в наборе NewDate.

Проблема

setNewdate setdaysAttendanceApprovedWithAdditionalDays устанавливается равным нулю

<h:form>
<p:panel id="panel" header="New User">

    <h:panelGrid columns="3" cellpadding="5">
        <p:outputLabel for="Additional Days" value="Additionaldays:" />
        <p:inputText id="additionaldays" value="#{saveMB.attendanceApprovalEntity.daysAttendanceApproved}">
        </p:inputText>
    </h:panelGrid>

    <p:commandButton value="Save" actionListener="#{saveMB.approveAttendance}" />
</p:panel>
</h:form>

saveMB.java

@ManagedBean(name = "saveMB")
@ViewScoped
public class saveMB implements Serializable {
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(saveMB.class);

private Integer daysAttendanceApproved;

public Integer getdaysAttendanceApproved() {
    return daysAttendanceApproved;
}

public void setdaysAttendanceApproved(Integer daysAttendanceApproved) {
    this.daysAttendanceApproved = daysAttendanceApproved;
}

private Date newdate;

public Date getNewdate() {
    return newdate;
}

public void setNewdate(Date newdate) {
    this.newdate = newdate;
}

private AttendanceFlow attendanceApprovalEntity;

public AttendanceFlow getattendanceApprovalEntity() {
    return attendanceApprovalEntity;
}

public void setattendanceApprovalEntity(AttendanceFlow attendanceApprovalEntity) {
    this.attendanceApprovalEntity = attendanceApprovalEntity;
}


@PostConstruct
public void init() {

    ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
    Map<String, String> params = externalContext.getRequestParameterMap();

}

private Date setdaysAttendanceApprovedWithAdditionalDays(int daysAttendanceApproved2) {

    Date currentDate = new Date();
    Calendar c = Calendar.getInstance();
    c.setTime(currentDate);

    c.add(Calendar.DATE, daysAttendanceApproved2);

    Date currentDatePlusUserInput = c.getTime();
    return currentDatePlusUserInput;
}

public void approveAttendance(AjaxBehaviorEvent event) {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    try {

        this.attendanceApprovalEntity.setNewdate(setdaysAttendanceApprovedWithAdditionalDays(this.attendanceApprovalEntity.getdaysAttendanceApproved())); 

    } catch (Exception e) {}

}
}

AttendanceFlow.java

@Entity
@Table(name = "ATTENDANCE_FLOW")
@NamedQuery(name = "AttendanceFlow.findAll", query = "SELECT h FROM AttendanceFlow h")
public class AttendanceFlow implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@SequenceGenerator(name = "ATTENDANCE_FLOW_ID_GENERATOR", sequenceName = "ATTENDANCE_FLOW_ID_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ATTENDANCE_FLOW_ID_GENERATOR")
@Column(name = "ATTENDANCE_FLOW_ID")
private Integer AttendanceFlowId;

@Column(name = "DAYS_ATTENDANCE_APPROVED")
private Integer daysAttendanceApproved;

@Column(name = "NEW_DATE")
@Temporal(TemporalType.DATE)
private Date newdate;

public Date getNewdate() {
    return newdate;
}

public void setNewdate(Date newdate) {
    this.newdate = newdate;
}    

public Integer getAttendanceFlowId() {
    return AttendanceFlowId;
}

public void setAttendanceFlowId(Integer AttendanceFlowId) {
    this.AttendanceFlowId = AttendanceFlowId;
}

public Integer getdaysAttendanceApproved() {
    return daysAttendanceApproved;
}

public void setdaysAttendanceApproved(Integer daysAttendanceApproved) {
    this.daysAttendanceApproved = daysAttendanceApproved;
}

}

Во время отладки я могу найти значение

 this.attendanceApprovalEntity.getdaysAttendanceApproved   

т.е. пользователь ввел значение что-то вроде 10, но после этого я не смог продолжить


person anveshijain    schedule 08.05.2020    source источник
comment
Это работает в юниттесте? Поместите эту логику в службу и протестируйте... не связанную с jsf   -  person Kukeltje    schedule 09.05.2020
comment
anveshijain: пожалуйста, не используйте тег [java], пока проблема не может быть продемонстрирована в простом классе приложения Java с методом main(). В противном случае вы получите совершенно бесполезные ответы от тех, кто ничего не знает о JSF.   -  person BalusC    schedule 09.05.2020


Ответы (2)


LocalDate::plusDays

Используйте LocalDate вместо устаревших Date и Calendar. Подробнее см. здесь.

Сделайте это следующим образом:

private LocalDate setDaysAttendanceApprovedWithAdditionalDays(int daysAttendanceApproved) {
    LocalDate date = LocalDate.now();
    return date.plusDays(daysAttendanceApproved);
}

Быстрая демонстрация:

import java.time.LocalDate;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(setDaysAttendanceApprovedWithAdditionalDays(10));
    }

    static LocalDate setDaysAttendanceApprovedWithAdditionalDays(int daysAttendanceApproved) {
        LocalDate date = LocalDate.now();
        return date.plusDays(daysAttendanceApproved);
    }
}

Вывод:

2020-05-18

JPA и java.time

Удалите аннотацию @Temporal из атрибута. Также обратите внимание, что если вы используете JPA 2.1 или более раннюю версию, вы необходимо написать преобразователь, как показано здесь. Если вы используете JPA 2.2 или более позднюю версию, вам не нужно любой преобразователь.

person Arvind Kumar Avinash    schedule 08.05.2020
comment
Итак, я попробовал ваше решение и в Entity @Column(name = NEW_DATE) @Temporal(TemporalType.DATE) private Date newdate; public Date getNewdate() { return newdate; } public void setNewdate(Date newdate) { this.newdate = newdate; } Мне пришлось перейти с Date на LocalDate - person anveshijain; 08.05.2020
comment
Мне пришлось перейти с Date на LocalDate @Column(name = NEW_DATE) @Temporal(TemporalType.DATE) private LocalDate newdate; public LocalDate getNewdate() { return newdate; } public void setNewdate(LocalDate localDate) { this.newdate = localDate; } - person anveshijain; 08.05.2020
comment
Но я получаю эту ошибку в классе сущностей, @Temporal следует использовать только в java.util.Date или java.util. календарь - person anveshijain; 08.05.2020
comment
@anveshijain - я обновил свой ответ, чтобы решить эту проблему. - person Arvind Kumar Avinash; 08.05.2020
comment
Я понял часть вашего решения, но я не понял, как обрабатывать атрибут LocalDate для столбца DATE. - person anveshijain; 08.05.2020
comment
@anveshijain - Просто создайте класс преобразователя, показанный в ссылке, и он будет автоматически применен к атрибутам типа LocalDate. Удалите аннотацию @Temporal из атрибута. Не стесняйтесь комментировать в случае каких-либо дальнейших сомнений/вопросов. - person Arvind Kumar Avinash; 08.05.2020

Вместо этого используйте класс GregorianCalendar. Текущую дату можно получить с помощью date=new GregorianCalendar(), а число, введенное пользователем, можно добавить с помощью date.add(Calendar.DAY_OF_MONTH,number).

person Zelig63    schedule 08.05.2020
comment
GregorianCalendar в ужасном классе с глубокими недостатками в дизайне, как и родственные классы Calendar и Date. Несколько лет назад они были вытеснены классами java.time, определенными в JSR 310. См. Ответ Авинаша для современного решения. - person Basil Bourque; 09.05.2020
comment
Однако у меня никогда не было проблем с использованием этого ужасного класса... - person Zelig63; 10.05.2020