0.1.3 • Published 7 years ago

dateful v0.1.3

Weekly downloads
4
License
MIT
Repository
github
Last release
7 years ago

dateful

A slim library for dates in JavaScript. Yes, another one.

Installation

The usual ways. If you're developing for Node or using a bundler, use Yarn or npm:

NPM

npm install --save dateful

Yarn

yarn add dateful

Then import or require it and start playing with time!

import {dateful} from 'dateful';

const lastTuesday = dateful ()
    .startOf ('week')
    .subtract (6, 'days')
    .value ();

Or if you want to use a CDN to get it in its own script tag use unpkg:

<script src="https://unpkg.com/dateful"></script>

Then the two factory functions dateful and timeless will be made available as properties of a global value called dateful:

dateful.dateful ([2017, 6, 27])
    .add (3, 'days')
    .format ('YYYY-MM-DD');

Usage

Use the factory function dateful to create a new Dateful, providing a fluent interface for manipulating the underlying Date:

dateful ()
    .add (3, 'days')
    .format ('YYYY-MM-DD')

The dateful function can be called in several ways:

// Calling with no parameters will create a Dateful that represents the present moment:
dateful ();

// Passing a Date object will create a Dateful that wraps a clone of that Date:
dateful (new Date ());

// Passing a Dateful will create a new clone of it:
dateful (dateful ());

// Passing an array of numbers will use those numbers as the year, month, date, hours, minutes,
// seconds and milliseconds and build a Dateful from that:
dateful ([2017, 6, 27, 12, 30, 23, 400]);

// Passing a single number will treat that number as Unix time (milliseconds since the Unix
// Epoch - 1970-01-01T00:00.000Z):
dateful (1234567890);

See the section on "timeless" mode below for an explanation of the other factory function, timeless.

Cancelling out the timezone offset

There is a very particular use-case in which a date has already been generated by a different library (say, a datepicker widget) and due to the local timezone being ahead of UTC, the time passed in to dateful is actually sometime the night before the selected date. For example, the local timezone is British Summertime (GMT+1), and the user selects 2017-08-03 from a datepicker. The value we get from that datepicker is a number in UTC:

new Date (2017, 7, 3).valueOf ();     // -> 1501714800000
new Date (2017, 7, 3).toISOString (); // -> '2017-08-02T23:00:00.000Z' - See the "02" in there? Ridiculous.

...which represents 11pm on the second of August. When we try to get the ISO string from a Date and slice it to get just the date part, we get '2017-08-02', not '2017-08-03'!

The Dateful would have the same problem, but there's a solution: an optional second parameter, fixTimezoneOffset:

const numFromDatepicker = 1501714800000;
dateful (numFromDatepicker, true)
    .format ('YYYY-MM-DD'); // -> '2017-08-03'

Timeless mode

There is an alternative mode in which your Dateful can exist: timeless. This sets the time (hours, minutes, seconds and milliseconds) to zero, and makes it immutable. In this mode, your Dateful only represents a date, with no time part. Trying to alter the time part will fail quietly, logging an error to the console but continuing running. This mode is activated in one of two ways: using the timeless factory function instead of dateful, or calling the timeless method on a Dateful object.

import {dateful, timeless} from 'dateful';

timeless ()
    .add (1, 'hour')  // Will do nothing but console.error
    .startOf ('week') // Will work despite the previous method failing
    .format  ('hh:mm:ss.sss'); // -> '00:00:00.000'

dateful ()
    .add (1, 'hour') // Will work fine
    .timeless ()     // Makes the above call to `add` a bit pointless, but never mind
    .format ('hh:mm:ss.sss'); // -> '00:00:00.000'

Formatting

Often, you'll want to be able to display your date/time in a nice way, or format it in exactly the right way for an API call. The output method format allows you to do this. format is simple to use: pass it a string containing any of the following representations, and it will return a string with those characters replaced with the values they represent.

CharactersDate partExample
YYYYFull year2017
YYShort year17
MonthMonth nameJanuary
MnthAbbr month nameJan
MMMonth number01
WwwWeek numberW30
DayDay nameMonday
DDDOrdinal date (zero-padded)*124
DDDate (zero-padded)07
DthDate (ordinal)**7th
DDay of the week (1-7)2

*Number of days into the year. 1st of February is day 32, etc.

**Date of the month, but with the "-st", "-nd", "-rd" or "-th" ending.

The time component can also be rendered by format. The following table shows the characters to use.

CharactersTime partExample
hhHours (24hr time)13
mmMinutes30
ssSeconds45

Each of the time parts can also be made decimal to include smaller increments of time, e.g. seconds with milliseconds: 'ss.sss' => '45.400'. This includes doing something most people would consider a bit odd, decimalising minutes or hours:

const halfTwelve    = dateful ([2017, 6, 27, 12, 30]);
const fortyFiveSecs = dateful ([2017, 6, 27, 12, 30, 45]);

halfTwelve.format ('hh.hhh'); // -> '12.500'
halfTwelve.format ('hh.hh');  // -> '12.50'
halfTwelve.format ('hh.h');   // -> '12.5'

fortyFiveSecs.format ('mm.mmm'); // -> '30.750'
fortyFiveSecs.format ('mm.mm');  // -> '30.75'
fortyFiveSecs.format ('mm.m');   // -> '30.8'

Odd as it may seem, it is a valid part of ISO 8601, and so is included here.

So why does it exist?

I'll be honest, I started this project in order to better understand how to manipulate Dates. They're a bit of a dark art in JavaScript, and have their issues. There are already great libraries out there for manipulating them, like Moment.js or js-joda. Despite the existence of these packages, working with Dates seemed like an interesting challenge that I wanted to take a crack at.

0.1.3

7 years ago

0.1.2

7 years ago

0.1.1

7 years ago

0.1.0

7 years ago

0.0.0

7 years ago