使用 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
请指导。
【问题讨论】:
Duration
是 java.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】:deHaar、DevX 和 Ole 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 中将天、分钟、小时转换为秒失败的主要内容,如果未能解决你的问题,请参考以下文章
Java日期时间API系列9-----Jdk8中java.time包中的新的日期时间API类的Period和Duration的区别