Jelajahi Sumber

formatter getunit

Adam Shaw 7 tahun lalu
induk
melakukan
9561756525
4 mengubah file dengan 74 tambahan dan 30 penghapusan
  1. 8 0
      src/datelib/duration.ts
  2. 23 6
      src/datelib/env.ts
  3. 41 23
      src/datelib/formatting-native.ts
  4. 2 1
      src/exports.ts

+ 8 - 0
src/datelib/duration.ts

@@ -129,6 +129,14 @@ export function multiplyDuration(d: Duration, n: number) {
 // Conversions
 // Conversions
 // "Rough" because they are based on average-case Gregorian months/years
 // "Rough" because they are based on average-case Gregorian months/years
 
 
+export function asRoughYears(dur: Duration) {
+  return asRoughDays(dur) / 365
+}
+
+export function asRoughMonths(dur: Duration) {
+  return asRoughDays(dur) / 30
+}
+
 export function asRoughDays(dur: Duration) {
 export function asRoughDays(dur: Duration) {
   return asRoughMs(dur) / 864e5
   return asRoughMs(dur) / 864e5
 }
 }

+ 23 - 6
src/datelib/env.ts

@@ -7,7 +7,7 @@ import {
 import { CalendarSystem, createCalendarSystem } from './calendar-system'
 import { CalendarSystem, createCalendarSystem } from './calendar-system'
 import { Locale } from './locale'
 import { Locale } from './locale'
 import { NamedTimeZoneImpl, createNamedTimeZoneImpl } from './timezone'
 import { NamedTimeZoneImpl, createNamedTimeZoneImpl } from './timezone'
-import { Duration } from './duration'
+import { Duration, asRoughYears, asRoughMonths, asRoughDays, asRoughMs } from './duration'
 import { DateFormatter, buildIsoString } from './formatting'
 import { DateFormatter, buildIsoString } from './formatting'
 import { parse } from './parsing'
 import { parse } from './parsing'
 import { isInt } from '../util/misc'
 import { isInt } from '../util/misc'
@@ -241,14 +241,31 @@ export class DateEnv {
   }
   }
 
 
   countDurationsBetween(m0: DateMarker, m1: DateMarker, d: Duration) {
   countDurationsBetween(m0: DateMarker, m1: DateMarker, d: Duration) {
-    let cnt = 0
+    // TODO: can use greatestWholeUnit
+    let diff
 
 
-    while (m0 < m1) { // better way to do this without iterating?
-      m0 = this.add(m0, d)
-      cnt++
+    if (d.year) {
+      diff = this.diffWholeYears(m0, m1)
+      if (diff !== null) {
+        return diff / asRoughYears(d)
+      }
+    }
+
+    if (d.month) {
+      diff = this.diffWholeMonths(m0, m1)
+      if (diff !== null) {
+        return diff / asRoughMonths(d)
+      }
+    }
+
+    if (d.day) {
+      diff = diffWholeDays(m0, m1)
+      if (diff !== null) {
+        return diff / asRoughDays(d)
+      }
     }
     }
 
 
-    return cnt
+    return (m1.valueOf() - m0.valueOf()) / asRoughMs(d)
   }
   }
 
 
 
 

+ 41 - 23
src/datelib/formatting-native.ts

@@ -5,11 +5,21 @@ import { Locale } from './locale'
 import { DateFormatter, DateFormattingContext, ZonedMarker, formatTimeZoneOffset } from './formatting'
 import { DateFormatter, DateFormattingContext, ZonedMarker, formatTimeZoneOffset } from './formatting'
 
 
 
 
-const STANDARD_DATE_PROP_RE = /^(weekday|era|year|month|day|hour|minute|second|timeZoneName)$/
 const DEFAULT_SEPARATOR = ' - '
 const DEFAULT_SEPARATOR = ' - '
-const EXTENDED_SETTINGS = {
-  week: true,
-  separator: true
+const EXTENDED_SETTINGS_AND_SEVERITIES = {
+  week: 3,
+  separator: 0 // not applicable
+}
+const STANDARD_DATE_PROP_SEVERITIES = {
+  timeZoneName: 7,
+  era: 6,
+  year: 5,
+  month: 4,
+  day: 2,
+  weekday: 2,
+  hour: 1,
+  minute: 1,
+  second: 1
 }
 }
 
 
 
 
@@ -18,20 +28,24 @@ export class NativeFormatter implements DateFormatter {
   standardSettings: any
   standardSettings: any
   standardDatePropCnt: number
   standardDatePropCnt: number
   extendedSettings: any
   extendedSettings: any
+  severity: number
 
 
   constructor(formatSettings) {
   constructor(formatSettings) {
     let standardSettings: any = {}
     let standardSettings: any = {}
     let extendedSettings: any = {}
     let extendedSettings: any = {}
     let standardDatePropCnt = 0
     let standardDatePropCnt = 0
+    let severity = 0
 
 
     for (let name in formatSettings) {
     for (let name in formatSettings) {
-      if (EXTENDED_SETTINGS[name]) {
+      if (name in EXTENDED_SETTINGS_AND_SEVERITIES) {
         extendedSettings[name] = formatSettings[name]
         extendedSettings[name] = formatSettings[name]
+        severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name], severity)
       } else {
       } else {
         standardSettings[name] = formatSettings[name]
         standardSettings[name] = formatSettings[name]
 
 
-        if (STANDARD_DATE_PROP_RE.test(name)) {
+        if (name in STANDARD_DATE_PROP_SEVERITIES) {
           standardDatePropCnt++
           standardDatePropCnt++
+          severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name], severity)
         }
         }
       }
       }
     }
     }
