Joda-Time:使用单个格式化程序以多种格式进行格式化

发布于 2024-10-21 18:20:48 字数 1373 浏览 2 评论 0原文

我想根据其大小以不同的格式规范打印以毫秒为单位的持续时间:

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)

这意味着持续时间低于 10 小时的情况下只有 1 小时的字段数字,
但是当具有前导日期字段时则为 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)
}

which 导致

  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 来做到这一点?

I'd like to print durations given in milliseconds with different format specification depending on its size:

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)

which means only 1 hour field digit for durations lower than 10 hours,
but 2 hour field digits when having a leading day field!

Examples:

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).

I had tried with

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)
}

which leads to

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

but I don't know how to omit leading zero of two-digit-day-representation in case (1)
but simultaneously force to print it in case (3) with same PeriodFormat.

Is it possible to do that with a single org.joda.time.format.PeriodFormatter?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

倥絔 2024-10-28 18:20:48

也许不是一个真正的答案,但同时我担心你需要两个 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".

Perhaps not a real answer but meanwhile I'm afraid that you need two PeriodFormatter to solve this task, so manage it with

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)
  }
}

which leads to desired

  2700000 => "0:45"
  4980000 => "1:23"
 43500000 => "12:05"
104940000 => "1d 05:09".
一抹淡然 2024-10-28 18:20:48

您可以实现PeriodPrinter接口来完全按照您想要的方式格式化周期,然后使用构建器 设置格式化程序。

You can implement the PeriodPrinter interface to format the period exactly as you want, then use the builder to set up the formatter.

独闯女儿国 2024-10-28 18:20:48

仍然找到了一个只有 一个 PeriodFormatter 的解决方案,但在 Joda-Time 之外做了一些工作。

这个想法是

  1. 使用 Joda-Time 生成像“000d 00:00”这样的原始格式化字符串,并
  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”和“#”,而且每个字段都需要字符并将文字放入格式字符串(可能通过转义)也很好。

Still found a solution with only one PeriodFormatter but doing a little work outside Joda-Time.

The idea is to

  1. Produce a raw formatted string like "000d 00:00" with Joda-Time and
  2. remove unwanted leading zeros separately

with

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))
  }
}

which leads to

   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"

Of course, it would be nice to build such formats directly with Joda-Time by specifying a pattern like an Excel number format (#,##0.00#) to say where one want zeros ever or only if required. But it seems not clear how to define it exactly because you have not only '0' and '#' but need chars for each field and put literals into format string (perhaps via escaping) would be nice too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文