or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

async-programming.mdcharacter-operations.mdcollections.mdconfiguration.mdcore-infrastructure.mddata-encoding.mddate-time.mdexternal-integration.mdindex.mdnumeric-types.mdreactive-programming.mdstring-operations.mdtype-system.md
tile.json

date-time.mddocs/

Date and Time

Comprehensive date and time handling with .NET DateTime compatibility, timezone support, and time span operations for precise temporal calculations.

Date Module - Date and DateTime Operations

Complete date/time manipulation with .NET DateTime compatibility, supporting multiple date kinds, formatting, and arithmetic operations.

Constants and Utilities

// Time zone offset regex for parsing
const offsetRegex: RegExp;

// Format date offset as string
function dateOffsetToString(offset: number): string;

// Convert date to half UTC string representation
function dateToHalfUTCString(date: IDateTime, half: "first" | "second"): string;

// Usage
import { dateOffsetToString, dateToHalfUTCString } from "fable-library/Date.js";

// Format timezone offset
console.log(dateOffsetToString(-300)); // "-05:00" (300 minutes = 5 hours)
console.log(dateOffsetToString(0)); // "+00:00" (UTC)

// Half UTC string representation (internal formatting)
const now = new Date();
console.log(dateToHalfUTCString(now, "first")); // Date part
console.log(dateToHalfUTCString(now, "second")); // Time part

Date Creation

// Create date with optional components and kind
function create(year?: number, month?: number, day?: number, h?: number, m?: number, s?: number, ms?: number, kind?: DateKind): Date;

// Create UTC date
function createUtc(year: number, month: number, day: number, h?: number, m?: number, s?: number, ms?: number): Date;

// Current date/time functions
function now(): Date;
function utcNow(): Date;
function today(): Date;

// Usage
import { create, createUtc, now, utcNow, today, DateKind } from "fable-library/Date.js";

// Create specific dates
const localDate = create(2023, 12, 25, 10, 30, 0, 0, DateKind.Local);
const utcDate = createUtc(2023, 12, 25, 15, 30, 0, 0);

// Current dates
const currentLocal = now();
const currentUtc = utcNow();
const todayDate = today(); // Today at midnight

console.log(localDate); // 2023-12-25T10:30:00 (local)
console.log(utcDate); // 2023-12-25T15:30:00Z (UTC)

Date Validation and Parsing

// Calendar utilities
function isLeapYear(year: number): boolean;
function daysInMonth(year: number, month: number): number;

// Parse date strings
function parse(str: string, detectUTC?: boolean): Date;
function tryParse(str: string, detectUTC?: boolean): [boolean, Date];

// Usage
import { isLeapYear, daysInMonth, parse, tryParse } from "fable-library/Date.js";

// Calendar calculations
console.log(isLeapYear(2024)); // true
console.log(isLeapYear(2023)); // false
console.log(daysInMonth(2024, 2)); // 29 (February in leap year)
console.log(daysInMonth(2023, 2)); // 28 (February in non-leap year)

// Parse date strings
const parsedDate = parse("2023-12-25T10:30:00");
console.log(parsedDate);

// Safe parsing
const [success, date] = tryParse("2023-12-25");
if (success) {
    console.log("Parsed successfully:", date);
} else {
    console.log("Parse failed");
}

// Invalid date parsing
const [failed, invalidDate] = tryParse("invalid-date");
console.log(failed); // false

Date Arithmetic

Add or subtract time periods from dates.

// Add time periods
function addYears(d: Date, v: number): Date;
function addMonths(d: Date, v: number): Date;
function addDays(d: Date, v: number): Date;
function addHours(d: Date, v: number): Date;
function addMinutes(d: Date, v: number): Date;
function addSeconds(d: Date, v: number): Date;
function addMilliseconds(d: Date, v: number): Date;
function addTicks(d: Date, t: number): Date;

// Usage
import { 
    addYears, addMonths, addDays, addHours, 
    addMinutes, addSeconds, addMilliseconds 
} from "fable-library/Date.js";

const baseDate = new Date(2023, 0, 1); // January 1, 2023

// Add various time periods
const nextYear = addYears(baseDate, 1); // January 1, 2024
const nextMonth = addMonths(baseDate, 6); // July 1, 2023
const tomorrow = addDays(baseDate, 1); // January 2, 2023
const laterHour = addHours(baseDate, 12); // January 1, 2023 12:00 PM
const laterMinute = addMinutes(baseDate, 30); // January 1, 2023 12:30 AM
const laterSecond = addSeconds(baseDate, 45); // January 1, 2023 12:00:45 AM

console.log(nextYear.getFullYear()); // 2024
console.log(nextMonth.getMonth()); // 6 (July, 0-indexed)
console.log(tomorrow.getDate()); // 2

Date Components

Extract individual components from dates.

// Get date components
function year(d: Date): number;
function month(d: Date): number;
function day(d: Date): number;
function hour(d: Date): number;
function minute(d: Date): number;
function second(d: Date): number;
function millisecond(d: Date): number;
function ticks(d: Date): number;
function dayOfWeek(d: Date): number;
function dayOfYear(d: Date): number;

// Usage
import { 
    year, month, day, hour, minute, second, 
    millisecond, dayOfWeek, dayOfYear 
} from "fable-library/Date.js";

const date = new Date(2023, 11, 25, 15, 30, 45, 123); // December 25, 2023 3:30:45.123 PM

console.log(year(date)); // 2023
console.log(month(date)); // 12 (December)
console.log(day(date)); // 25
console.log(hour(date)); // 15
console.log(minute(date)); // 30
console.log(second(date)); // 45
console.log(millisecond(date)); // 123
console.log(dayOfWeek(date)); // 1 (Monday, 0=Sunday)

// Day of year calculation
const newYear = new Date(2023, 0, 1);
const christmas = new Date(2023, 11, 25);
console.log(dayOfYear(newYear)); // 1
console.log(dayOfYear(christmas)); // 359

Date Formatting

Convert dates to various string representations.

// Format with options
function toString(d: Date, format?: string, utc?: boolean): string;
function toStringWithOffset(d: any, format?: string): string;
function toStringWithKind(d: any, format?: string): string;

// Usage
import { toString, toStringWithOffset, toStringWithKind } from "fable-library/Date.js";

const date = new Date(2023, 11, 25, 15, 30, 45);

// Default formatting
console.log(toString(date)); // Standard date string

// Custom formatting (F# style format strings)
console.log(toString(date, "yyyy-MM-dd")); // "2023-12-25"
console.log(toString(date, "HH:mm:ss")); // "15:30:45"
console.log(toString(date, "yyyy-MM-dd HH:mm:ss")); // "2023-12-25 15:30:45"

// UTC formatting
console.log(toString(date, "yyyy-MM-dd HH:mm:ss", true)); // UTC representation

// With offset information
const offsetDate = Object.assign(date, { offset: -300 }); // 5 hours behind UTC
console.log(toStringWithOffset(offsetDate)); // Includes offset

// With kind information
const kindDate = Object.assign(date, { kind: DateKind.Local });
console.log(toStringWithKind(kindDate)); // Includes kind info

Date Comparison

// Equality and comparison
function equals(d1: Date, d2: Date): boolean;
function compare(d1: Date, d2: Date): number;
function compareTo(d1: Date, d2: Date): number;

// Arithmetic operators
function op_Addition(x: Date, y: number): Date;
function op_Subtraction(x: Date, y: number | Date): number | Date;

// Usage
import { equals, compare, op_Addition, op_Subtraction } from "fable-library/Date.js";

const date1 = new Date(2023, 11, 25);
const date2 = new Date(2023, 11, 25);
const date3 = new Date(2023, 11, 26);

console.log(equals(date1, date2)); // true
console.log(equals(date1, date3)); // false

console.log(compare(date1, date2)); // 0 (equal)
console.log(compare(date1, date3)); // -1 (date1 < date3)
console.log(compare(date3, date1)); // 1 (date3 > date1)

