How to calculate time diff between two time columns in a field group?

Hi,
My field group have two time fields: begintime and endtime. The data type of these two columns are date in the entity. I want to calculate the difference between them and put the result to the field “hrs”. How can I do it? Thank you.

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "BEGINTIME", nullable = false)
    protected Date begintime;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "ENDTIME", nullable = false)
    protected Date endtime;

    @Column(name = "HRS")
    protected Double hrs;
<fieldGroup id="fieldGroup"
                        datasource="ccsWoDs">
                <column width="250px">
                    <field property="wodate"/>
                    <field property="begintime"/>
                    <field property="endtime"/>
                    <field property="hrs"/>
                </column>
            </fieldGroup>

I tried TimeField,DateField,TextField and addValueChangeListener as below but all of these have problems.

    @Named("fieldGroup.begintime")
    private TimeField startTimeField;

    @Named("fieldGroup.endtime")
    private TimeField endTimeField;        

    @Override
    public void ready() {
        startTimeField.addValueChangeListener(this::updateManHours);
        endTimeField.addValueChangeListener(this::updateManHours);
    }

    private void updateManHours(ValueChangeEvent ignored) {
    long nd = 1000 * 24 * 60 * 60;
    long nh = 1000 * 60 * 60;
    
    Date begin = getItem().getBegintime();
    Date end = getItem().getEndtime();
    long diff = begin.getTime() - end.getTime();
    
    long hour = diff % nd / nh; 
}

Hi,

Could you clarify what kind of problems do you face?

Regards,
Gleb

Time Calculation
Attribute

Hi,
I want to calculate the hours between begin and end. Both begin and end are datetime attribute. Thank you.

Hi @thomaslei,

I only calculate the time difference on this :slight_smile:

https://www.cuba-platform.com/discuss/t/how-to-update-fieldgroup-property-using-a-datasource/4420/10

Hi @thomaslei,

Extract the time first from the given datetime & manipualte it.

try {
DateFormat f = new SimpleDateFormat(“MM/dd/yyyy hh:mm:ss a”);
Date d = f.parse(“8/29/2011 11:16:12 AM”);
DateFormat date = new SimpleDateFormat(“MM/dd/yyyy”);
DateFormat time = new SimpleDateFormat(“hh:mm:ss a”);
System.out.println("Date: " + date.format(d));
System.out.println("Time: " + time.format(d));
} catch (ParseException e) {
e.printStackTrace();
}

Hi,
I tried to get the start date , start time , end date and end time like below but it shows error.

IllegalArgumentException: Can not set com.haulmont.cuba.gui.components.TimeField field com.tupperware.wocompletion.web.ccswo.CcsWoEdit.endTimeField to com.haulmont.cuba.web.gui.components.WebDateField

    @Named("fieldGroup.begintime")
    private TimeField startTimeField;

    @Named("fieldGroup.endtime")
    private TimeField endTimeField;
    
    @Named("fieldGroup.begintime")
    private DateField startDateField;

    @Named("fieldGroup.endtime")
    private DateField endDateField;

There’s no DateTimeField.

I think you can use the DateField to extract the time.

image

Hi,
DateField doesn’t work since the value of it is only part of “Date”. I need “Time” part as well.

Mine is working :slight_smile:

image

Time is using long type.

Hi,
Thank you for your patience. It works for me as well.

The DateField component (see docs) is a field to display and enter date and time, i.e. there is no a separate DateTimeField.

Because the attributes of your entity are of the type Date and have the @Temporal(TemporalType.TIMESTAMP) annotation, this means that they will be displayed as date fields (with time), so you can’t inject these fields as time fields. That’s why you get an exception.

Also, It’s recommended to use a datasource’s ItemPropertyChangeListener instead of field’s ValueChangeListener:

ccsWoDs.addItemPropertyChangeListener(e -> {
    if ("begintime".equals(e.getProperty())
            || "endtime".equals(e.getProperty())) {
        updateManHours();
    }
});

Regards,
Gleb

Hi,
Could you share the complete code? I tried below but it prompts “can’t find the symbol” compile error.

public class CcsWoEdit extends AbstractEditor<CcsWo> {
    @Inject
    private Datasource<CcsWo> CcsWoDs; 
    
    @Override
    public void init(Map<String, Object> params) {
        CcsWoDs.addItemPropertyChangeListener(e -> {
        if ("begintime".equals(e.getProperty())
            || "endtime".equals(e.getProperty())) {
            updateManHours();
        }
    });
    }
    
    private void updateManHours() {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        Date begin = null;
        Date end = null;
    
        if(startTimeField.getValue() != null)
        {
            begin = startTimeField.getValue();
        
        }
        
        if(endTimeField.getValue() != null)
           end = endTimeField.getValue();
    
        if(begin == null || end == null)
            return;
        else
        {
            long diff = end.getTime()  - begin.getTime();
            if (diff <=0)
            {
                showNotification("结束时间必须大于开始时间", NotificationType.HUMANIZED);
                double hours = 0;
                this.getItem().setHrs(hours);
            }
            else
            {
                double hours = ((double)diff / 10000) / 360;
                showNotification("diff:"+String.valueOf(diff)+"Hours:"+String.valueOf(hours), NotificationType.HUMANIZED);
                this.getItem().setHrs(hours);
            }
        }
    }

I suppose that the error has appeared because you removed date field injections. I will be able to say more if you either attach a sample project or an error log.

It shows the error “can’t find symbol” here.

Did you import the Datasource class?

I think I didn’t import it. Which package shall I import? I can’t find the package info. from the documentation.

The full refference is com.haulmont.cuba.gui.data.Datasource.

Thank you. I solved the issue.

You don’t need to add two ItemPropertyChangeListener, just make all check in a single one.

Hi @gorelov,

What does e.getProperty() means?