or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration-settings.mdduration-formatting.mdindex.mdlocalization.mdmultiple-duration-formatting.mdtemplate-system.md

localization.mddocs/

0

# Localization

1

2

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

3

4

## Capabilities

5

6

### Locale Extension System

7

8

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

9

10

```javascript { .api }

11

/**

12

* Extend moment locale with duration formatting data

13

* @param locale - Locale identifier (e.g., 'en', 'de', 'fr')

14

* @param localeData - Duration-specific locale configuration

15

*/

16

moment.updateLocale(locale: string, localeData: {

17

durationLabelsStandard?: DurationLabels;

18

durationLabelsShort?: DurationLabels;

19

durationTimeTemplates?: TimeTemplates;

20

durationLabelTypes?: LabelType[];

21

durationPluralKey?: PluralKeyFunction;

22

}): void;

23

24

interface DurationLabels {

25

S: string; // millisecond singular

26

SS: string; // millisecond plural

27

s: string; // second singular

28

ss: string; // second plural

29

m: string; // minute singular

30

mm: string; // minute plural

31

h: string; // hour singular

32

hh: string; // hour plural

33

d: string; // day singular

34

dd: string; // day plural

35

w: string; // week singular

36

ww: string; // week plural

37

M: string; // month singular

38

MM: string; // month plural

39

y: string; // year singular

40

yy: string; // year plural

41

}

42

43

interface TimeTemplates {

44

HMS: string; // hour:minute:second template

45

HM: string; // hour:minute template

46

MS: string; // minute:second template

47

[key: string]: string; // custom templates

48

}

49

50

interface LabelType {

51

type: string; // label type name

52

string: string; // replacement marker

53

}

54

55

type PluralKeyFunction = (

56

token: string,

57

integerValue: number,

58

decimalValue: number | null

59

) => string;

60

```

61

62

### Default English Locale

63

64

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

65

66

```javascript { .api }

67

// Default English locale extensions

68

moment.updateLocale('en', {

69

durationLabelsStandard: {

70

S: 'millisecond',

71

SS: 'milliseconds',

72

s: 'second',

73

ss: 'seconds',

74

m: 'minute',

75

mm: 'minutes',

76

h: 'hour',

77

hh: 'hours',

78

d: 'day',

79

dd: 'days',

80

w: 'week',

81

ww: 'weeks',

82

M: 'month',

83

MM: 'months',

84

y: 'year',

85

yy: 'years'

86

},

87

durationLabelsShort: {

88

S: 'msec',

89

SS: 'msecs',

90

s: 'sec',

91

ss: 'secs',

92

m: 'min',

93

mm: 'mins',

94

h: 'hr',

95

hh: 'hrs',

96

d: 'dy',

97

dd: 'dys',

98

w: 'wk',

99

ww: 'wks',

100

M: 'mo',

101

MM: 'mos',

102

y: 'yr',

103

yy: 'yrs'

104

},

105

durationTimeTemplates: {

106

HMS: 'h:mm:ss',

107

HM: 'h:mm',

108

MS: 'm:ss'

109

},

110

durationLabelTypes: [

111

{ type: "standard", string: "__" },

112

{ type: "short", string: "_" }

113

],

114

durationPluralKey: function (token, integerValue, decimalValue) {

115

// Singular for value of 1, but not for 1.0

116

if (integerValue === 1 && decimalValue === null) {

117

return token;

118

}

119

return token + token;

120

}

121

});

122

```

123

124

## Auto-Localization Features

125

126

### Unit Label Replacement

127

128

Automatic replacement of underscore markers with localized unit labels.

129

130

**Usage Examples:**

131

132

```javascript

133

// Single underscore - short labels

134

moment.duration(2, "minutes").format("m _");

135

// "2 mins"

136

137

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

138

// "1 hr"

139

140

// Double underscore - standard labels

141

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

142

// "2 minutes"

143

144

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

145

// "1 hour"

146

147

// Auto-pluralization

148

moment.duration(1, "minute").format("m __");

149

// "1 minute" (automatic singular)

150

151

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

152

// "2 minutes" (automatic plural)

153

```

154

155

### Time Notation Templates

156

157

Localized time notation patterns for common duration display formats.

158

159

**Usage Examples:**

160

161

```javascript

162

// HMS - full time notation

163

moment.duration(3661, "seconds").format("_HMS_");

164

// "1:01:01"

165

166

// HM - hour:minute notation

167

moment.duration(3661, "seconds").format("_HM_");

168

// "1:01"

169

170

// MS - minute:second notation

171

moment.duration(61, "seconds").format("_MS_");

172

// "1:01"

173

174

// Combined with other elements

175

moment.duration(7322, "seconds").format("_HMS_ [elapsed]");

176

// "2:02:02 elapsed"

177

```