// Operator-style arithmetic
const futureDate = op_Addition(date1, 86400000); // Add 1 day in milliseconds
const timeDiff = op_Subtraction(date3, date1); // Time difference in milliseconds
console.log(timeDiff); // 86400000 (1 day)

DateOffset Module - DateTimeOffset Operations

DateTimeOffset implementation providing timezone-aware date operations with explicit offset management.

Creation and Conversion

// Create DateTimeOffset with components
function create(year?: number, month?: number, day?: number, h?: number, m?: number, s?: number, ms?: number, offset?: number): Date;

// Create from existing Date
function fromDate(d: Date, offset?: number): Date;

// Create from ticks
function fromTicks(ticks: number, offset: number): Date;

// Current time functions
function now(): Date;
function utcNow(): Date;

// Time zone conversions
function toUniversalTime(d: Date): Date;
function toLocalTime(d: Date): Date;

// Usage
import { 
    create, fromDate, fromTicks, now, utcNow, 
    toUniversalTime, toLocalTime 
} from "fable-library/DateOffset.js";

// Create with specific offset (EST = UTC-5 = -300 minutes)
const estDate = create(2023, 12, 25, 15, 30, 0, 0, -300);

// Create from existing date
const localDate = new Date();
const offsetDate = fromDate(localDate, -300); // Convert to EST

// Current time with offset
const nowWithOffset = now(); // Current local time with system offset
const utcNow = utcNow(); // Current UTC time

// Convert between time zones
const utcTime = toUniversalTime(offsetDate); // Convert to UTC
const backToLocal = toLocalTime(utcTime); // Convert back to local

console.log("EST Date:", estDate);
console.log("UTC equivalent:", toUniversalTime(estDate));

Properties and Components

// Get offset and time components
function offset(d: Date): number;
function timeOfDay(d: Date): number;
function date(d: Date): Date;

// Date components (same as Date module but offset-aware)
function day(d: Date): number;
function dayOfWeek(d: Date): number;
function dayOfYear(d: Date): number;
function hour(d: Date): number;
function millisecond(d: Date): number;
function minute(d: Date): number;
function month(d: Date): number;
function second(d: Date): number;
function year(d: Date): number;

// Tick functions
function ticks(d: Date): number;
function utcTicks(d: Date): number;

// Usage
import { 
    offset, timeOfDay, date, hour, minute, 
    ticks, utcTicks 
} from "fable-library/DateOffset.js";

const offsetDate = create(2023, 12, 25, 15, 30, 0, 0, -300);

console.log(offset(offsetDate)); // -300 (5 hours behind UTC)
console.log(timeOfDay(offsetDate)); // Time portion in milliseconds
console.log(date(offsetDate)); // Date portion only

// Components respect the offset
console.log(hour(offsetDate)); // 15 (local hour)
console.log(minute(offsetDate)); // 30

// Ticks (100-nanosecond intervals since .NET epoch)
console.log(ticks(offsetDate)); // Local ticks
console.log(utcTicks(offsetDate)); // UTC ticks (adjusted for offset)

Arithmetic Operations

// Add time periods (preserving offset)
function addYears(d: Date, years: number): Date;
function addMonths(d: Date, months: number): Date;
function addDays(d: Date, days: number): Date;
function addHours(d: Date, hours: number): Date;
function addMinutes(d: Date, minutes: number): Date;
function addSeconds(d: Date, seconds: number): Date;
function addMilliseconds(d: Date, milliseconds: number): Date;
function addTicks(d: Date, ticks: number): Date;

// Usage
import { 
    addYears, addMonths, addDays, addHours,
    create
} from "fable-library/DateOffset.js";

const baseDate = create(2023, 1, 1, 12, 0, 0, 0, -300); // EST

// Add time periods (offset is preserved)
const nextYear = addYears(baseDate, 1);
const nextMonth = addMonths(baseDate, 1);
const tomorrow = addDays(baseDate, 1);
const laterHour = addHours(baseDate, 6);

console.log("Base:", baseDate);
console.log("Next year:", nextYear);
console.log("Tomorrow:", tomorrow);

