String.format 打印错误的时间
String.format prints wrong hours
我正在使用 String.format 打印经过的时间。这对 minutes:seconds...
非常有用
long millis = 330000;
String.format("%tMm%tSs", millis, millis);
...将打印 05 分 30 秒。
但是,当我尝试在已用时间中包含小时数时,小时数显示为 19!起初我以为这是我的语言环境,但我尝试了以下...
long millis = 330000;
String.format(Locale.ITALY, "%tHh%tMm%tSs", millis, millis, millis);
...我仍然得到 19h05m30s。
你甚至可以试试
long millis = 0;
String.format(Locale.ITALY, "%tHh", millis);
但你仍然得到 19h。
怎么回事?
检查 modifiers,几个小时是 tl
而不是 tHh
。
For long, Long, and Date the time zone used is the default time zone
for this instance of the Java virtual machine. The Formatter's locale
will supersede the locale of the argument (if any).
我想 Locale 参数纯粹是为了格式化而不是时间计算。
long
值被视为 java.util.Date
,而不是持续时间。这就是时区影响它的原因。您的毫秒值相当于表示 00:05:30 1970 年 1 月 1 日 UTC.
的日期
尝试使时间相对于当地时区的午夜:
long millis = 330000;
System.out.printf("%THh%<tMm%<tSs%n", millis);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.add(Calendar.MILLISECOND, (int) millis);
System.out.printf("%THh%<tMm%<tSs%n", cal);
看这个例子:
int s = 330;
System.out.println(String.format("%d:%02d:%02d", s/3600, (s%3600)/60, (s%60)));
我使用了秒,但该示例也适用于毫秒,但您必须在示例中的每个数字上添加 000 :)
乔达时间
Joda-Time 库具有 class 智能处理时间跨度的功能,让您避免处理毫秒。
ISO 8601
ISO 8601 标准定义了一种类似于您尝试使用的格式。 Joda-Time 库默认使用 ISO 8601 格式来解析和生成此类字符串。
不要那么努力
所以换句话说,你工作太努力了。让 Joda-Time 2.7 在这里完成工作。
最好指定您想要的时区,而不是隐式依赖 JVM 当前的默认时区(随时可能更改)。
使用proper time zone names。切勿使用既不标准化也不唯一的 3 或 4 字母代码。
DateTimeZone zone = DateTimeZone.forID ( "Europe/Rome" );
通过捕获当前时刻来伪造一些数据,然后后退一些小时、分钟和秒。
DateTime now = DateTime.now ( zone );
DateTime then = now.minusHours(19).minusMinutes(5).minusSeconds ( 30 );
以两种方式表示时间跨度。首先,时间线上的一对定点。二、月数、天数、小时数等
Interval interval = new Interval( then, now ); // String representation defaults to the pair of date-time values displayed in ISO 8601 format.
Period period = interval.toPeriod(); // String representation defaults to ISO 8601 format of PnYnMnDTnHnMnS.
请注意,Period
class' toString
方法默认生成与您的 PnYnMnDTnHnMnS
类似的 ISO 8601 标准格式的字符串。 P
标记开始,而 T
将日期部分与时间部分分开。
转储到控制台。
System.out.println ( "interval: " + interval );
System.out.println ( "period: " + period );
当运行.
interval: 2015-04-18T12:16:55.700+02:00/2015-04-19T07:22:25.700+02:00
period: PT19H5M30S
我正在使用 String.format 打印经过的时间。这对 minutes:seconds...
非常有用long millis = 330000;
String.format("%tMm%tSs", millis, millis);
...将打印 05 分 30 秒。
但是,当我尝试在已用时间中包含小时数时,小时数显示为 19!起初我以为这是我的语言环境,但我尝试了以下...
long millis = 330000;
String.format(Locale.ITALY, "%tHh%tMm%tSs", millis, millis, millis);
...我仍然得到 19h05m30s。
你甚至可以试试
long millis = 0;
String.format(Locale.ITALY, "%tHh", millis);
但你仍然得到 19h。
怎么回事?
检查 modifiers,几个小时是 tl
而不是 tHh
。
For long, Long, and Date the time zone used is the default time zone for this instance of the Java virtual machine. The Formatter's locale will supersede the locale of the argument (if any).
我想 Locale 参数纯粹是为了格式化而不是时间计算。
long
值被视为 java.util.Date
,而不是持续时间。这就是时区影响它的原因。您的毫秒值相当于表示 00:05:30 1970 年 1 月 1 日 UTC.
尝试使时间相对于当地时区的午夜:
long millis = 330000;
System.out.printf("%THh%<tMm%<tSs%n", millis);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.add(Calendar.MILLISECOND, (int) millis);
System.out.printf("%THh%<tMm%<tSs%n", cal);
看这个例子:
int s = 330;
System.out.println(String.format("%d:%02d:%02d", s/3600, (s%3600)/60, (s%60)));
我使用了秒,但该示例也适用于毫秒,但您必须在示例中的每个数字上添加 000 :)
乔达时间
Joda-Time 库具有 class 智能处理时间跨度的功能,让您避免处理毫秒。
ISO 8601
ISO 8601 标准定义了一种类似于您尝试使用的格式。 Joda-Time 库默认使用 ISO 8601 格式来解析和生成此类字符串。
不要那么努力
所以换句话说,你工作太努力了。让 Joda-Time 2.7 在这里完成工作。
最好指定您想要的时区,而不是隐式依赖 JVM 当前的默认时区(随时可能更改)。
使用proper time zone names。切勿使用既不标准化也不唯一的 3 或 4 字母代码。
DateTimeZone zone = DateTimeZone.forID ( "Europe/Rome" );
通过捕获当前时刻来伪造一些数据,然后后退一些小时、分钟和秒。
DateTime now = DateTime.now ( zone );
DateTime then = now.minusHours(19).minusMinutes(5).minusSeconds ( 30 );
以两种方式表示时间跨度。首先,时间线上的一对定点。二、月数、天数、小时数等
Interval interval = new Interval( then, now ); // String representation defaults to the pair of date-time values displayed in ISO 8601 format.
Period period = interval.toPeriod(); // String representation defaults to ISO 8601 format of PnYnMnDTnHnMnS.
请注意,Period
class' toString
方法默认生成与您的 PnYnMnDTnHnMnS
类似的 ISO 8601 标准格式的字符串。 P
标记开始,而 T
将日期部分与时间部分分开。
转储到控制台。
System.out.println ( "interval: " + interval );
System.out.println ( "period: " + period );
当运行.
interval: 2015-04-18T12:16:55.700+02:00/2015-04-19T07:22:25.700+02:00
period: PT19H5M30S