# date — Date Arithmetic, Formatting, and Timezones > `import { addDays, addMonths, addYears, addHours, addMinutes, addSeconds, formatDate, getTimeDiff, toTz } from 'puffy-core/date'` > CJS: `const { date: { addDays, addMonths, addYears, addHours, addMinutes, addSeconds, formatDate, getTimeDiff, toTz } } = require('puffy-core')` > Also available in snake_case: `add_days`, `add_months`, `add_years`, `add_hours`, `add_minutes`, `add_seconds`, `format_date`, `get_time_diff`, `to_tz` --- ## Date Arithmetic All functions create and return a NEW Date object (the input is not mutated). Accepts negative values to subtract. ### Signatures ``` addSeconds(date: Date, value: number = 0) → Date addMinutes(date: Date, value: number = 0) → Date addHours(date: Date, value: number = 0) → Date addDays(date: Date, value: number = 0) → Date addMonths(date: Date, value: number = 0) → Date addYears(date: Date, value: number = 0) → Date ``` ### Examples ```js const now = new Date() addSeconds(now, 30) // 30 seconds from now addMinutes(now, 65) // 65 minutes from now addHours(now, 3) // 3 hours from now addDays(now, 4) // 4 days from now addMonths(now, 3) // 3 months from now addYears(now, -10) // 10 years ago (negative value subtracts) ``` GOTCHA: `addYears()` internally uses the deprecated `Date.prototype.setYear()` instead of `setFullYear()`. This works correctly for modern dates but may behave unexpectedly with years before 1900. --- ## formatDate Formats a date into a string using format tokens. ### Signature ``` formatDate(date: Date|string, options?: { format?: string, tz?: string }) → string|null ``` Parameters: - `date`: Date object or date string - `options.format`: Format string using tokens below. Default: `'yyyy-MM-dd'` - `options.tz`: Timezone — `'utc'` (default), `'local'`, or IANA timezone code (e.g., `'Australia/Sydney'`) Returns: Formatted string, or `null` if date is falsy. ### Format tokens | Token | Output | Example | |---|---|---| | `yyyy` | 4-digit year | `2021` | | `yy` | 2-digit year | `21` | | `MM` | 2-digit month | `10` | | `MMM` | Full month name | `October` | | `dd` | 2-digit day | `12` | | `HH` | 2-digit hours (24h) | `13` | | `mm` | 2-digit minutes | `45` | | `ss` | 2-digit seconds | `21` | | `{nth}` | Ordinal suffix | `st`, `nd`, `rd`, `th` | ### Examples ```js const d = new Date('2021-10-12T13:45:21Z') formatDate(d) // '2021-10-12' formatDate(d, { format:'dd-MM-yyyy' }) // '12-10-2021' formatDate(d, { format:'ddMMyyyy' }) // '12102021' formatDate(d, { format:'MMyy' }) // '1021' formatDate(d, { format:'dd/MM/yy' }) // '12/10/21' formatDate(d, { format:'dd/MM/yy HH:mm:ss' }) // '12/10/21 13:45:21' formatDate(d, { format:'The dd of MMM, yyyy' }) // 'The 12 of October, 2021' formatDate(d, { format:'The dd{nth} of MMM, yyyy' }) // 'The 12th of October, 2021' ``` ### Examples with timezones ```js const d = new Date('2021-10-12T13:45:21Z') // UTC (default) formatDate(d, { format:'dd/MM/yy HH:mm:ss' }) // '12/10/21 13:45:21' // Specific timezone (full list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) formatDate(d, { format:'dd/MM/yy HH:mm:ss', tz:'Australia/Sydney' }) // '13/10/21 00:45:21' // Local system timezone formatDate(d, { format:'dd/MM/yy HH:mm:ss', tz:'local' }) // depends on your system timezone ``` --- ## toTz Converts a UTC date into another UTC date shifted as if it was in a specific timezone. The returned Date's UTC methods will return values matching the target timezone. ### Signature ``` toTz(date: Date|string, tz?: string) → Date|null ``` Parameters: - `date`: Date object or date string - `tz`: `'utc'` (default, returns date as-is), `'local'`, or IANA timezone code Returns: New Date object, or `null` if date is falsy. ### Examples ```js const d = new Date('2024-01-23T09:42:57.311Z') toTz(d).toISOString() // '2024-01-23T09:42:57.311Z' — UTC, unchanged toTz(d, 'local').toISOString() // '2024-01-23T17:42:57.311Z' — shifted to local toTz(d, 'Australia/Sydney').toISOString() // '2024-01-23T20:42:57.311Z' — shifted to Sydney toTz(d, 'America/Chicago').toISOString() // '2024-01-23T03:42:57.311Z' — shifted to Chicago ``` GOTCHA: `toTz` does NOT parse a local time into UTC. It takes a UTC date and shifts it so that the UTC representation shows the target timezone's wall clock time. This is useful for display purposes and for `formatDate` with timezone support. --- ## getTimeDiff Calculates the absolute difference between two dates. ### Signature ``` getTimeDiff(date1: Date|string, date2: Date|string, unit?: string) → number ``` Default unit: `'ms'` (milliseconds) ### Supported units | Unit strings | Description | |---|---| | `'ms'`, `'millisecond'` | Milliseconds | | `'s'`, `'sec'`, `'second'` | Seconds | | `'m'`, `'min'`, `'minute'` | Minutes | | `'h'`, `'hour'` | Hours | | `'d'`, `'day'` | Days | | `'w'`, `'week'` | Weeks | | `'month'` | Months (uses 30.41 days) | | `'y'`, `'year'` | Years (uses 365 days) | ### Examples ```js getTimeDiff('2021-08-12', new Date('2021-12-12T13:09')) // 10548540000 getTimeDiff('2021-08-12', new Date('2021-12-12T13:09'), 'second') // 10548540 getTimeDiff('2021-08-12', new Date('2021-12-12T13:09'), 'minute') // 175809 getTimeDiff('2021-08-12', new Date('2021-12-12T13:09'), 'hour') // 2930.15 getTimeDiff('2021-08-12', new Date('2021-12-12T13:09'), 'day') // 122.09 getTimeDiff('2021-08-12', new Date('2021-12-12T13:09'), 'week') // 17.44 getTimeDiff('2021-08-12', new Date('2021-12-12T13:09'), 'month') // 4.01 getTimeDiff('2021-08-12', new Date('2021-12-12T13:09'), 'year') // 0.33 ``` GOTCHA: The result is always the absolute difference (positive number). The order of date1 and date2 does not matter. GOTCHA: Month and year calculations use fixed approximations (30.41 days/month, 365 days/year), not calendar-aware computations.