// Offset is maintained through arithmetic
console.log(offset(baseDate)); // -300
console.log(offset(nextYear)); // -300 (same offset)

Formatting and Comparison

// Formatting
function toString(d: Date, format?: string): string;

// Comparison
function equals(d1: Date, d2: Date): boolean;
function compare(d1: Date, d2: Date): number;
function compareTo(d1: Date, d2: Date): number;

// Usage
import { toString, equals, compare } from "fable-library/DateOffset.js";

const est = create(2023, 12, 25, 15, 30, 0, 0, -300);
const pst = create(2023, 12, 25, 12, 30, 0, 0, -480);

// Format with offset information
console.log(toString(est)); // Includes offset in output
console.log(toString(est, "yyyy-MM-dd HH:mm:ss zzz")); // Custom format with offset

// Comparison accounts for offset (compares UTC times)
console.log(equals(est, pst)); // true (same UTC time)
console.log(compare(est, pst)); // 0 (equal when normalized to UTC)

TimeSpan Module - Time Duration Operations

TimeSpan implementation for representing time durations with precision and comprehensive arithmetic operations.

Creation Functions

// Create from components (multiple overloads)
function create(d?: number, h?: number, m?: number, s?: number, ms?: number): number;
function create(h: number, m: number, s: number): number;
function create(d: number, h: number, m: number, s: number, ms: number): number;

// Create from specific units
function fromTicks(ticks: number): number;
function fromDays(d: number): number;
function fromHours(h: number): number;
function fromMinutes(m: number): number;
function fromSeconds(s: number): number;
function fromMilliseconds(ms: number): number;

// Usage
import { 
    create, fromDays, fromHours, fromMinutes, 
    fromSeconds, fromTicks 
} from "fable-library/TimeSpan.js";

// Create from components
const timeSpan1 = create(1, 2, 30, 45, 500); // 1 day, 2 hours, 30 minutes, 45.5 seconds
const timeSpan2 = create(2, 30, 45); // 2 hours, 30 minutes, 45 seconds

// Create from specific units
const oneDay = fromDays(1);
const twoHours = fromHours(2);
const thirtyMinutes = fromMinutes(30);
const fortyFiveSeconds = fromSeconds(45);
const fiveHundredMs = fromMilliseconds(500);

console.log("One day in ms:", oneDay); // 86400000
console.log("Two hours in ms:", twoHours); // 7200000
console.log("Thirty minutes in ms:", thirtyMinutes); // 1800000

Component Extraction

Extract individual time components from TimeSpan values.

// Get whole components
function days(ts: number): number;
function hours(ts: number): number;
function minutes(ts: number): number;
function seconds(ts: number): number;
function milliseconds(ts: number): number;
function ticks(ts: number): number;

// Get total values in different units
function totalDays(ts: number): number;
function totalHours(ts: number): number;
function totalMinutes(ts: number): number;
function totalSeconds(ts: number): number;
function totalMilliseconds(ts: number): number;

// Usage
import { 
    days, hours, minutes, seconds, milliseconds,
    totalDays, totalHours, totalMinutes, create
} from "fable-library/TimeSpan.js";

const duration = create(1, 2, 30, 45, 500); // 1d 2h 30m 45.5s

// Whole components (remainder after larger units)
console.log(days(duration)); // 1
console.log(hours(duration)); // 2 (not 26, just the hour part)
console.log(minutes(duration)); // 30 (just the minute part)
console.log(seconds(duration)); // 45 (just the second part)
console.log(milliseconds(duration)); // 500 (just the millisecond part)

// Total values (entire duration in specified units)
console.log(totalDays(duration)); // ~1.104 (total duration in days)
console.log(totalHours(duration)); // ~26.51 (total duration in hours)
console.log(totalMinutes(duration)); // ~1590.75 (total duration in minutes)
console.log(totalSeconds(duration)); // ~95445.5 (total duration in seconds)

TimeSpan Operations

// Arithmetic operations
function negate(ts: number): number;
function add(ts1: number, ts2: number): number;
function subtract(ts1: number, ts2: number): number;

