CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-moment-duration-format

A moment.js plugin for formatting durations with comprehensive template-based formatting and localization support.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

localization.mddocs/

Localization

Complete internationalization support with auto-pluralization, locale-specific number formatting, and extensible locale definitions for duration unit labels and time notation templates.

Capabilities

Locale Extension System

Moment Duration Format extends moment.js locale objects with duration-specific localization data.

/**
 * Extend moment locale with duration formatting data
 * @param locale - Locale identifier (e.g., 'en', 'de', 'fr')
 * @param localeData - Duration-specific locale configuration
 */
moment.updateLocale(locale: string, localeData: {
  durationLabelsStandard?: DurationLabels;
  durationLabelsShort?: DurationLabels;
  durationTimeTemplates?: TimeTemplates;
  durationLabelTypes?: LabelType[];
  durationPluralKey?: PluralKeyFunction;
}): void;

interface DurationLabels {
  S: string;   // millisecond singular
  SS: string;  // millisecond plural
  s: string;   // second singular
  ss: string;  // second plural
  m: string;   // minute singular
  mm: string;  // minute plural
  h: string;   // hour singular
  hh: string;  // hour plural
  d: string;   // day singular
  dd: string;  // day plural
  w: string;   // week singular
  ww: string;  // week plural
  M: string;   // month singular
  MM: string;  // month plural
  y: string;   // year singular
  yy: string;  // year plural
}

interface TimeTemplates {
  HMS: string; // hour:minute:second template
  HM: string;  // hour:minute template
  MS: string;  // minute:second template
  [key: string]: string; // custom templates
}

interface LabelType {
  type: string;   // label type name
  string: string; // replacement marker
}

type PluralKeyFunction = (
  token: string,
  integerValue: number,
  decimalValue: number | null
) => string;

Default English Locale

Built-in English locale configuration that serves as fallback for all locales.

// Default English locale extensions
moment.updateLocale('en', {
  durationLabelsStandard: {
    S: 'millisecond',
    SS: 'milliseconds',
    s: 'second',
    ss: 'seconds',
    m: 'minute',
    mm: 'minutes',
    h: 'hour',
    hh: 'hours',
    d: 'day',
    dd: 'days',
    w: 'week',
    ww: 'weeks',
    M: 'month',
    MM: 'months',
    y: 'year',
    yy: 'years'
  },
  durationLabelsShort: {
    S: 'msec',
    SS: 'msecs',
    s: 'sec',
    ss: 'secs',
    m: 'min',
    mm: 'mins',
    h: 'hr',
    hh: 'hrs',
    d: 'dy',
    dd: 'dys',
    w: 'wk',
    ww: 'wks',
    M: 'mo',
    MM: 'mos',
    y: 'yr',
    yy: 'yrs'
  },
  durationTimeTemplates: {
    HMS: 'h:mm:ss',
    HM: 'h:mm',
    MS: 'm:ss'
  },
  durationLabelTypes: [
    { type: "standard", string: "__" },
    { type: "short", string: "_" }
  ],
  durationPluralKey: function (token, integerValue, decimalValue) {
    // Singular for value of 1, but not for 1.0
    if (integerValue === 1 && decimalValue === null) {
      return token;
    }
    return token + token;
  }
});

Auto-Localization Features

Unit Label Replacement

Automatic replacement of underscore markers with localized unit labels.

Usage Examples:

// Single underscore - short labels
moment.duration(2, "minutes").format("m _");
// "2 mins"

moment.duration(1, "hour").format("h _");  
// "1 hr"

// Double underscore - standard labels
moment.duration(2, "minutes").format("m __");
// "2 minutes"

moment.duration(1, "hour").format("h __");
// "1 hour"

// Auto-pluralization
moment.duration(1, "minute").format("m __");
// "1 minute" (automatic singular)

moment.duration(2, "minutes").format("m __");
// "2 minutes" (automatic plural)

Time Notation Templates

Localized time notation patterns for common duration display formats.

Usage Examples:

// HMS - full time notation
moment.duration(3661, "seconds").format("_HMS_");
// "1:01:01"

// HM - hour:minute notation
moment.duration(3661, "seconds").format("_HM_");
// "1:01"

