Coder Social home page Coder Social logo

bjuppa / com-plain-date Goto Github PK

View Code? Open in Web Editor NEW
1.0 1.0 0.0 430 KB

JavaScript date-time utilities that keep timezones on the surface

Home Page: https://deno.land/x/complaindate/mod.ts

License: MIT License

TypeScript 100.00%
date-time functional-programming timezone plain-date plain-time immutable curried fp localization pure

com-plain-date's People

Contributors

bjuppa avatar

Stargazers

 avatar

Watchers

 avatar

com-plain-date's Issues

Change prefix of plain-date-navigating utils (e.g. addDays => jumpDays)

The functions that navigate from a plain-date to another are currently named with the add prefix, but they don't really "add" per se, they can also subtract if the argument is negative.

Would it make sense to change their prefix to jump, e.g. jumpDays?

Does "jump" sound to silly? I think navigate is too long and move is a bit boring.

  • addBusinessDays
  • addDays
  • addMonths
  • addQuarters
  • addYears

...but not addTime, because it actually does move specifically forward and has a reverse function subtractTime.

(also, it seems ExPlainDate only has 4 of those navigators... addQuarters is missing)

Create utils for time manipulation on JS Date objects

It could be useful to provide utils for directly truncating minutes relative full hours directly on JS Date objects, and it's easy to forget that it requires a timezone to do correctly... ;)

ComPlainDate could help developers by directly providing:

  • startOfHour(timezone: string)(instant: Date): Date
  • startOfDay(timezone: string)(instant: Date): Date

...and perhaps also:

  • truncateToHalfHour
  • truncateToThirdOfHour
  • truncateToQuarterOfHour
  • truncateToSixthOfHour
  • truncateToTwelfthOfHour

Create difference utils for JS Date objects

Some quick ideas:

  • differenceInHours(from: Date)(to: Date): number
  • differenceInMinutes(from: Date)(to: Date): number
  • differenceInSeconds(from: Date)(to: Date): number
  • differenceAsDuration(timezone: string)(from: Date)(to: Date): Duration

Investigate if type-lift prevents tree-shaking

The PlainDateFactory interface requires a type-lift function (of) that is meant to be a reference back to the function itself.

I suspect that the self-reference prevents any such function (and it's dependencies) from being tree-shaken in a production build ๐Ÿ™€

Investigate if we can drop the type-lift from the interface and the implementations!

Docs show "unnamed 0" for destructured function parameters

The generated docs have trouble picking up the parameter names when destructuring function parameters. This function declaration:

export function isLeapYear({ year }: SloppyDate): boolean { ... }

...looks like this in docs:

isLeapYear(unnamed 0: SloppyDate): boolean

Searching for }: in the codebase reveals the problematic functions, in 16 files at the time of writing.

Use plural properties for duration-like objects

In preparation for Duration objects, we should already start using plural property names, like hours, minutes, etc in objects not describing a time-of-day.

These are the relevant functions that need new signatures:

  • tallyMilliseconds
  • addTime & subtractTime
  • timezoneOffsetParts

Also, add this as a guiding principle in the readme, and cut down on the existing object shape principle.

Handle short form timezone reported by some systems

Our localTimezone() function returns unexpected short form timezone names (e.g. "CET") on some systems. This breaks our tests for localTimezone as well as safeTimezone on those systems.

Seen with Deno 1.39.0 on macOS 14.2

The underlying call is Intl.DateTimeFormat()?.resolvedOptions()?.timeZone

There are no options affecting returned timeZone, so my suggestion is that we rewrite localTimezone to fallback to returning UTC whenever no / can be found in reported timeZone. The short form will not be useful for the UI anyway, for example the short forms will not be available in a dropdown.

Add an equality check method to ComPlainDate and ComPlainTime

Plain-date and plain-time objects can be compared with <, >=, etc... but not for equality with == because of JS objects, duh.

It'd still be useful to compare them for equality though.

The simplest way would be an is(date: ComPlainDate): bool method that checks that all three properties are equal.

Next level would be isMatch(pattern: { year?: number | string, month?: number | string, day?: number | string }): bool that would return true when just the given properties match.

Having the latter makes the first one redundant. Would it make sense to implement the latter but calling it simply is, or would that be a confusing name?

Add utils for PlainDate ranges, generators and sequences

If we start with a generator, we can use that to create some nifty range- and sequence-related functions:

  • plainDateGenerator(next: (x: PlainDate) => PlainDate)(first: PlainDate): Iterable<PlainDate>
  • plainDateRange(days: number)(first: PlainDate): PlainDate[] (days may be negative!)
  • plainDatesBetween(first: PlainDate)(last: PlainDate): PlainDate[]
  • firstPlainDate(predicate: (x: PainDate) => boolean))(sequence: Iterable<PlainDate>): PlainDate | undefined

See https://github.com/tc39/proposal-iterator-helpers

Add an object type and utils for durations

Create factory function Duration for duration objects (time-period, span, stretch), like 3 days, 4 hours, 25 minutes.

Some resolution units to consider, each can be negative, at least one needs to be given:

Time-level:

  • milliseconds
  • seconds
  • minutes
  • hours

Days-level:

  • days
  • weeks

Months-level:

  • months
  • quarters
  • years
  • decades
  • centuries
  • millennia

Upon object creation, normalize / balance to the largest given unit within each level.

Properties and methods:

  • iso
  • toString() => iso
  • toJson() => iso
  • valueOf() => number tally milliseconds
  • is(other: Duration) => boolean equality check
  • round() => Duration
  • rescale(shape: SloppyDuration) => Duration
  • add(duration: Duration): Duration
  • subtract(duration: Duration): Duration
  • asHours(), asDays(), etc

Use Intl number format to localise strings using units. See how Luxon does this!
Check Temporal for balancing https://tc39.es/proposal-temporal/docs/balancing.html and compare that to Luxon's round, rescale & shift!

Create utils for datetime-local with Date

When using <input type="datetime-local"> it's quite common to go straight from and to JS Date. We could provide some utils to help:

  • datetimeLocalToInstant(timezone: string)(datetimeLocal: string): Date
  • instantToDatetimeLocal(timezone: string)(instant: Date): string

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.