将经过的毫秒转换为正确的 java 日期格式?
Posted
技术标签:
【中文标题】将经过的毫秒转换为正确的 java 日期格式?【英文标题】:Converting elapsed milliseconds into proper java date format? 【发布时间】:2012-11-13 18:06:41 【问题描述】:我在开发过程中遇到困难,我有这样的要求,我需要找到两个日期之间的延迟,即..currentdate-date from database
我需要以 dd:hh:mm
的格式显示延迟。在参考了很多参考资料后,我发现了如何转换为单个毫秒的小时和分钟,但期待的是:如果结果是 X 毫秒,我需要以正确的日分钟和秒格式显示它
示例:2 天:03 分钟:46 秒
这是我正在使用的代码:
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar1.setTime(date);
calendar2.setTime(date1);
long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds1 - milliseconds2;
System.out.println("diff ::"+diff);
long diffSeconds = diff / 1000;
long diffMinutes = diff / (60 * 1000);
long diffHours = diff / (60 * 60 * 1000);
long diffDays = diff / (24 * 60 * 60 * 1000);
谁能建议我进一步做什么? 请指导我..
【问题讨论】:
在该代码中,您假设每天有 24 小时,每小时有 60 分钟,每分钟有 60 秒。这不适用于夏令时的国家,也不适用于闰秒的行星。您应该改用 Joda Time 之类的日历框架,并让它完成繁重的工作。 @wallenborn ,是的,现在在 joda time 做后台工作,你能帮我看看如何使用它 仅供参考,麻烦的旧日期时间类,例如java.util.Date
、java.util.Calendar
和 java.text.SimpleDateFormat
现在是 legacy,被 Java 8 及更高版本中内置的 java.time 类所取代.见Tutorial by Oracle。
【参考方案1】:
使用Joda Time。 Java API 不包含任何处理“两个日期/时间值之间的差异”的内容。在 Joda Time 中,您可以在 Period
(实际上是针对以日历为中心的差异)和 Duration
(实际上只是经过的时间差异)之间进行选择。
理想情况下,将 Joda Time 用于所有您的日期/时间问题 - 这是一个更好、更好的 API。
在这种情况下,我怀疑您逻辑上得到了Duration
,但您需要将其转换为Period
,以便使用PeriodFormatter
进行字符串转换.
【讨论】:
你能提供一些joda time的例子吗 @Esh:嗯,你尝试了什么? 到目前为止,我尝试分别获取小时和分钟,现在我陷入了年表概念,我想将年表设置为“000”,但将默认设置为 ISOChronology[亚洲/加尔各答] ,不知道如何覆盖它 @Esh:你说的“000”是什么意思?听起来你可能想要ISOChronology.getInstanceUTC
。
,.我会在***.com/questions/13577222/… 中发布我的作品。请指导我【参考方案2】:
你需要先计算diffDays
diffDays = diff / (24 * 60 * 60 * 1000);
然后计算剩余的毫秒数:
diff -= diffDays * 24 * 60 * 60 * 1000;
使用新的 diff 计算 diffHours 等等...
一个建议:使用像这样的常量值:
private static final int SECOND = 1000;
private static final int MINUTE = 60 * SECOND;
// and so on
【讨论】:
丹,你能不能详细解释一下 这假设每天有 24 小时,如果你住在有夏令时的地区,每年都会失败两次。 您还能找到哪些其他极端情况?也许你可以对每一个投反对票。【参考方案3】:-我建议您在处理任何日期时间问题时使用 Joda
库。
Joda Time 有一个时间间隔的概念:
Interval interval = new Interval(oldTime, new Instant());
顺便说一下,Joda 有两个概念:Interval 表示两个时间点之间的时间间隔(表示上午 8 点到 10 点之间的时间),以及 Duration 表示没有实际时间界限的时间长度(例如表示两个小时!)
【讨论】:
仅供参考,Joda-Time 项目现在位于maintenance mode,团队建议迁移到java.time 类。见Tutorial by Oracle。【参考方案4】:有了 JodaTime,这真的很容易。见以下代码:
public void testJoda()
DateTime then = new DateTime("2012-03-23T02:30:00.000");
DateTime now = new DateTime("2012-03-24T02:29:00.000");
DurationFieldType[] ddhhmm = DurationFieldType.days(),
DurationFieldType.hours(), DurationFieldType.minutes() ;
Period p = new Period(then, now, PeriodType.forFields(ddhhmm));
System.out.println(p.toString());
p = new Period(then, now, PeriodType.days());
System.out.println(p.toString());
p = new Period(then, now, PeriodType.hours());
System.out.println(p.toString());
DurationFieldType[] hhmm = DurationFieldType.hours(), DurationFieldType.minutes() ;
p = new Period(then, now, PeriodType.forFields(hhmm));
System.out.println(p.toString());
测试间隔为 23h59m。它的输出符合预期:
PT23H59M
P0D
PT23H
PT23H59M
以同样的时间间隔,一天后,就在 3 月 25 日春季 DST 跳跃前后:
DateTime then = new DateTime("2012-03-24T02:30:00.000");
DateTime now = new DateTime("2012-03-25T03:29:00.000");
你正确得到:
P1DT-1M
P1D
PT23H
PT23H59M
真的,没有比这更容易的了。
【讨论】:
仅供参考,Joda-Time 项目现在位于maintenance mode,团队建议迁移到java.time 类。见Tutorial by Oracle。【参考方案5】:Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar1.setTime(date);
calendar2.setTime(date1);
int dayDiff = calendar1.get(Calendar.DAY_OF_MONTH) - calendar2.get(Calendar.DAY_OF_MONTH);
int hourDiff = calendar1.get(Calendar.HOUR_OF_DAY) -calendar2.get(Calendar.HOUR_OF_DAY);
int dayDiff = calendar1.get(Calendar.SECOND) - calendar2.get(Calendar.SECOND);
【讨论】:
【参考方案6】:tl;博士
Duration.between( // Represent a span of time, unattached to the timeline.
earlier , // `Instant` class represents a moment in UTC with a resolution as fine as nanoseconds. Current moment captured in microseconds, depending on capability of host computer hardware and operating system.
Instant.now()
) // Returns a `Duration` object. Call `to…Part` methods to get the days, hours, minutes, seconds as separate numbers.
java.time
使用现代的 java.time 类取代了与最早的 Java 版本捆绑在一起的麻烦的旧日期时间类时,要容易得多。
获取 UTC 中的当前时刻。 Instant
类代表UTC 时间线上的时刻,分辨率为nanoseconds(最多九 (9) 位小数)。
当前时刻在 Java 8 中的 milliseconds 中捕获。在 Java 9 及更高版本中,由于Clock
的全新实现,您可能会看到以更精细的粒度捕获的当前时刻。在 macOS Sierra 上的 Oracle Java 9 JDK 中,我得到了 microseconds 中的当前时刻(六位小数秒)。
Instant earlier = Instant.now() ;
…
Instant later = Instant.now() ;
将经过的时间计算为与时间轴无关的时间跨度。对于小时-分钟-秒(以及与日历无关的 24 小时时间块),请使用 Duration
。对于年-月-日的比例,请使用Period
。
Duration d = Duration.between( earlier , later ) ;
生成一个字符串是standard ISO 8601 format,PnYnMnDTnHnMnS
,其中P
标志着开始,T
将年-月-日与小时-分钟-秒分开。
String output = d.toString() ; // Standard ISO 8601 format.
我强烈建议使用标准格式,而不是问题中看到的格式。我已经看到时间格式会导致如此多的混乱和模棱两可,以至于它可能被误认为是一天中的时间而不是时间跨度。 ISO 8601 格式的设计巧妙地避免了这种歧义。但如果您坚持,在 Java 9 及更高版本中,您可以通过调用 to…Part
方法来请求 Duration
的部分。
long days = d.toDaysPart() ; // 24-hour chunks of time, unrelated to calendar dates.
int hours = d.toHoursPart() ;
int minutes = d.toMinutesPart() ;
然后根据需要组装成一个字符串。
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date
、Calendar
和 SimpleDateFormat
。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.*
类。
从哪里获得 java.time 类?
Java SE 8、Java SE 9、Java SE 10 及更高版本 内置。 标准 Java API 的一部分,带有捆绑实现。 Java 9 添加了一些小功能和修复。 Java SE 6 和 Java SE 7 ThreeTen-Backport 中的大部分 java.time 功能都向后移植到 Java 6 和 7。 Android java.time 类的 android 捆绑包实现的更高版本。 对于早期的 Android (ThreeTenABP 项目采用 ThreeTen-Backport(如上所述)。见How to use ThreeTenABP…。ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval
、YearWeek
、YearQuarter
和more。
【讨论】:
以上是关于将经过的毫秒转换为正确的 java 日期格式?的主要内容,如果未能解决你的问题,请参考以下文章