// MS - minute:second notation  
moment.duration(61, "seconds").format("_MS_");
// "1:01"

// Combined with other elements
moment.duration(7322, "seconds").format("_HMS_ [elapsed]");
// "2:02:02 elapsed"

Pluralization System

Intelligent pluralization based on numeric values and decimal precision.

Usage Examples:

// Integer values
moment.duration(1, "minutes").format("m [minutes]");
// "1 minute" (singular)

moment.duration(2, "minutes").format("m [minutes]");  
// "2 minutes" (plural)

moment.duration(0, "minutes").format("m [minutes]");
// "0 minutes" (plural for zero)

// Decimal values (always plural by default)
moment.duration(1, "minutes").format("m [minutes]", 2);
// "1.00 minutes" (plural due to decimal precision)

// Custom pluralization with manual labels
moment.duration(1, "minutes").format("m [minute]");
// "1 minutes" (corrected to plural automatically)

moment.duration(2, "minutes").format("m [minute]");
// "2 minutes" (corrected to plural)

Creating Custom Locales

Basic Locale Extension

Extending existing locales with duration-specific labels.

Usage Examples:

// French locale extension
moment.updateLocale('fr', {
  durationLabelsStandard: {
    S: 'milliseconde',
    SS: 'millisecondes', 
    s: 'seconde',
    ss: 'secondes',
    m: 'minute',
    mm: 'minutes',
    h: 'heure',
    hh: 'heures',
    d: 'jour',
    dd: 'jours',
    w: 'semaine',
    ww: 'semaines',
    M: 'mois',
    MM: 'mois',
    y: 'année',
    yy: 'années'
  },
  durationLabelsShort: {
    S: 'ms',
    SS: 'ms',
    s: 'sec',
    ss: 'sec',
    m: 'min',
    mm: 'min', 
    h: 'h',
    hh: 'h',
    d: 'j',
    dd: 'j',
    w: 'sem',
    ww: 'sem',
    M: 'mois',
    MM: 'mois',
    y: 'an',
    yy: 'ans'
  }
});

// Using French locale
moment.locale('fr');
moment.duration(2, "minutes").format("m __");
// "2 minutes"

moment.duration(1, "hour").format("h _");
// "1 h"

Advanced Locale with Custom Pluralization

Complex locale with multiple plural forms and custom time templates.

Usage Examples:

// Example: Custom locale with three plural forms
moment.updateLocale('sample', {
  durationLabelsLong: {
    s: 'singular long second',
    ss: 'first plural long seconds', 
    sss: 'many plural long seconds'
  },
  durationLabelsStandard: {
    s: 'singular second',
    ss: 'first plural seconds',
    sss: 'many plural seconds'
  },
  durationLabelsShort: {
    s: 'singular sec',
    ss: 'first plural secs',
    sss: 'many plural secs'
  },
  durationTimeTemplates: {
    HMS: 'h[h]:mm[m]:ss[s]',  // Custom time template
    HS: 'hh[h].ssss[s]'       // Custom template
  },
  durationLabelTypes: [
    { type: "long", string: "___" },     // Triple underscore
    { type: "standard", string: "__" },   // Double underscore  
    { type: "short", string: "_" }        // Single underscore
  ],
  durationPluralKey: function (token, integerValue, decimalValue) {
    // Custom pluralization logic
    if (integerValue === 1 && decimalValue === null) {
      return token;           // "s" for exactly 1
    } else if (integerValue === 2) {
      return token + token;   // "ss" for exactly 2
    } else {
      return token + token + token;  // "sss" for all others
    }
  }
});

// Using custom locale
moment.locale('sample');
moment.duration(1, "second").format("s ___");
// "1 singular long second"

moment.duration(2, "seconds").format("s ___");  
// "2 first plural long seconds"

moment.duration(5, "seconds").format("s ___");
// "5 many plural long seconds"

Custom Time Templates

Adding specialized time notation templates to locales.

Usage Examples:

// Add custom time templates
moment.updateLocale('en', {
  durationTimeTemplates: {
    HMS: 'h:mm:ss',
    HM: 'h:mm', 
    MS: 'm:ss',
    DHMS: 'd[d] h:mm:ss',    // Custom: days + time
    PRECISION: 'h:mm:ss.SSS' // Custom: with milliseconds
  }
});