178

179

### Pluralization System

180

181

Intelligent pluralization based on numeric values and decimal precision.

182

183

**Usage Examples:**

184

185

```javascript

186

// Integer values

187

moment.duration(1, "minutes").format("m [minutes]");

188

// "1 minute" (singular)

189

190

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

191

// "2 minutes" (plural)

192

193

moment.duration(0, "minutes").format("m [minutes]");

194

// "0 minutes" (plural for zero)

195

196

// Decimal values (always plural by default)

197

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

198

// "1.00 minutes" (plural due to decimal precision)

199

200

// Custom pluralization with manual labels

201

moment.duration(1, "minutes").format("m [minute]");

202

// "1 minutes" (corrected to plural automatically)

203

204

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

205

// "2 minutes" (corrected to plural)

206

```

207

208

## Creating Custom Locales

209

210

### Basic Locale Extension

211

212

Extending existing locales with duration-specific labels.

213

214

**Usage Examples:**

215

216

```javascript

217

// French locale extension

218

moment.updateLocale('fr', {

219

durationLabelsStandard: {

220

S: 'milliseconde',

221

SS: 'millisecondes',

222

s: 'seconde',

223

ss: 'secondes',

224

m: 'minute',

225

mm: 'minutes',

226

h: 'heure',

227

hh: 'heures',

228

d: 'jour',

229

dd: 'jours',

230

w: 'semaine',

231

ww: 'semaines',

232

M: 'mois',

233

MM: 'mois',

234

y: 'année',

235

yy: 'années'

236

},

237

durationLabelsShort: {

238

S: 'ms',

239

SS: 'ms',

240

s: 'sec',

241

ss: 'sec',

242

m: 'min',

243

mm: 'min',

244

h: 'h',

245

hh: 'h',

246

d: 'j',

247

dd: 'j',

248

w: 'sem',

249

ww: 'sem',

250

M: 'mois',

251

MM: 'mois',

252

y: 'an',

253

yy: 'ans'

254

}

255

});

256

257

// Using French locale

258

moment.locale('fr');

259

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

260

// "2 minutes"

261

262

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

263

// "1 h"

264

```

265

266

### Advanced Locale with Custom Pluralization

267

268

Complex locale with multiple plural forms and custom time templates.

269

270

**Usage Examples:**

271

272

```javascript

273

// Example: Custom locale with three plural forms

274

moment.updateLocale('sample', {

275

durationLabelsLong: {

276

s: 'singular long second',

277

ss: 'first plural long seconds',

278

sss: 'many plural long seconds'

279

},

280

durationLabelsStandard: {

281

s: 'singular second',

282

ss: 'first plural seconds',

283

sss: 'many plural seconds'

284

},

285

durationLabelsShort: {

286

s: 'singular sec',

287

ss: 'first plural secs',

288

sss: 'many plural secs'

289

},

290

durationTimeTemplates: {

291

HMS: 'h[h]:mm[m]:ss[s]', // Custom time template

292

HS: 'hh[h].ssss[s]' // Custom template

293

},

294

durationLabelTypes: [

295

{ type: "long", string: "___" }, // Triple underscore

296

{ type: "standard", string: "__" }, // Double underscore

297

{ type: "short", string: "_" } // Single underscore

298

],

299

durationPluralKey: function (token, integerValue, decimalValue) {

300

// Custom pluralization logic

301

if (integerValue === 1 && decimalValue === null) {

302

return token; // "s" for exactly 1

303

} else if (integerValue === 2) {

304

return token + token; // "ss" for exactly 2

305

} else {

306

return token + token + token; // "sss" for all others

307

}

308

}

309

});

310

311

// Using custom locale

312

moment.locale('sample');

313

moment.duration(1, "second").format("s ___");

314

// "1 singular long second"

315

316

moment.duration(2, "seconds").format("s ___");

317

// "2 first plural long seconds"

318

319

moment.duration(5, "seconds").format("s ___");

320

// "5 many plural long seconds"

321

```

322

323

### Custom Time Templates

324

325

Adding specialized time notation templates to locales.

326

327

**Usage Examples:**

328

329

```javascript

330

// Add custom time templates

331

moment.updateLocale('en', {

332

durationTimeTemplates: {

333

HMS: 'h:mm:ss',

334

HM: 'h:mm',

335

MS: 'm:ss',

336

DHMS: 'd[d] h:mm:ss', // Custom: days + time

337

PRECISION: 'h:mm:ss.SSS' // Custom: with milliseconds

338

}

339

});

340

341

// Using custom templates

342

moment.duration(90061, "seconds").format("_DHMS_");

343

// "1d 1:01:01"

344

345

moment.duration(3661789, "milliseconds").format("_PRECISION_");

346

// "1:01:01.789"

347

```

