duration.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright 2013 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Functions for formatting duration values. Such as "3 days"
  16. * "3 hours", "14 minutes", "2 hours 45 minutes".
  17. *
  18. */
  19. goog.provide('goog.date.duration');
  20. goog.require('goog.i18n.DateTimeFormat');
  21. goog.require('goog.i18n.MessageFormat');
  22. /**
  23. * Number of milliseconds in a minute.
  24. * @type {number}
  25. * @private
  26. */
  27. goog.date.duration.MINUTE_MS_ = 60000;
  28. /**
  29. * Number of milliseconds in an hour.
  30. * @type {number}
  31. * @private
  32. */
  33. goog.date.duration.HOUR_MS_ = 3600000;
  34. /**
  35. * Number of milliseconds in a day.
  36. * @type {number}
  37. * @private
  38. */
  39. goog.date.duration.DAY_MS_ = 86400000;
  40. /**
  41. * Accepts a duration in milliseconds and outputs an absolute duration time in
  42. * form of "1 day", "2 hours", "20 minutes", "2 days 1 hour 15 minutes" etc.
  43. * @param {number} durationMs Duration in milliseconds.
  44. * @return {string} The formatted duration.
  45. */
  46. goog.date.duration.format = function(durationMs) {
  47. var ms = Math.abs(durationMs);
  48. // Handle durations shorter than 1 minute.
  49. if (ms < goog.date.duration.MINUTE_MS_) {
  50. /**
  51. * @desc Duration time of zero minutes.
  52. */
  53. var MSG_ZERO_MINUTES = goog.getMsg('0 minutes');
  54. return MSG_ZERO_MINUTES;
  55. }
  56. var days = Math.floor(ms / goog.date.duration.DAY_MS_);
  57. ms %= goog.date.duration.DAY_MS_;
  58. var hours = Math.floor(ms / goog.date.duration.HOUR_MS_);
  59. ms %= goog.date.duration.HOUR_MS_;
  60. var minutes = Math.floor(ms / goog.date.duration.MINUTE_MS_);
  61. // Localized number representations.
  62. var daysText = goog.i18n.DateTimeFormat.localizeNumbers(days);
  63. var hoursText = goog.i18n.DateTimeFormat.localizeNumbers(hours);
  64. var minutesText = goog.i18n.DateTimeFormat.localizeNumbers(minutes);
  65. // We need a space after the days if there are hours or minutes to come.
  66. var daysSeparator = days * (hours + minutes) ? ' ' : '';
  67. // We need a space after the hours if there are minutes to come.
  68. var hoursSeparator = hours * minutes ? ' ' : '';
  69. /**
  70. * @desc The days part of the duration message: 1 day, 5 days.
  71. */
  72. var MSG_DURATION_DAYS = goog.getMsg(
  73. '{COUNT, plural, ' +
  74. '=0 {}' +
  75. '=1 {{TEXT} day}' +
  76. 'other {{TEXT} days}}');
  77. /**
  78. * @desc The hours part of the duration message: 1 hour, 5 hours.
  79. */
  80. var MSG_DURATION_HOURS = goog.getMsg(
  81. '{COUNT, plural, ' +
  82. '=0 {}' +
  83. '=1 {{TEXT} hour}' +
  84. 'other {{TEXT} hours}}');
  85. /**
  86. * @desc The minutes part of the duration message: 1 minute, 5 minutes.
  87. */
  88. var MSG_DURATION_MINUTES = goog.getMsg(
  89. '{COUNT, plural, ' +
  90. '=0 {}' +
  91. '=1 {{TEXT} minute}' +
  92. 'other {{TEXT} minutes}}');
  93. var daysPart = goog.date.duration.getDurationMessagePart_(
  94. MSG_DURATION_DAYS, days, daysText);
  95. var hoursPart = goog.date.duration.getDurationMessagePart_(
  96. MSG_DURATION_HOURS, hours, hoursText);
  97. var minutesPart = goog.date.duration.getDurationMessagePart_(
  98. MSG_DURATION_MINUTES, minutes, minutesText);
  99. /**
  100. * @desc Duration time text concatenated from the individual time unit message
  101. * parts. The separator will be a space (e.g. '1 day 2 hours 24 minutes') or
  102. * nothing in case one/two of the duration parts is empty (
  103. * e.g. '1 hour 30 minutes', '3 days 15 minutes', '2 hours').
  104. */
  105. var MSG_CONCATENATED_DURATION_TEXT = goog.getMsg(
  106. '{$daysPart}{$daysSeparator}{$hoursPart}{$hoursSeparator}{$minutesPart}',
  107. {
  108. 'daysPart': daysPart,
  109. 'daysSeparator': daysSeparator,
  110. 'hoursPart': hoursPart,
  111. 'hoursSeparator': hoursSeparator,
  112. 'minutesPart': minutesPart
  113. });
  114. return MSG_CONCATENATED_DURATION_TEXT;
  115. };
  116. /**
  117. * Gets a duration message part for a time unit.
  118. * @param {string} pattern The pattern to apply.
  119. * @param {number} count The number of units.
  120. * @param {string} text The string to use for amount of units in the message.
  121. * @return {string} The formatted message part.
  122. * @private
  123. */
  124. goog.date.duration.getDurationMessagePart_ = function(pattern, count, text) {
  125. var formatter = new goog.i18n.MessageFormat(pattern);
  126. return formatter.format({'COUNT': count, 'TEXT': text});
  127. };