Joda-Time: форматирование с несколькими форматами с одним Formatter - PullRequest
5 голосов
/ 11 марта 2011

Я бы хотел напечатать длительность в миллисекундах с разной спецификацией формата в зависимости от его размера:

case (1)      "H:mm"  if duration < 10 hours
case (2)     "HH:mm"  if duration < 24 hours
case (3)  "#d HH:mm"  else (duration >= 24 hours)

, что означает только 1-часовую цифру поля для длительностей менее 10 часов,
, но 2-часовую цифру поля при наличии поля начального дня!

Примеры:

case (1)      "0:45"  means 45 minutes,
              "1:23"  means 1 hour and 23 minutes,
case (2)     "12:05"  means 12 hours and 5 minutes and
case (3)  "1d 05:09"  means 1 day, 5 hours and 9 minutes
                               (= 29 hours and 9 minutes).

Я пытался с

object JodaTest {
  import org.joda.time._
  private val pdf = {
    import format._
    val pfb = new PeriodFormatterBuilder()
      .appendDays.appendSeparator("d ")
      .printZeroAlways
      .minimumPrintedDigits(2).appendHours.appendSeparator(":")
      .appendMinutes
    new PeriodFormatter(pfb.toPrinter, null)
  }
  def durstr(duration: Long): String =
    pdf.print((new Period(duration)).normalizedStandard)
}

, что приводит к

  2700000 => "00:45"     but should be "0:45"
  4980000 => "01:23"     but should be "1:23"
 43500000 => "12:05"
104940000 => "1d 05:09"

но я не знаю, как опустить ведущий ноль двухзначного представления дня в случае (1) но одновременно вынудить его напечатать в случае (3) с тем же PeriodFormat.

Возможно ли это сделать с помощью одного org.joda.time.format.PeriodFormatter?

Ответы [ 3 ]

1 голос
/ 11 марта 2011

Возможно, это не реальный ответ, но, тем не менее, я боюсь, что вам нужно два PeriodFormatter для решения этой задачи, поэтому управляйте им с помощью

object JodaTest {
  import org.joda.time._
  import format._
  private def pdf(digits: Int) = new PeriodFormatter(
    new PeriodFormatterBuilder()
      .appendDays.appendSeparator("d ")
      .printZeroAlways
      .minimumPrintedDigits(digits).appendHours.appendSeparator(":")
      .minimumPrintedDigits(2).appendMinutes
      .toPrinter, null)
  private lazy val pdf1 = pdf(1)
  private lazy val pdf2 = pdf(2)
  def durstr(duration: Long): String = {
    val period = new Period(duration).normalizedStandard
    val pdf = if (period.getDays > 0) pdf2 else pdf1
    pdf.print(period)
  }
}

что приводит к желаемому

  2700000 => "0:45"
  4980000 => "1:23"
 43500000 => "12:05"
104940000 => "1d 05:09".
0 голосов
/ 22 марта 2011

Вы можете реализовать интерфейс PeriodPrinter для точного форматирования периода, а затем использовать строитель для настройки форматера.

0 голосов
/ 13 марта 2011

Все еще нашел решение только с one PeriodFormatter, но выполнил небольшую работу вне Joda-Time.

Идея состоит в том, чтобы

  1. Создание необработанной форматированной строки, например, «000d 00:00» с Joda-Time и
  2. удалить ненужные ведущие нули отдельно

с

object JodaTest {
  import org.joda.time._
  import format._
  // "000d 00:00" - 3 day digits for periods with up to 999 days long
  private val pdf = new PeriodFormatter(new PeriodFormatterBuilder()
    .printZeroAlways
    .minimumPrintedDigits(3).appendDays.appendSeparator("d ")
    .minimumPrintedDigits(2).appendHours.appendSeparator(":").appendMinutes
    .toPrinter, null)
  private def adjust(rawstr: String): String = {
    // "000d 00:00" => ("000d 0", "0:00")
    val (first, second) = rawstr splitAt 6
    // remove unwanted leading zeros in first part, keep it in second
    first.dropWhile(c => !c.isDigit || c == '0') + second
  }
  def durstr(duration: Long): String = {
    // PeriodType.dayTime => day is the most significant field (no weeks etc.)
    adjust(pdf.print(new Period(duration) normalizedStandard PeriodType.dayTime))
  }
}

, что приводит к

   duration =>       rawstr =>       adjust
          0 => "000d 00:00" =>       "0:00"
    2700000 => "000d 00:45" =>       "0:45"
    4980000 => "000d 01:23" =>       "1:23"
   43500000 => "000d 12:05" =>      "12:05"
  104940000 => "001d 05:09" =>   "1d 05:09"
  518760000 => "006d 00:06" =>   "6d 00:06"
  605220000 => "007d 00:07" =>   "7d 00:07"
  951060000 => "011d 00:11" =>  "11d 00:11"
43230000000 => "500d 08:20" => "500d 08:20"

Конечно, было бы неплохо создавать такие форматы напрямую с помощью Joda-Time, указав шаблон, такой как числовой формат Excel (#, ## 0,00 #), в котором указывается, где всегда нужны нули или только при необходимости. Но, похоже, неясно, как определить его точно, потому что у вас есть не только '0' и '#', но вам нужны символы для каждого поля и вставка литералов в строку формата (возможно, через экранирование), тоже было бы неплохо.

...