348

349

## Locale-Specific Number Formatting

350

351

### User Locale Setting

352

353

Override moment locale for numerical formatting only.

354

355

**Usage Examples:**

356

357

```javascript

358

// Using German locale for numbers, English for labels

359

moment.locale('en'); // English labels

360

moment.duration(1234567, "seconds").format({

361

template: "m [minutes]",

362

precision: 3,

363

userLocale: "de-DE" // German number formatting

364

});

365

// "20.576,117 minutes"

366

367

// Compare with English number formatting

368

moment.duration(1234567, "seconds").format({

369

template: "m [minutes]",

370

precision: 3,

371

userLocale: "en-US"

372

});

373

// "20,576.117 minutes"

374

```

375

376

### Locale Detection and Fallback

377

378

Automatic fallback to English locale when duration extensions are missing.

379

380

**Usage Examples:**

381

382

```javascript

383

// Set moment to unsupported locale

384

moment.locale('xyz-unknown');

385

386

// Duration formatting falls back to English

387

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

388

// "2 minutes" (English fallback)

389

390

// But uses locale for number formatting if available

391

moment.duration(1234, "seconds").format("s [seconds]");

392

// Number formatting may vary based on system locale

393

```

394

395

## Pluralization Function Details

396

397

### Plural Key Function Interface

398

399

Function signature for custom pluralization logic.

400

401

```javascript { .api }

402

/**

403

* Determines the appropriate label key for a duration value

404

* @param token - Single character unit token (s, m, h, d, w, M, y, S)

405

* @param integerValue - Integer portion of the duration value

406

* @param decimalValue - Decimal portion (null if no decimal part)

407

* @returns Label key to use for lookup (e.g., "s", "ss", "sss")

408

*/

409

type PluralKeyFunction = (

410

token: string,

411

integerValue: number,

412

decimalValue: number | null

413

) => string;

414

```

415

416

**Usage Examples:**

417

418

```javascript

419

// Default English pluralization

420

function englishPluralKey(token, integerValue, decimalValue) {

421

// Singular only for exactly 1 with no decimal

422

if (integerValue === 1 && decimalValue === null) {

423

return token; // "s" -> singular label

424

}

425

return token + token; // "ss" -> plural label

426

}

427

428

// Custom: Slavic-style pluralization

429

function slavicPluralKey(token, integerValue, decimalValue) {

430

// Complex Slavic plural rules (simplified example)

431

if (integerValue === 1 && decimalValue === null) {

432

return token; // 1 -> singular

433

} else if (integerValue >= 2 && integerValue <= 4) {

434

return token + token; // 2-4 -> first plural

435

} else {

436

return token + token + token; // 5+ -> second plural

437

}

438

}

439

440

// Custom: Always plural

441

function alwaysPluralKey(token, integerValue, decimalValue) {

442

return token + token; // Always use plural form

443

}

444

```

445

446

### Integration with Label Types

447

448

Pluralization works in conjunction with label types for complete localization.

449

450

**Usage Examples:**

451

452

```javascript

453

// Set up locale with multiple label types and custom pluralization

454

moment.updateLocale('multi', {

455

durationLabelsVerbose: {

456

s: 'one verbose second',

457

ss: 'few verbose seconds',

458

sss: 'many verbose seconds'

459

},

460

durationLabelsStandard: {

461

s: 'one second',

462

ss: 'few seconds',

463

sss: 'many seconds'

464

},

465

durationLabelsShort: {

466

s: 'one sec',

467

ss: 'few secs',

468

sss: 'many secs'

469

},

470

durationLabelTypes: [

471

{ type: "verbose", string: "____" }, // 4 underscores

472

{ type: "standard", string: "__" }, // 2 underscores

473

{ type: "short", string: "_" } // 1 underscore

474

],

475

durationPluralKey: function(token, integerValue, decimalValue) {

476

if (integerValue === 1 && decimalValue === null) return token;

477

if (integerValue >= 2 && integerValue <= 4) return token + token;

478

return token + token + token;

479

}

480

});

481

482

// Using different label types with pluralization

483

moment.locale('multi');

484

moment.duration(1, "second").format("s ____"); // "1 one verbose second"

485

moment.duration(3, "seconds").format("s ____"); // "3 few verbose seconds"

486

moment.duration(7, "seconds").format("s ____"); // "7 many verbose seconds"

487

```