Skip to content

feat: extend math engine: currencies, timezones, finance, cooking#715

Merged
antonreshetov merged 33 commits intomainfrom
feat/math-new-features
Mar 29, 2026
Merged

feat: extend math engine: currencies, timezones, finance, cooking#715
antonreshetov merged 33 commits intomainfrom
feat/math-new-features

Conversation

@antonreshetov
Copy link
Copy Markdown
Member

No description provided.

- `workdays in 3 weeks` → 15 workdays
- `workdays from April 12 to June 15` → N workdays
- `March 3 to March 7 in workdays` → N workdays
- `2 workdays after March 3` → date
- `date to timestamp` → unix timestamp
- `date as iso8601` → ISO 8601 string
- `2019-04-01T15:30:00 to date` → parsed date
- `1733823083000 to date` → millisecond timestamp auto-detection
…in, time difference

- Airport codes: LAX, JFK, SYD, NRT, CDG, FRA, etc.
- Country names: Japan, Germany, Thailand, etc.
- City aliases: Seattle, Boston, Miami, etc.
- `date in Vancouver` → date-only display in timezone
- `time difference between Seattle and Moscow` → hours
- `difference between PDT & AEST` → hours
- `5.5 minutes as timespan` → 5 min 30 s
- `72 days as timespan` → 10 weeks 2 days
- `5.5 minutes as laptime` → 00:05:30
- `3h 5m 10s` shorthand input → stacked time units
- `03:04:05` laptime input → parsed as hours + minutes + seconds
- Laptime arithmetic: `03:04:05 + 01:02:03 as laptime` → 04:06:08
- `7:30 to 20:45` → 13 hours 15 min
- `4pm to 3am` → 11 hours (wraps around midnight)
- `9am to 5pm` → 8 hours
- Rounding: negative numbers, to 0 dp, to nearest 1, pi to 10 digits
- Fix: 'to N dp' now preserves N digits in output (not capped by default precision)
- Percentages: 0%, 100%, 200%, edge cases
- Fractions: 0.25 as fraction, -0.5 as fraction
- Multipliers: 0x, fractional multiplier
- Currency: euros/rubles words, implicit rate with EUR, reverse order
- Format directives: 0 in hex/bin, 0.001 in sci, mixed hex+bin input
- Conditionals: if with and, expression in condition, expression in postfix if
- Calendar: Q1/Q2/Q4, 0 days between, months/years from now/ago
- Clock intervals: midnight crossing, 12am/12pm, same time
- Timespans: 0 seconds, 1.5 hours, singular form
- min/max, half, midpoint, random, gcd/lcm
- permutations/combinations, clamp, proportions (rule of three)
- Timecode format HH:MM:SS:FF with `at/@ N fps` (default 24 fps)
- `frame`/`frames` and `fps` units registered in math.js
- Timecode → frames conversion: `00:30:10:00 @ 24 fps in frames`
- Timecode arithmetic: `03:10:20:05 at 30 fps + 50 frames`
- fps calculations: `30 fps * 3 minutes`
- Compound interest: yearly/monthly/quarterly compounding
- Interest only, ROI, annual return, present value
- Mortgage: daily/monthly/annual/total repayment and interest
- `0b101101 as base 8` → 0o55
- `0x2D as base 2` → 0b101101
- `hex(99)` → 0x63, `bin(0x73)` → 0b1110011, `int(0o55)` → 45
- Large numbers: B/bn (billion), T/tn (trillion), trillion word
- Comments: parenthesis comments `$999 (for iPhone)`, end-of-line `// comment`
- Parenthesis stripping safely skips function calls like sin(x)
- `density of yogurt` → 1.06 g/cm³
- `300g butter in cups` → mass-to-volume conversion
- `10 cups olive oil in grams` → volume-to-mass conversion
- ~120 cooking substances with densities
- Expand fiat currencies from 27 to 166 (all from open.er-api.com)
- Add 21 cryptocurrencies via CoinGecko API (BTC, ETH, SOL, DOGE, etc.)
- Prefixed dollar symbols: US$, NZ$, CA$, AU$, HK$, S$, NT$
- Custom exchange rates: `50 EUR in USD at 1.05 USD/EUR`
- CoinGecko + fiat fetched in parallel with 1h cache
14 fixture files covering all math engine features:
- arithmetic, variables, percentages, aggregates, rounding
- math functions, conditionals, units, currency
- fractions/multipliers, calendar, timezones, timespans
- finance, misc functions, cooking
- 4 real-world scenarios: budget, travel, cooking, dev
- Single formatMathDate() for all date outputs (timezone, calendar, arithmetic)
- DateFormatStyle: 'numeric' | 'short' | 'long' (configurable via setFormatSettings)
- Options: timeZone, timeZoneName, dateOnly for context-specific formatting
- Remove separate formatTimeZoneDate function
- All dates now respect user locale consistently
- Date format preference: numeric, short, long
- Separate refresh buttons for fiat currencies and crypto rates
- IPC handlers for forced refresh (ignores cache)
- i18n keys for new preferences
- numericBlock stores value + unit name
- Aggregates sum only if all entries have same unit
- Mixed units → aggregate returns null (cannot sum)
- $100 + $200 + $50 → sum = 350 USD
- Unit info extracted from math.js rawResult for block tracking
@antonreshetov antonreshetov changed the title feat: extend math engine — currencies, timezones, finance, cooking, UX fixes feat: extend math engine: currencies, timezones, finance, cooking Mar 29, 2026
- P1: merge partial rates with existing cache instead of overwriting
- P2: show error toast on fiat refresh failure (was showing success)
- P2: finance evaluator uses user locale for formatting
- P2: cooking evaluator uses user locale for formatting
- P2: cooking classifier supports all volume units (pints, quarts, etc.)
- useMathEngine.integration.test.ts (66) — multi-line, variables, aggregates, errors
- useMathEngine.math.test.ts (229) — arithmetic, rounding, percentages, conditionals
- useMathEngine.units.test.ts (59) — unit conversion, area/volume, css, rates
- useMathEngine.currency.test.ts (22) — currency symbols, prefixes, modifiers
- useMathEngine.timezones.test.ts (28) — timezone display, conversion, difference
- useMathEngine.calendar.test.ts (47) — calendar, workdays, timestamps, timespans
- useMathEngine.domain.test.ts (17) — finance, cooking
- Shared setup in mathEngineTestUtils.ts
@antonreshetov antonreshetov merged commit 7ab5634 into main Mar 29, 2026
@antonreshetov antonreshetov deleted the feat/math-new-features branch March 29, 2026 11:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant