2015-04-17 2 views
3

Я использую String.format для печати прошедшего времени. Это отлично работает в течение минут: секунд ...String.format печатает неправильные часы

long millis = 330000; 
String.format("%tMm%tSs", millis, millis); 

... будет печатать 05m30s.

Однако, когда я пытаюсь включить часы в мое прошедшее время, часы показаны как 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.

Что происходит?

+0

Что вы подразумеваете под «когда я пытаюсь включить часы в мое прошедшее время»? –

+0

Извините, я забыл форматировать в своей строке формата. Я отредактировал вопрос. – naugler

+0

Я получаю '01h05m30s' для второго – Sionnach733

ответ

1

Значение long рассматривается как java.util.Date, а не продолжительность. Вот почему часовой пояс влияет на него. Значение вашего миллиса эквивалентно дате, представляющей 00:05:30 1 января 1970 г. 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); 
+0

Спасибо, это была основная проблема. Я знал, что это будет относиться к ценности как к дате, но я ХОТЕЛ представить 00:05:30 1 января 1970 года (часы, минуты и секунды все еще только истекли с 00:00:00 1 января 1970 года) , однако я не знал о том, как будет обрабатываться часовой пояс. См. Мой собственный ответ. – naugler

-1

Проверьте modifiers, часами это tl не tHh.

+0

H является действующим модификатором в течение 24 часов, и я хочу напечатать букву «h» после часов – naugler

+0

Тот же результат, но '3h05m30s' вместо' 03h05m30s' –

0

От Formatter doc:

долго, долго, и дата часового пояса используется часовой пояс по умолчанию для этого экземпляра виртуальной машины Java. Локаль Formatter заменит локаль аргумента (если есть).

Я предполагаю, что аргумент Locale предназначен исключительно для форматирования, а не для вычисления времени.

0

Посмотрите на этот пример:

int s = 330; 
System.out.println(String.format("%d:%02d:%02d", s/3600, (s%3600)/60, (s%60))); 

я использовал секунд, но этот пример будет также работать на миллисекунды, но Вы должны добавьте 000 к каждой цифре в примере :)

+0

Не то, что я задал, но да, я решил сделать что-то подобное, чтобы избежать проблем с часовым поясом. Спасибо за вашу помощь. – naugler

1

Joda-Time

В библиотеке Joda-Time есть классы, позволяющие разумно обрабатывать промежуток времени, позволяя избегать общения с миллисекундами.

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 класс toString метод по умолчанию генерирует строку в стандартном формате ISO 8601 похожа на вашу, PnYnMnDTnHnMnS. 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 
+0

Очень полезные примеры, спасибо – naugler

Смежные вопросы