使用 Duration 对象在 Java 中将天、分钟、小时转换为秒失败

Posted

技术标签:

【中文标题】使用 Duration 对象在 Java 中将天、分钟、小时转换为秒失败【英文标题】:Convert days, minutes, hours to seconds in Java Using Duration object failing 【发布时间】:2020-03-21 18:20:38 【问题描述】:

测验持续时间以整数形式指定为天、小时和分钟。

我正在尝试将这些组合转换为秒。下面的代码我试过了。但它总是返回 0 秒。我正在使用 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

请指导。

【问题讨论】:

Durationjava.time.Duration 吗?貌似没有秒返回,duration.getMinutes()返回什么?是20吗? 持续时间是 javax.xml.datatype.Duration 是的,它返回 20 分钟。基本上我想将这些组合转换为秒 java.xml 数据类型有些过时,至少Duration。我认为你会更乐意使用@deHaar 提到的java.time.Duration 类。 getSeconds() 返回你在构造函数中传递的秒数,所以这里你传递 0,所以它返回 0 【参考方案1】:

据我所知,您尝试使用的代码

javax.xml.datatype.Duration

我相信它只会在几秒钟内返回指定的持续时间。如果您想获取提供的持续时间中的秒数,您需要使用

java.time.Duration

有一个可用的parse 方法可以让您解析一个 CharSequence 并获得一个正确的 java.time.Duration 实例,如下所示

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

这是一个示例代码,您可以进一步阅读 documentation 给定的方法以及可用于 java.time.Duration 的不同方法。

【讨论】:

【参考方案2】:

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

获取 SECONDS 字段的值作为整数值,如果不存在则为 0。此方法的工作原理与 getYears() 类似,只是此方法适用于 SECONDS 字段。

如果你想计算这个持续时间所代表的总秒数,你必须自己计算它们,也许像这样(可能有更好的解决方案):

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;

对于某些持续时间,int 是不够的,请记住这一点。

如果可能,请考虑改用java.time.Duration

Java 6 和 7 有一个 backport of java.time,但不幸的是,下面没有。

【讨论】:

它工作了谢谢。我不能使用 java.time.Duration,因为我必须使用 jdk6 @stack_user60 没问题,您可以使用反向移植,查看编辑后的答案或 Ole V.V. 的答案【参考方案3】:

java.time 和 ThreeTen 反向移植

我认为你会更喜欢 org.threeten.bp.Duration 从 java.time 向后移植到 Java 6 和 7。java.time 是最初在 Java 8 中引入的现代 Java 日期和时间 API。

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

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

链接:ThreeTen Backport

【讨论】:

【参考方案4】:

基本上,您的持续时间是小时 = 3、天=4、分钟=20 和秒=0。这就是为什么当您尝试检索秒数时会得到 0。 如果您想将整个持续时间转换为秒,请添加天*24*60*60 + 小时*60*60 + 分钟*60 + 秒。

Java 8 对 Duration 的支持要好得多。请转至https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html

【讨论】:

【参考方案5】:

deHaarDevXOle V.V. 的答案是正确的,并引导您朝着正确的方向前进。

如果您想坚持使用javax.xml.datatype.Duration,有一种简单的方法,纯粹使用 OOTB(Out-Of-The-Box)API 来实现您想要的。就像将java.util.Calendar 实例传递给javax.xml.datatype.Duration#getTimeInMillis 并使用TimeUnit.MILLISECONDS.toSeconds 将返回值转换为秒一样简单。

演示:

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);
    

输出:

357600

【讨论】:

极端案例:duration.getTimeInMillis(calendar) 将日历中的夏季时间转换考虑在内。在我的时区(欧洲/哥本哈根)使用 2021 年 3 月 26 日的Calendar 时,我只得到354000,因为 3 月 28 日只有 23 小时。如果您希望一天始终是 24 小时,确保它的一种方法是在 UTC 中使用 Calendar,例如 GregorianCalendar.from(ZonedDateTime.now(ZoneOffset.UTC)) @OleV.V. - 再次感谢您的另一个宝贵建议。由于 OP 希望在不使用任何向后移植 API 的情况下坚持使用 Java-6,因此我将时区添加为 calendar.setTimeZone(TimeZone.getTimeZone("GMT"))。我还针对您提到的日期对其进行了测试,并且可以按预期工作。【参考方案6】:
import java.util.concurrent.TimeUnit;
import java.util.*;