@@ -41,6 +55,7 @@ export class NativeFormatter implements DateFormatter {
     this.standardSettings = standardSettings
     this.standardSettings = standardSettings
     this.standardDatePropCnt = standardDatePropCnt
     this.standardDatePropCnt = standardDatePropCnt
     this.extendedSettings = extendedSettings
     this.extendedSettings = extendedSettings
+    this.severity = severity
   }
   }
 
 
   format(date: ZonedMarker, context: DateFormattingContext, standardOverrides?) {
   format(date: ZonedMarker, context: DateFormattingContext, standardOverrides?) {
@@ -121,6 +136,21 @@ export class NativeFormatter implements DateFormatter {
     return full0 + separator + full1
     return full0 + separator + full1
   }
   }
 
 
+  getLargestUnit() {
+    switch (this.severity) {
+      case 7:
+      case 6:
+      case 5:
+        return 'year'
+      case 4:
+        return 'month'
+      case 3:
+        return 'week'
+      default:
+        return 'day'
+    }
+  }
+
 }
 }
 
 
 
 
@@ -146,27 +176,15 @@ function formatWeekNumber(num: number, locale: Locale, display?: 'numeric' | 'na
 
 
 // Range Formatting Utils
 // Range Formatting Utils
 
 
-const SEVERITIES_FOR_PARTS = {
-  year: 4,
-  month: 3,
-  day: 2,
-  weekday: 2,
-  hour: 1,
-  minute: 1,
-  second: 1
-}
-
 // 0 = exactly the same
 // 0 = exactly the same
 // 1 = different by time
 // 1 = different by time
-// 2 = different by day
-// 3 = different by month
-// 4 = different by year
+// and bigger
 function computeMarkerDiffSeverity(d0: DateMarker, d1: DateMarker, ca: CalendarSystem) {
 function computeMarkerDiffSeverity(d0: DateMarker, d1: DateMarker, ca: CalendarSystem) {
   if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) {
   if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) {
-    return 4
+    return 5
   }
   }
   if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) {
   if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) {
-    return 3
+    return 4
   }
   }
   if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) {
   if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) {
     return 2
     return 2
@@ -182,8 +200,8 @@ function computePartialFormattingOptions(options, biggestUnit) {
 
 
   for (let name in options) {
   for (let name in options) {
     if (
     if (
-      name === 'timeZone' ||
-      SEVERITIES_FOR_PARTS[name] <= biggestUnit // if undefined, will always be false
+      !(name in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone)
+      STANDARD_DATE_PROP_SEVERITIES[name] <= biggestUnit
     ) {
     ) {
       partialOptions[name] = options[name]
       partialOptions[name] = options[name]
     }
     }

+ 2 - 1
src/exports.ts

@@ -117,6 +117,7 @@ export { default as DayGrid } from './basic/DayGrid'
 export { default as BasicView } from './basic/BasicView'
 export { default as BasicView } from './basic/BasicView'
 export { default as MonthView } from './basic/MonthView'
 export { default as MonthView } from './basic/MonthView'
 export { default as ListView } from './list/ListView'
 export { default as ListView } from './list/ListView'
+export { DateProfile } from './DateProfileGenerator'
 
 
 export { DateMarker, addDays, startOfDay, addMs, diffWholeWeeks, diffWholeDays, diffDayAndTime } from './datelib/marker'
 export { DateMarker, addDays, startOfDay, addMs, diffWholeWeeks, diffWholeDays, diffDayAndTime } from './datelib/marker'
 export {
 export {
@@ -127,4 +128,4 @@ export {
 } from './datelib/duration'
 } from './datelib/duration'
 export { DateEnv } from './datelib/env'
 export { DateEnv } from './datelib/env'
 export { defineLocale, getLocale, getLocaleCodes } from './datelib/locale'
 export { defineLocale, getLocale, getLocaleCodes } from './datelib/locale'
-export { createFormatter } from './datelib/formatting'
+export { DateFormatter, createFormatter } from './datelib/formatting'