// Comparison
function compare(ts1: number, ts2: number): number;
function compareTo(ts1: number, ts2: number): number;

// Other operations
function duration(ts: number): number; // Absolute value
function toString(ts: number, format?: string, _provider?: any): string;

// Usage
import { 
    add, subtract, negate, compare, duration, 
    toString, fromHours, fromMinutes 
} from "fable-library/TimeSpan.js";

const oneHour = fromHours(1);
const thirtyMinutes = fromMinutes(30);
const negativeHour = negate(oneHour);

// Arithmetic
const sum = add(oneHour, thirtyMinutes); // 1.5 hours
const diff = subtract(oneHour, thirtyMinutes); // 0.5 hours

console.log("Sum:", toString(sum)); // "01:30:00"
console.log("Difference:", toString(diff)); // "00:30:00"

// Comparison
console.log(compare(oneHour, thirtyMinutes)); // 1 (oneHour > thirtyMinutes)
console.log(compare(thirtyMinutes, oneHour)); // -1 (thirtyMinutes < oneHour)

// Duration (absolute value)
console.log(duration(negativeHour) === oneHour); // true
console.log(toString(duration(negativeHour))); // "01:00:00" (positive)

Formatting Options

// Format TimeSpan values
function toString(ts: number, format?: string, _provider?: any): string;

// Usage
import { toString, create } from "fable-library/TimeSpan.js";

const duration = create(2, 3, 45, 30, 250); // 2d 3h 45m 30.25s

// Default format
console.log(toString(duration)); // "2.03:45:30.2500000"

// Custom formats (F# style)
console.log(toString(duration, "g")); // General short format
console.log(toString(duration, "G")); // General long format
console.log(toString(duration, "c")); // Constant format
console.log(toString(duration, "hh\\:mm\\:ss")); // Custom format: "03:45:30"

Practical Examples

Timer and Stopwatch Functionality

import { 
    fromMilliseconds, subtract, totalMilliseconds, 
    totalSeconds, toString 
} from "fable-library/TimeSpan.js";

// Simple stopwatch implementation
class Stopwatch {
    private startTime: number = 0;
    private elapsed: number = 0;
    private running: boolean = false;

    start(): void {
        if (!this.running) {
            this.startTime = Date.now();
            this.running = true;
        }
    }

    stop(): void {
        if (this.running) {
            this.elapsed = fromMilliseconds(Date.now() - this.startTime);
            this.running = false;
        }
    }

    reset(): void {
        this.elapsed = 0;
        this.running = false;
    }

    getElapsed(): number {
        if (this.running) {
            const current = fromMilliseconds(Date.now() - this.startTime);
            return current;
        }
        return this.elapsed;
    }

    toString(): string {
        return toString(this.getElapsed());
    }
}

// Usage
const sw = new Stopwatch();
sw.start();
// ... do some work ...
setTimeout(() => {
    sw.stop();
    console.log(`Operation took: ${sw.toString()}`);
}, 1000);

Duration Calculations

import { 
    create, add, subtract, totalHours, 
    totalDays, toString 
} from "fable-library/TimeSpan.js";

// Calculate business hours
function calculateBusinessHours(startDate: Date, endDate: Date): number {
    const totalTime = endDate.getTime() - startDate.getTime();
    const totalDuration = fromMilliseconds(totalTime);
    
    // Assuming 8-hour business days
    const businessDaysOnly = totalDays(totalDuration) * 8;
    const businessHours = create(0, Math.floor(businessDaysOnly), 0, 0, 0);
    
    return businessHours;
}

// Schedule management
function addBusinessDays(startDate: Date, businessDays: number): Date {
    const businessHours = create(businessDays, 0, 0, 0, 0);
    const totalMs = totalMilliseconds(businessHours);
    
    return new Date(startDate.getTime() + totalMs);
}

// Usage
const projectStart = new Date(2023, 0, 1); // Jan 1, 2023
const projectEnd = new Date(2023, 0, 15); // Jan 15, 2023

const businessHours = calculateBusinessHours(projectStart, projectEnd);
console.log(`Project duration: ${toString(businessHours)} business hours`);