// Using custom templates
moment.duration(90061, "seconds").format("_DHMS_");
// "1d 1:01:01"

moment.duration(3661789, "milliseconds").format("_PRECISION_");
// "1:01:01.789"

Locale-Specific Number Formatting

User Locale Setting

Override moment locale for numerical formatting only.

Usage Examples:

// Using German locale for numbers, English for labels
moment.locale('en');  // English labels
moment.duration(1234567, "seconds").format({ 
  template: "m [minutes]",
  precision: 3,
  userLocale: "de-DE"  // German number formatting
});
// "20.576,117 minutes"

// Compare with English number formatting
moment.duration(1234567, "seconds").format({ 
  template: "m [minutes]",
  precision: 3,
  userLocale: "en-US"
});
// "20,576.117 minutes"

Locale Detection and Fallback

Automatic fallback to English locale when duration extensions are missing.

Usage Examples:

// Set moment to unsupported locale
moment.locale('xyz-unknown');

// Duration formatting falls back to English
moment.duration(2, "minutes").format("m __");
// "2 minutes" (English fallback)

// But uses locale for number formatting if available
moment.duration(1234, "seconds").format("s [seconds]");
// Number formatting may vary based on system locale

Pluralization Function Details

Plural Key Function Interface

Function signature for custom pluralization logic.

/**
 * Determines the appropriate label key for a duration value
 * @param token - Single character unit token (s, m, h, d, w, M, y, S)
 * @param integerValue - Integer portion of the duration value
 * @param decimalValue - Decimal portion (null if no decimal part)
 * @returns Label key to use for lookup (e.g., "s", "ss", "sss")
 */
type PluralKeyFunction = (
  token: string,
  integerValue: number, 
  decimalValue: number | null
) => string;

Usage Examples:

// Default English pluralization
function englishPluralKey(token, integerValue, decimalValue) {
  // Singular only for exactly 1 with no decimal
  if (integerValue === 1 && decimalValue === null) {
    return token;        // "s" -> singular label
  }
  return token + token;  // "ss" -> plural label
}

// Custom: Slavic-style pluralization  
function slavicPluralKey(token, integerValue, decimalValue) {
  // Complex Slavic plural rules (simplified example)
  if (integerValue === 1 && decimalValue === null) {
    return token;                    // 1 -> singular
  } else if (integerValue >= 2 && integerValue <= 4) {
    return token + token;            // 2-4 -> first plural
  } else {
    return token + token + token;    // 5+ -> second plural  
  }
}

// Custom: Always plural
function alwaysPluralKey(token, integerValue, decimalValue) {
  return token + token;  // Always use plural form
}

Integration with Label Types

Pluralization works in conjunction with label types for complete localization.

Usage Examples:

// Set up locale with multiple label types and custom pluralization
moment.updateLocale('multi', {
  durationLabelsVerbose: {
    s: 'one verbose second',
    ss: 'few verbose seconds',
    sss: 'many verbose seconds'
  },
  durationLabelsStandard: {
    s: 'one second', 
    ss: 'few seconds',
    sss: 'many seconds'
  },
  durationLabelsShort: {
    s: 'one sec',
    ss: 'few secs', 
    sss: 'many secs'
  },
  durationLabelTypes: [
    { type: "verbose", string: "____" },  // 4 underscores
    { type: "standard", string: "__" },   // 2 underscores
    { type: "short", string: "_" }        // 1 underscore
  ],
  durationPluralKey: function(token, integerValue, decimalValue) {
    if (integerValue === 1 && decimalValue === null) return token;
    if (integerValue >= 2 && integerValue <= 4) return token + token;
    return token + token + token;
  }
});

// Using different label types with pluralization
moment.locale('multi');
moment.duration(1, "second").format("s ____");   // "1 one verbose second"
moment.duration(3, "seconds").format("s ____");  // "3 few verbose seconds"  
moment.duration(7, "seconds").format("s ____");  // "7 many verbose seconds"

docs

configuration-settings.md

duration-formatting.md

index.md

localization.md

multiple-duration-formatting.md

template-system.md

tile.json