final class TimeConverter 
    public static void main(String[] args) 

        Scanner userInput = new Scanner(System.in);

        System.out.print(" [ d = Day/s, h = Hour/s, m = Minute/s, s = Second/s, ss = Milli/s ]\n\n Mode: ");

        String selectMode = userInput.nextLine().toLowerCase().trim();

        try 

            if (selectMode.equals("d")) 

                System.out.print(" Day/s: ");
                Long days = userInput.nextLong();

                System.out.println("\n  Hour/s: " + TimeUnit.DAYS.toHours(days) + ".hr/s");
                System.out.println("  Minute/s: " + TimeUnit.DAYS.toMinutes(days) + ".min/s");
                System.out.println("  Second/s: " + TimeUnit.DAYS.toSeconds(days) + ".sec/s");
                System.out.println("  Milli-Second/s: " + TimeUnit.DAYS.toMillis(days) + ".milli/s");

             else if (selectMode.equals("h")) 

                System.out.print(" Hour/s: ");
                Long hours = userInput.nextLong();

                System.out.println("\n  Day/s: " + TimeUnit.HOURS.toDays(hours) + ".day/s");
                System.out.println("  Minutes/s: " + TimeUnit.HOURS.toMinutes(hours) + ".min/s");
                System.out.println("  Second/s: " + TimeUnit.HOURS.toSeconds(hours) + ".sec/s");
                System.out.println("  Milli-Second/s: " + TimeUnit.HOURS.toMillis(hours) + ".milli/s");

             else if (selectMode.equals("m")) 

                System.out.print(" Minute/s: ");
                Long minutes = userInput.nextLong();

                System.out.println("\n  Day/s: " + TimeUnit.MINUTES.toDays(minutes) + ".day/s");
                System.out.println("  Hour/s: " + TimeUnit.MINUTES.toHours(minutes) + ".hr/s");
                System.out.println("  Second/s: " + TimeUnit.MINUTES.toSeconds(minutes) + ".sec/s");
                System.out.println("  Milli-Second/s: " + TimeUnit.MINUTES.toMillis(minutes) + ".milli/s");

             else if (selectMode.equals("s")) 

                System.out.print(" Second/s: ");
                Long seconds = userInput.nextLong();

                System.out.println("\n  Day/s: " + TimeUnit.SECONDS.toDays(seconds) + ".day/s");
                System.out.println("  Hour/s: " + TimeUnit.SECONDS.toHours(seconds) + ".hr/s");
                System.out.println("  Minute/s: " + TimeUnit.SECONDS.toMinutes(seconds) + ".min/s");
                System.out.println("  Milli-Second/s: " + TimeUnit.SECONDS.toMillis(seconds) + ".milli/s");

             else if (selectMode.equals("ss")) 

                System.out.print(" Milli-Second/s: ");
                Long millis = userInput.nextLong();

                System.out.println("\n  Day/s: " + TimeUnit.MILLISECONDS.toDays(millis) + ".day/s");
                System.out.println("  Hour/s: " + TimeUnit.MILLISECONDS.toHours(millis) + ".hr/s");
                System.out.println("  Minute/s: " + TimeUnit.MILLISECONDS.toMinutes(millis) + ".min/s");
                System.out.println("  Second/s: " + TimeUnit.MILLISECONDS.toSeconds(millis) + ".sec/s");
                System.out.println("  Nano-Second/s: " + TimeUnit.MILLISECONDS.toNanos(millis) + ".nano/s");

             else 

                System.out.println(" \"" + selectMode + "\" is not a valid mode. Please try again.\n");
                TimeConverter.main(args);

            
         catch (InputMismatchException error) 

            System.out.println(" Please enter numbers only.\n");
            TimeConverter.main(args);

         catch (Exception error) 

            System.out.println(" Something went wrong. Please try again.\n");
            TimeConverter.main(args);

        
    

【讨论】:

作为一般规则,在发布代码时,请解释它的作用以及它如何解决手头的问题,以及它与现有答案的不同之处。在这种情况下,代码似乎也做了一些与问题无关的事情(读取用户输入?)(转换日期/秒)。专注于这一点应该有助于使答案更简洁。 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于使用 Duration 对象在 Java 中将天、分钟、小时转换为秒失败的主要内容,如果未能解决你的问题,请参考以下文章

如何在sql中将分钟拆分为天、小时和分钟

Java 8 的 Period 和 Duration 类

java8时间搓计算代码运行时间

Java日期时间API系列9-----Jdk8中java.time包中的新的日期时间API类的Period和Duration的区别

在 JavaScript 中将 Dialogfow 持续时间系统实体从分钟转换为秒

在 Java 中将字符串转换为日历对象