ソースを参照

cleaner formatting

Adam Shaw 7 年 前
コミット
7b21de4737

+ 4 - 7
src/agenda/TimeGrid.ts

@@ -161,15 +161,12 @@ export default class TimeGrid extends InteractiveDateComponent {
       input = input[input.length - 1]
     }
 
-    this.labelFormat = createFormatter(
-      input ||
-      {
-        // like "h(:mm)a" -> "6pm" / "6:30pm"
+    this.labelFormat = createFormatter(input || {
         hour: 'numeric',
         minute: '2-digit',
-        // TODO: omit minute if possible
-      }
-    )
+        omitZeroTime: true,
+        meridiem: 'short'
+    })
 
     input = this.opt('slotLabelInterval')
     this.labelInterval = input ?

+ 1 - 1
src/agenda/TimeGridEventRenderer.ts

@@ -56,7 +56,7 @@ export default class TimeGridEventRenderer extends EventRenderer {
     return {
       hour: 'numeric',
       minute: '2-digit',
-      // TODO: remove am/pm
+      meridiem: false
     }
   }
 

+ 2 - 2
src/basic/DayGridEventRenderer.ts

@@ -222,8 +222,8 @@ export default class DayGridEventRenderer extends EventRenderer {
     return {
       hour: 'numeric',
       minute: '2-digit',
-      // TODO: remove :00
-      // TODO: convert am/pm -> a/p
+      omitZeroTime: true,
+      meridiem: 'narrow'
     }
   }
 

+ 1 - 1
src/component/DayTableMixin.ts

@@ -161,7 +161,7 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
     if (this.rowCnt > 1 || this.colCnt > 10) {
       return { weekday: 'short' } // "Sat"
     } else if (this.colCnt > 1) {
-      return { weekday: 'short', month: 'numeric', day: 'numeric' } // "Sat 11/12"
+      return { weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true } // "Sat 11/12"
     } else {
       return { weekday: 'long' } // "Saturday"
     }

+ 3 - 3
src/component/renderers/EventRenderer.ts

