`DateAdapter#format` type declaration error
- Dominant language
- JavaScript
- Stars
- 67.7k
- Forks
- 11.9k
- Avg merge
- 7h 39m
- Merged PRs (30d)
- 5
Description
### Expected behavior
The type declaration `DateAdapter#format` contains an error
https://github.com/chartjs/Chart.js/blob/c0bf05f87df431202c991cfb5f3ee34106d9b6f4/src/core/core.adapters.ts#L34
Here, `format` (3rd param) is of type whatever `DateAdapter#formats` return, not `TimeUnit`
---
Additional problems:
- `options` should not be of type `T` but whatever the adapter wants it to be
- `init` should be optional
- Maybe `diff` should not exist `diff(a, b, unit) <=> add(a, -b, unit)`
- `endOf` might writable as a combination of `add` and `startOf`
### Current behavior
N/A
### Reproducible sample
N/A
### Optional extra steps/info to reproduce
_No response_
### Possible solution
_No response_
### Context
I'm currently implementing a native date adapter (with `Intl.DateTimeFormat` and the likes)
WIP
```ts
import type { DateAdapter } from 'chart.js';
/**
* Adapter to work with Time Cartesian Axis, without dependencies.
*
* @see https://www.chartjs.org/docs/next/axes/cartesian/time.html
*/
export default {
options: new Date(),
init() {},
add(timestamp, amount, unit) {
switch (unit) {
case 'millisecond': {
return timestamp + amount;
}
case 'second': {
return timestamp + amount * 1000;
}
case 'minute': {
return timestamp + amount * 1000 * 60;
}
case 'hour': {
return timestamp + amount * 1000 * 60 * 60;
}
case 'day': {
return timestamp + amount * 1000 * 60 * 60 * 24;
}
case 'week': {
return timestamp + amount * 1000 * 60 * 60 * 24 * 7;
}
// Starting with month, units become irregular
case 'month': {
const source = new Date(timestamp);
return new Date(
source.getFullYear(),
source.getMonth() + amount,
source.getDate(),
source.getHours(),
source.getMinutes(),
source.getSeconds(),
source.getMilliseconds()
).getTime();
}
case 'quarter': {
const source = new Date(timestamp);
return new Date(
source.getFullYear(),
source.getMonth() + amount * 3,
source.getDate(),
source.getHours(),
source.getMinutes(),
source.getSeconds(),
source.getMilliseconds()
).getTime();
}
case 'year': {
const source = new Date(timestamp);
return new Date(
source.getFullYear() + amount,
source.getMonth(),
source.getDate(),
source.getHours(),
source.getMinutes(),
source.getSeconds(),
source.getMilliseconds()
).getTime();
}
}
},
diff(a, b, unit) {
return this.add(a, -b, unit);
},
startOf(timestamp, unit, startOfWeek) {
switch (unit) {
case 'millisecond': {
return timestamp;
}
case 'second': {
return timestamp - (timestamp % 1000);
}
case 'minute': {
const source = new Date(timestamp);
return new Date(
source.getFullYear(),
source.getMonth(),
source.getDate(),
source.getHours(),
source.getMinutes()
).getTime();
}
case 'hour': {
const source = new Date(timestamp);
return new Date(
source.getFullYear(),
source.getMonth(),
source.getDate(),
source.getHours()
).getTime();
}
case 'day': {
const source = new Date(timestamp);
return new Date(source.getFullYear(), source.getMonth(), source.getDate()).getTime();
}
case 'week': {
const source = new Date(timestamp);
return new Date(
source.getFullYear(),
source.getMonth(),
source.getDate() - source.getDay()
).getTime();
}
case 'quarter': {
const source = new Date(timestamp);
return new Date(source.getFullYear(), Math.floor(source.getMonth() / 3) * 3, 1).getTime();
}
case 'month': {
const source = new Date(timestamp);
return new Date(source.getFullYear(), source.getMonth(), 1).getTime();
}
case 'year': {
const source = new Date(timestamp);
return new Date(source.getFullYear(), 0, 1).getTime();
}
case 'isoWeek': {
const source = new Date(timestamp);
return new Date(
source.getFullYear(),
source.getMonth(),
source.getDate() - source.getDay() + (startOfWeek ?? 1)
).getTime();
}
}
},
endOf(timestamp, unit) {
if (unit === 'isoWeek') return this.add(this.startOf(timestamp, unit, 1), 1, 'week') - 1;
return this.add(this.startOf(timestamp, unit), 1, unit) - 1;
},
parse: (value) => new Date(value as string).getTime(),
// Type declarations are broken, see https://github.com/chartjs/Chart.js/issues/11199
formats: () => formatters as unknown as Record,
format: (timestamp, formatter) => (formatter as unknown as Intl.DateTimeFormat).format(timestamp),
} satisfies DateAdapter;
export const formatters = {
millisecond: new Intl.DateTimeFormat('en-US', {
second: 'numeric',
fractionalSecondDigits: 3,
}),
second: new Intl.DateTimeFormat('en-US', { minute: 'numeric', second: '2-digit' }),
minute: new Intl.DateTimeFormat('en-US', { hour: 'numeric', minute: '2-digit' }),
hour: new Intl.DateTimeFormat('en-US', { hour: 'numeric', minute: '2-digit' }),
day: new Intl.DateTimeFormat('en-US', { month: 'short', day: 'numeric' }),
week: new Intl.DateTimeFormat('en-US', { month: 'short', day: 'numeric' }),
month: new Intl.DateTimeFormat('en-US', { month: 'short', year: 'numeric' }),
quarter: new Intl.DateTimeFormat('en-US', { month: 'short', year: 'numeric' }),
year: new Intl.DateTimeFormat('en-US', { year: 'numeric' }),
datetime: new Intl.DateTimeFormat('en-US', { dateStyle: 'medium', timeStyle: 'short' }),
} satisfies Record;
```
### chart.js version
master
### Browser name and version
_No response_
### Link to your project
_No response_
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.