Jer*_*gan 42 java formatting time date
我想拍两次(自纪元以来几秒钟),并以两种格式显示两者之间的差异:
我该怎么做到这一点?
Bal*_*usC 68
因为每个人都喊"YOODAA !!!" 但没有人发布一个具体的例子,这是我的贡献.
你也可以用Joda-Time做到这一点.使用Period代表一个时期.要格式化所需人类表示中的句点,请使用PeriodFormatter您可以构建的句点PeriodFormatterBuilder.
这是一个启动示例:
DateTime myBirthDate = new DateTime(1978, 3, 26, 12, 35, 0, 0);
DateTime now = new DateTime();
Period period = new Period(myBirthDate, now);
PeriodFormatter formatter = new PeriodFormatterBuilder()
.appendYears().appendSuffix(" year, ", " years, ")
.appendMonths().appendSuffix(" month, ", " months, ")
.appendWeeks().appendSuffix(" week, ", " weeks, ")
.appendDays().appendSuffix(" day, ", " days, ")
.appendHours().appendSuffix(" hour, ", " hours, ")
.appendMinutes().appendSuffix(" minute, ", " minutes, ")
.appendSeconds().appendSuffix(" second", " seconds")
.printZeroNever()
.toFormatter();
String elapsed = formatter.print(period);
System.out.println(elapsed + " ago");
Run Code Online (Sandbox Code Playgroud)
更清晰简洁,不是吗?
这打印到现在
32 years, 1 month, 1 week, 5 days, 6 hours, 56 minutes, 24 seconds ago
(咳嗽,老,咳)
Tim*_*our 45
Date start = new Date(1167627600000L); // JANUARY_1_2007
Date end = new Date(1175400000000L); // APRIL_1_2007
long diffInSeconds = (end.getTime() - start.getTime()) / 1000;
long diff[] = new long[] { 0, 0, 0, 0 };
/* sec */diff[3] = (diffInSeconds >= 60 ? diffInSeconds % 60 : diffInSeconds);
/* min */diff[2] = (diffInSeconds = (diffInSeconds / 60)) >= 60 ? diffInSeconds % 60 : diffInSeconds;
/* hours */diff[1] = (diffInSeconds = (diffInSeconds / 60)) >= 24 ? diffInSeconds % 24 : diffInSeconds;
/* days */diff[0] = (diffInSeconds = (diffInSeconds / 24));
System.out.println(String.format(
"%d day%s, %d hour%s, %d minute%s, %d second%s ago",
diff[0],
diff[0] > 1 ? "s" : "",
diff[1],
diff[1] > 1 ? "s" : "",
diff[2],
diff[2] > 1 ? "s" : "",
diff[3],
diff[3] > 1 ? "s" : ""));
Run Code Online (Sandbox Code Playgroud)
Abd*_*ius 18
Yup唤醒了我的死者,但这里是基于@mtim发布的代码的改进实现,因为这个线程几乎在搜索之上,所以我正在弄乱困的空洞,
public static String getFriendlyTime(Date dateTime) {
StringBuffer sb = new StringBuffer();
Date current = Calendar.getInstance().getTime();
long diffInSeconds = (current.getTime() - dateTime.getTime()) / 1000;
/*long diff[] = new long[]{0, 0, 0, 0};
/* sec * diff[3] = (diffInSeconds >= 60 ? diffInSeconds % 60 : diffInSeconds);
/* min * diff[2] = (diffInSeconds = (diffInSeconds / 60)) >= 60 ? diffInSeconds % 60 : diffInSeconds;
/* hours * diff[1] = (diffInSeconds = (diffInSeconds / 60)) >= 24 ? diffInSeconds % 24 : diffInSeconds;
/* days * diff[0] = (diffInSeconds = (diffInSeconds / 24));
*/
long sec = (diffInSeconds >= 60 ? diffInSeconds % 60 : diffInSeconds);
long min = (diffInSeconds = (diffInSeconds / 60)) >= 60 ? diffInSeconds % 60 : diffInSeconds;
long hrs = (diffInSeconds = (diffInSeconds / 60)) >= 24 ? diffInSeconds % 24 : diffInSeconds;
long days = (diffInSeconds = (diffInSeconds / 24)) >= 30 ? diffInSeconds % 30 : diffInSeconds;
long months = (diffInSeconds = (diffInSeconds / 30)) >= 12 ? diffInSeconds % 12 : diffInSeconds;
long years = (diffInSeconds = (diffInSeconds / 12));
if (years > 0) {
if (years == 1) {
sb.append("a year");
} else {
sb.append(years + " years");
}
if (years <= 6 && months > 0) {
if (months == 1) {
sb.append(" and a month");
} else {
sb.append(" and " + months + " months");
}
}
} else if (months > 0) {
if (months == 1) {
sb.append("a month");
} else {
sb.append(months + " months");
}
if (months <= 6 && days > 0) {
if (days == 1) {
sb.append(" and a day");
} else {
sb.append(" and " + days + " days");
}
}
} else if (days > 0) {
if (days == 1) {
sb.append("a day");
} else {
sb.append(days + " days");
}
if (days <= 3 && hrs > 0) {
if (hrs == 1) {
sb.append(" and an hour");
} else {
sb.append(" and " + hrs + " hours");
}
}
} else if (hrs > 0) {
if (hrs == 1) {
sb.append("an hour");
} else {
sb.append(hrs + " hours");
}
if (min > 1) {
sb.append(" and " + min + " minutes");
}
} else if (min > 0) {
if (min == 1) {
sb.append("a minute");
} else {
sb.append(min + " minutes");
}
if (sec > 1) {
sb.append(" and " + sec + " seconds");
}
} else {
if (sec <= 1) {
sb.append("about a second");
} else {
sb.append("about " + sec + " seconds");
}
}
sb.append(" ago");
/*String result = new String(String.format(
"%d day%s, %d hour%s, %d minute%s, %d second%s ago",
diff[0],
diff[0] > 1 ? "s" : "",
diff[1],
diff[1] > 1 ? "s" : "",
diff[2],
diff[2] > 1 ? "s" : "",
diff[3],
diff[3] > 1 ? "s" : ""));*/
return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)
它显然可以改善.基本上它试图让时间跨度更友好,但有一些限制,即如果时间过去(参数)将来会出现奇怪的行为,并且它仅限于几天,几小时和几秒(几个月和几年没有处理,以便其他人可以;-).
样本输出是:
,干杯:D
编辑:现在支持数月和数年:P
其他答案可能是正确的,但已过时.Java中令人烦恼的旧日期时间类现在已经遗留下来,取而代之的是java.time类.
同样,现在处于维护模式的Joda-Time项目建议迁移到java.time类.
Instant两次(自纪元以来的秒数)
在java.time中,我们用UTC表示时间轴上的时刻Instant.我将假设您的纪元与java.time相同,这是UTC(1970-01-01T00:00:00Z)1970年的第一个时刻.请注意,Instanta的分辨率为纳秒.Instant如问题中所述,便利工厂方法从整秒开始构造.
Instant start = Instant.ofEpochSecond( … );
Instant stop = Instant.ofEpochSecond( … );
Run Code Online (Sandbox Code Playgroud)
这里我们使用当前时刻和几分钟后.
Instant start = Instant.now() ;
Instant stop = start.plusSeconds( TimeUnit.MINUTES.toSeconds( 7L ) ) ; // Seven minutes as a number of seconds.
Run Code Online (Sandbox Code Playgroud)
Duration在java.time中,未附加到时间轴的时间跨度以两种方式表示.几年 - 月 - 天,我们有Period.我们有几小时 - 几分钟Duration.
Duration duration = Duration.between( start , stop );
Run Code Online (Sandbox Code Playgroud)
使用半开放方法计算经过的时间.在这种方法中,开头是包容性的,而结尾是独占的.这种方法通常用于日期时间工作.我相信在您的代码库中始终如一地使用这种方法将有助于消除由于含糊不清而导致的错误和误解,并且可以减轻编程的认知负担.
在ISO 8601标准定义表示日期时间值作为文本许多实际的格式.这些格式旨在避免歧义,易于通过机器解析,并且可以直观地跨文化阅读.
在解析和生成字符串时,java.time类默认使用这些格式.
对于时间没有附加到时间轴上的跨度,该标准定义的格式的PnYnMnDTnHnMnS地方P标志着开始和T分离任何年-月-日从任何小时,分钟,秒.所以一个半小时PT1H30M.
在我们的示例代码中使用七分钟:
String outputStandard = duration.toString();
Run Code Online (Sandbox Code Playgroud)
PT7M
请参阅IdeOne.com上运行的上述示例代码.
我建议尽可能坚持使用这些格式,当然在交换或序列化日期时间数据时,还要考虑在适当的用户界面中使用,并且可以训练用户使用它们.
我建议永远不要使用时钟格式(例如:01:30为一小时),因为该格式与时间完全不一致.
如果您必须拼出问题中所示的时间范围,则需要自己构建文本.
Period,调用getYears,getMonths以及getDays检索每个部分.Duration类缺乏这样干将的Java 8,但在获得了他们的Java 9及更高版本:toDaysPart,toHoursPart,toMinutesPart,toSecondsPart,和toNanosPart.一些示例代码,简单和基本,以帮助您入门.
int days = duration.toDaysPart() ;
int hours = duration.toHoursPart() ;
int minutes = duration.toMinutesPart() ;
int seconds = duration.toSecondsPart() ;
int nanos = duration.toNanosPart() ;
StringBuilder sb = new StringBuilder( 100 );
if( days != 0 ) {
sb.append( days + " days" ) ;
};
if( hours != 0 ) {
sb.append( ( sb.length = 0 ) ? ( "" ) : ( ", " ) ) ; // Append comma if any existing text.
sb.append( hours + " hours" ) ;
};
if( minutes != 0 ) {
sb.append( ( sb.length = 0 ) ? ( "" ) : ( ", " ) ) ; // Append comma if any existing text.
sb.append( minutes + " minutes" ) ;
};
if( seconds != 0 ) {
sb.append( ( sb.length = 0 ) ? ( "" ) : ( ", " ) ) ; // Append comma if any existing text.
sb.append( seconds + " seconds" ) ;
};
if( nanos != 0 ) {
sb.append( ( sb.length = 0 ) ? ( "" ) : ( ", " ) ) ; // Append comma if any existing text.
sb.append( nanos + " nanos" ) ;
};
String output = sb.toString();
Run Code Online (Sandbox Code Playgroud)
或者也许您可以DateTimeFormatterBuilder按照Balus C的答案中使用Joda-Time显示的方式编写更流畅的代码.
该java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.
现在处于维护模式的Joda-Time项目建议迁移到java.time类.
要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.
从哪里获取java.time类?
该ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在这里找到一些有用的类,例如Interval,YearWeek和YearQuarter,以及更多.