@@ -275,7 +275,7 @@ export default class EventRenderer {
 
     return this._getTimeText(
       eventDateProfile.unzonedRange.start,
-      eventDateProfile.unzonedRange.end,
+      eventDateProfile.hasEnd ? eventDateProfile.unzonedRange.end : null,
       eventFootprint.componentFootprint.isAllDay,
       formatter,
       displayEnd,
@@ -321,11 +321,11 @@ export default class EventRenderer {
   }
 
 
-  computeEventTimeFormat() {
+  computeEventTimeFormat(): any {
     return {
       hour: 'numeric',
       minute: '2-digit',
-      // TODO: remove :00
+      omitZeroTime: true
     }
   }
 

+ 36 - 4
src/datelib/formatting-native.ts

@@ -8,7 +8,10 @@ import { DateFormatter, DateFormattingContext, ZonedMarker, formatTimeZoneOffset
 const DEFAULT_SEPARATOR = ' - '
 const EXTENDED_SETTINGS_AND_SEVERITIES = {
   week: 3,
-  separator: 0 // not applicable
+  separator: 0, // 0 = not applicable
+  omitZeroTime: 0,
+  meridiem: 0,
+  omitCommas: 0
 }
 const STANDARD_DATE_PROP_SEVERITIES = {
   timeZoneName: 7,
@@ -21,7 +24,8 @@ const STANDARD_DATE_PROP_SEVERITIES = {
   minute: 1,
   second: 1
 }
-
+const MERIDIEM_RE = /\s*([ap])\.?m\.?/i // eats up leading spaces too
+const COMMA_RE = /,/g // we need re for globalness
 
 export class NativeFormatter implements DateFormatter {
 
@@ -59,7 +63,7 @@ export class NativeFormatter implements DateFormatter {
   }
 
   format(date: ZonedMarker, context: DateFormattingContext, standardOverrides?) {
-    let standardSettings = standardOverrides || this.standardSettings
+    let standardSettings = assignTo({}, standardOverrides || this.standardSettings) // always copy (efficient?)
     let { extendedSettings } = this
 
     if (this.standardDatePropCnt === 1 && standardSettings.timeZoneName === 'short') {
@@ -80,10 +84,18 @@ export class NativeFormatter implements DateFormatter {
         standardSettings.timeZoneName === 'short' && date.timeZoneOffset == null
       )
     ) {
-      standardSettings = assignTo({}, standardSettings) // copy
       delete standardSettings.timeZoneName
     }
 
+    if (extendedSettings.omitZeroTime) {
+      if (standardSettings.minute && !date.marker.getUTCMinutes()) {
+        delete standardSettings.minute
+      }
+      if (standardSettings.second && !date.marker.getUTCSeconds()) {
+        delete standardSettings.second
+      }
+    }
+
     let s = date.marker.toLocaleString(context.locale.codeArg, standardSettings)
 
     if (
@@ -94,6 +106,26 @@ export class NativeFormatter implements DateFormatter {
       s = s.replace(/UTC|GMT/, formatTimeZoneOffset(date.timeZoneOffset))
     }
 
+    if (extendedSettings.meridiem === false) {
+      s = s.replace(MERIDIEM_RE, '').trim()
+    } else if (extendedSettings.meridiem === 'narrow') { // a/p
+      s = s.replace(MERIDIEM_RE, function(m0, m1) {
+        return m1.toLocaleLowerCase()
+      })
+    } else if (extendedSettings.meridiem === 'short') { // am/pm
+      s = s.replace(MERIDIEM_RE, function(m0, m1) {
+        return m1.toLocaleLowerCase() + 'm'
+      })
+    } else if (extendedSettings.meridiem === 'lowercase') { // other meridiem transformers already converted to lowercase
+      s = s.replace(MERIDIEM_RE, function(m0) {
+        return m0.toLocaleLowerCase()
+      })
+    }
+
+    if (extendedSettings.omitCommas) {
+      s = s.replace(COMMA_RE, '').trim()
+    }
+
     return s
   }
 

+ 3 - 6
src/datelib/formatting.ts

@@ -1,3 +1,4 @@
+import { padStart } from '../util/misc'
 import { DateMarker } from './marker'
 import { CalendarSystem } from './calendar-system'
 import { Locale } from './locale'
@@ -81,16 +82,12 @@ export function formatTimeZoneOffset(minutes: number, doIso = false) {
   let mins = Math.round(abs % 60)
 
   if (doIso) {
-    return sign + pad(hours) + ':' + pad(mins)
+    return sign + padStart(hours, 2) + ':' + padStart(mins, 2)
   } else {
-    return 'GMT' + sign + hours + (mins ? ':' + pad(mins) : '')
+    return 'GMT' + sign + hours + (mins ? ':' + padStart(mins, 2) : '')
   }
 }
 
-function pad(n) {
-  return n < 10 ? '0' + n : '' + n
-}
-
 
 // Arg Utils
 

+ 1 - 0
src/exports.ts

@@ -16,6 +16,7 @@ export {
 export {
   applyAll,
   debounce,
+  padStart,
   isInt,
   capitaliseFirstLetter,
   parseFieldSpecs,

+ 2 - 1
src/list/ListEventRenderer.ts

@@ -75,7 +75,8 @@ export default class ListEventRenderer extends EventRenderer {
   computeEventTimeFormat() {
     return {
       hour: 'numeric',
-      minute: '2-digit'
+      minute: '2-digit',
+      meridiem: 'short'
     }
   }
 

+ 30 - 16
src/util/misc.ts

@@ -286,7 +286,36 @@ export function warn(...args) {
 }
 
 
-/* General Utilities
+/* String Utilities
+----------------------------------------------------------------------------------------------------------------------*/
+
+
+export function capitaliseFirstLetter(str) {
+  return str.charAt(0).toUpperCase() + str.slice(1)
+}
+
+
+export function padStart(val, len) { // doesn't work with total length more than 3
+  let s = String(val)
+  return '000'.substr(0, val.length - len) + s
+}
+
+
+/* Number Utilities
+----------------------------------------------------------------------------------------------------------------------*/
+
+
+export function compareNumbers(a, b) { // for .sort()
+  return a - b
+}
+
+
+export function isInt(n) {
+  return n % 1 === 0
+}
+
+
+/* Weird Utilities
 ----------------------------------------------------------------------------------------------------------------------*/
 
 
@@ -314,21 +343,6 @@ export function firstDefined(...args) {
 }
 
 
-export function capitaliseFirstLetter(str) {
-  return str.charAt(0).toUpperCase() + str.slice(1)
-}
-
-
-export function compareNumbers(a, b) { // for .sort()
-  return a - b
-}
-
-
-export function isInt(n) {
-  return n % 1 === 0
-}
-
-
 // Returns a function, that, as long as it continues to be invoked, will not
 // be triggered. The function will be called after it stops being called for
 // N milliseconds. If `immediate` is passed, trigger the function on the