2

Quiz duration is specified as days, hours and minutes each in integers.

I am trying to convert combination of these to seconds. Below code I tried. but it always returns 0 seconds. I am using jdk 6

Integer hours = 3, days=4, minutes=20;
javax.xml.datatype.Duration duration = DatatypeFactory.newInstance().newDuration(true, 0, 0, 
                    days, 
                    hours, 
                    minutes, 
                    0);  
Integer seconds = duration.getSeconds(); // It always returns zero

Please guide.

stack_user60
  • 35
  • 1
  • 6
  • 2
    Is the `Duration` a `java.time.Duration`? Looks like there are no seconds to be returned, what does `duration.getMinutes()` return? Is it `20`? – deHaar Nov 26 '19 at 10:46
  • Duration is javax.xml.datatype.Duration and yes it returns 20 as minutes. basically i want to convert combination of these to seconds – stack_user60 Nov 26 '19 at 10:50
  • The java.xml datatypes are somewhat antiquated, `Duration` at least. I think you will be happier working with the `java.time.Duration` class that @deHaar mentioned instead. – Ole V.V. Nov 26 '19 at 11:09
  • 1
    getSeconds() return whatever you pass as seconds in the constructor, so here you pass 0, so it returns 0 – Bentaye Nov 26 '19 at 11:21

5 Answers5

2

As far as I can see your code you are trying to use

javax.xml.datatype.Duration

which will I believe only return the specified duration in the seconds. If you want to get the number of seconds in a time provided duration, you need to use

java.time.Duration

There is a parse method available that allows you to parse a CharSequence and get a proper instance of java.time.Duration which can be done as shown below

String toParse = "P"+days+"DT"+hours+"H"+minutes+"M";
Duration secondsDuration = Duration.parse(toParse);
System.out.println(secondsDuration.getSeconds());

This is a sample code you can read further documentation for the given method an different methods available for java.time.Duration.

DevX
  • 308
  • 5
  • 16
1

The JavaDocs for javax.xml.datatype.Duration.getSeconds() say

Obtains the value of the SECONDS field as an integer value, or 0 if not present. This method works just like getYears() except that this method works on the SECONDS field.

If you want to calculate the total amount of seconds this duration is representing, you will have to calculate them yourself, maybe like this (there may be better solutions):

private static int getInSeconds(javax.xml.datatype.Duration duration) {
    int totalSeconds = 0;
    totalSeconds += duration.getSeconds();
    totalSeconds += (duration.getMinutes() * 60);
    totalSeconds += (duration.getHours() * 60 * 60);
    totalSeconds += (duration.getDays() * 24 * 60 * 60);
    // ... calculate values for other fields here, too
    return totalSeconds;
}

For certain durations, an int will not be sufficient, keep that in mind, please.

Consider using java.time.Duration instead, if possible.

There is a backport of java.time for Java 6 and 7, but unfortunately, not for below.

deHaar
  • 17,687
  • 10
  • 38
  • 51
1

java.time and ThreeTen Backport

I think you will be happier with org.threeten.bp.Duration from the backport of java.time to Java 6 and 7. java.time is the modern Java date and time API originally introduced in Java 8.

    int days = 4;
    int hours = 3;
    int minutes = 20;

    Duration duration = Duration.ofDays(days).plusHours(hours).plusMinutes(minutes);
    long totalSeconds = duration.getSeconds();

Link: ThreeTen Backport

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

Basically, your duration is hours = 3, days=4, minutes=20 and Seconds=0. that's why when you are trying to retrieve seconds you are getting 0. If you want convert your whole duration to seconds then add days*24*60*60 + hours*60*60 + minutes*60 + seconds.

Java 8 has much better support to Duration. Please go through https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html

0

The answers by deHaar, DevX and Ole V.V. are correct and guide you in the right direction.

If you want to stick to javax.xml.datatype.Duration, there is an easy way, purely using the OOTB (Out-Of-The-Box) API, to achieve what you want to. It is as simple as passing a java.util.Calendar instance to javax.xml.datatype.Duration#getTimeInMillis and converting the returned value to seconds by using TimeUnit.MILLISECONDS.toSeconds.

Demo:

import java.util.Calendar;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;

public class Main {
    public static void main(String[] args) throws DatatypeConfigurationException {
        Integer hours = 3, days = 4, minutes = 20;
        javax.xml.datatype.Duration duration = DatatypeFactory.newInstance().newDuration(true, 0, 0, 
                            days, 
                            hours,
                            minutes, 
                            0);

        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
        long seconds = TimeUnit.MILLISECONDS.toSeconds(duration.getTimeInMillis(calendar));
        System.out.println(seconds);
    }
}

Output:

357600
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • Corner case: `duration.getTimeInMillis(calendar)` takes summer time transitions in the calendar into account. When using a `Calendar` of March 26, 2021 in my time zone (Europe/Copenhagen), I get only `354000` because March 28 is only 23 hours long. If you want a day to be 24 hours always, one way to ensure it is to use a `Calendar` in UTC, for example `GregorianCalendar.from(ZonedDateTime.now(ZoneOffset.UTC))`. – Ole V.V. Dec 31 '20 at 10:45
  • 1
    @OleV.V. - Thanks again for yet another valuable suggestion. Since the OP wants to stick to Java-6 without using any backporting API, I've added the timezone as `calendar.setTimeZone(TimeZone.getTimeZone("GMT"))`. I've also tested it for the date you have mentioned and it works as expected. – Arvind Kumar Avinash Dec 31 '20 at 11:49