Skip to content

Commit

Permalink
add unixDay interval (#58)
Browse files Browse the repository at this point in the history
* add unixDay interval

* Update README
  • Loading branch information
mbostock committed Dec 2, 2022
1 parent 3e9b59b commit 850c1c2
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 27 deletions.
6 changes: 4 additions & 2 deletions README.md
Expand Up @@ -197,8 +197,9 @@ Hours (e.g., 01:00 AM); 60 minutes. Note that advancing time by one hour in loca

<a name="timeDay" href="#timeDay">#</a> d3.<b>timeDay</b> · [Source](https://github.com/d3/d3-time/blob/master/src/day.js "Source")
<br><a href="#timeDay">#</a> d3.<b>utcDay</b> · [Source](https://github.com/d3/d3-time/blob/master/src/utcDay.js "Source")
<br><a href="#timeDay">#</a> d3.<b>unixDay</b> · [Source](https://github.com/d3/d3-time/blob/master/src/unixDay.js "Source")

Days (e.g., February 7, 2012 at 12:00 AM); typically 24 hours. Days in local time may range from 23 to 25 hours due to daylight saving.
Days (e.g., February 7, 2012 at 12:00 AM); typically 24 hours. Days in local time may range from 23 to 25 hours due to daylight saving. d3.unixDay is like [d3.utcDay](#timeDay), except it counts days since the UNIX epoch (January 1, 1970) such that *interval*.every returns uniformly-spaced dates rather than varying based on day-of-month.

<a name="timeWeek" href="#timeWeek">#</a> d3.<b>timeWeek</b> · [Source](https://github.com/d3/d3-time/blob/master/src/week.js "Source")
<br><a href="#timeWeek">#</a> d3.<b>utcWeek</b> · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js "Source")
Expand Down Expand Up @@ -276,8 +277,9 @@ Aliases for [d3.timeHour](#timeHour).[range](#interval_range) and [d3.utcHour](#

<a name="timeDays" href="#timeDays">#</a> d3.<b>timeDays</b>(<i>start</i>, <i>stop</i>[, <i>step</i>]) · [Source](https://github.com/d3/d3-time/blob/master/src/day.js)
<br><a href="#timeDays">#</a> d3.<b>utcDays</b>(<i>start</i>, <i>stop</i>[, <i>step</i>]) · [Source](https://github.com/d3/d3-time/blob/master/src/utcDay.js)
<br><a href="#timeDays">#</a> d3.<b>unixDays</b>(<i>start</i>, <i>stop</i>[, <i>step</i>]) · [Source](https://github.com/d3/d3-time/blob/master/src/unixDay.js)

Aliases for [d3.timeDay](#timeDay).[range](#interval_range) and [d3.utcDay](#timeDay).[range](#interval_range).
Aliases for [d3.timeDay](#timeDay).[range](#interval_range), [d3.utcDay](#timeDay).[range](#interval_range), and [d3.unixDay](#timeDay).[range](#interval_range).

<a name="timeWeeks" href="#timeWeeks">#</a> d3.<b>timeWeeks</b>(<i>start</i>, <i>stop</i>[, <i>step</i>])
<br><a href="#timeWeeks">#</a> d3.<b>utcWeeks</b>(<i>start</i>, <i>stop</i>[, <i>step</i>])
Expand Down
43 changes: 24 additions & 19 deletions src/index.js
Expand Up @@ -62,46 +62,51 @@ export {

export {
default as utcMinute,
utcMinutes as utcMinutes
utcMinutes
} from "./utcMinute.js";

export {
default as utcHour,
utcHours as utcHours
utcHours
} from "./utcHour.js";

export {
default as utcDay,
utcDays as utcDays
utcDays
} from "./utcDay.js";

export {
default as unixDay,
unixDays
} from "./unixDay.js";

export {
utcSunday as utcWeek,
utcSundays as utcWeeks,
utcSunday as utcSunday,
utcSundays as utcSundays,
utcMonday as utcMonday,
utcMondays as utcMondays,
utcTuesday as utcTuesday,
utcTuesdays as utcTuesdays,
utcWednesday as utcWednesday,
utcWednesdays as utcWednesdays,
utcThursday as utcThursday,
utcThursdays as utcThursdays,
utcFriday as utcFriday,
utcFridays as utcFridays,
utcSaturday as utcSaturday,
utcSaturdays as utcSaturdays
utcSunday,
utcSundays,
utcMonday,
utcMondays,
utcTuesday,
utcTuesdays,
utcWednesday,
utcWednesdays,
utcThursday,
utcThursdays,
utcFriday,
utcFridays,
utcSaturday,
utcSaturdays
} from "./utcWeek.js";

export {
default as utcMonth,
utcMonths as utcMonths
utcMonths
} from "./utcMonth.js";

export {
default as utcYear,
utcYears as utcYears
utcYears
} from "./utcYear.js";

export {
Expand Down
4 changes: 2 additions & 2 deletions src/ticks.js
Expand Up @@ -10,7 +10,7 @@ import month from "./month.js";
import year from "./year.js";
import utcMinute from "./utcMinute.js";
import utcHour from "./utcHour.js";
import utcDay from "./utcDay.js";
import unixDay from "./unixDay.js";
import {utcSunday as utcWeek} from "./utcWeek.js";
import utcMonth from "./utcMonth.js";
import utcYear from "./utcYear.js";
Expand Down Expand Up @@ -58,7 +58,7 @@ function ticker(year, month, week, day, hour, minute) {
return [ticks, tickInterval];
}

const [utcTicks, utcTickInterval] = ticker(utcYear, utcMonth, utcWeek, utcDay, utcHour, utcMinute);
const [utcTicks, utcTickInterval] = ticker(utcYear, utcMonth, utcWeek, unixDay, utcHour, utcMinute);
const [timeTicks, timeTickInterval] = ticker(year, month, week, day, hour, minute);

export {utcTicks, utcTickInterval, timeTicks, timeTickInterval};
15 changes: 15 additions & 0 deletions src/unixDay.js
@@ -0,0 +1,15 @@
import interval from "./interval.js";
import {durationDay} from "./duration.js";

var unixDay = interval(function(date) {
date.setUTCHours(0, 0, 0, 0);
}, function(date, step) {
date.setUTCDate(date.getUTCDate() + step);
}, function(start, end) {
return (end - start) / durationDay;
}, function(date) {
return Math.floor(date / durationDay);
});

export default unixDay;
export var unixDays = unixDay.range;
117 changes: 117 additions & 0 deletions test/unixDay-test.js
@@ -0,0 +1,117 @@
import assert from "assert";
import {unixDay, unixDays} from "../src/index.js";
import {utc} from "./date.js";

it("unixDays in an alias for unixDay.range", () => {
assert.strictEqual(unixDays, unixDay.range);
});

it("unixDay.floor(date) returns days", () => {
assert.deepStrictEqual(unixDay.floor(utc(2010, 11, 31, 23)), utc(2010, 11, 31));
assert.deepStrictEqual(unixDay.floor(utc(2011, 0, 1, 0)), utc(2011, 0, 1));
assert.deepStrictEqual(unixDay.floor(utc(2011, 0, 1, 1)), utc(2011, 0, 1));
});

it("unixDay.floor(date) does not observe daylight saving", () => {
assert.deepStrictEqual(unixDay.floor(utc(2011, 2, 13, 7)), utc(2011, 2, 13));
assert.deepStrictEqual(unixDay.floor(utc(2011, 2, 13, 8)), utc(2011, 2, 13));
assert.deepStrictEqual(unixDay.floor(utc(2011, 2, 13, 9)), utc(2011, 2, 13));
assert.deepStrictEqual(unixDay.floor(utc(2011, 2, 13, 10)), utc(2011, 2, 13));
assert.deepStrictEqual(unixDay.floor(utc(2011, 10, 6, 5)), utc(2011, 10, 6));
assert.deepStrictEqual(unixDay.floor(utc(2011, 10, 6, 6)), utc(2011, 10, 6));
assert.deepStrictEqual(unixDay.floor(utc(2011, 10, 6, 7)), utc(2011, 10, 6));
assert.deepStrictEqual(unixDay.floor(utc(2011, 10, 6, 8)), utc(2011, 10, 6));
});

it("unixDay.round(date) returns days", () => {
assert.deepStrictEqual(unixDay.round(utc(2010, 11, 30, 13)), utc(2010, 11, 31));
assert.deepStrictEqual(unixDay.round(utc(2010, 11, 30, 11)), utc(2010, 11, 30));
});

it("unixDay.ceil(date) returns days", () => {
assert.deepStrictEqual(unixDay.ceil(utc(2010, 11, 30, 23)), utc(2010, 11, 31));
assert.deepStrictEqual(unixDay.ceil(utc(2010, 11, 31, 0)), utc(2010, 11, 31));
assert.deepStrictEqual(unixDay.ceil(utc(2010, 11, 31, 1)), utc(2011, 0, 1));
});

it("unixDay.ceil(date) does not observe daylight saving", () => {
assert.deepStrictEqual(unixDay.ceil(utc(2011, 2, 13, 7)), utc(2011, 2, 14));
assert.deepStrictEqual(unixDay.ceil(utc(2011, 2, 13, 8)), utc(2011, 2, 14));
assert.deepStrictEqual(unixDay.ceil(utc(2011, 2, 13, 9)), utc(2011, 2, 14));
assert.deepStrictEqual(unixDay.ceil(utc(2011, 2, 13, 10)), utc(2011, 2, 14));
assert.deepStrictEqual(unixDay.ceil(utc(2011, 10, 6, 5)), utc(2011, 10, 7));
assert.deepStrictEqual(unixDay.ceil(utc(2011, 10, 6, 6)), utc(2011, 10, 7));
assert.deepStrictEqual(unixDay.ceil(utc(2011, 10, 6, 7)), utc(2011, 10, 7));
assert.deepStrictEqual(unixDay.ceil(utc(2011, 10, 6, 8)), utc(2011, 10, 7));
});

it("unixDay.offset(date) is an alias for unixDay.offset(date, 1)", () => {
assert.deepStrictEqual(unixDay.offset(utc(2010, 11, 31, 23, 59, 59, 999)), utc(2011, 0, 1, 23, 59, 59, 999));
});

it("unixDay.offset(date, step) does not modify the passed-in date", () => {
const d = utc(2010, 11, 31, 23, 59, 59, 999);
unixDay.offset(d, +1);
assert.deepStrictEqual(d, utc(2010, 11, 31, 23, 59, 59, 999));
});

it("unixDay.offset(date, step) does not round the passed-in date", () => {
assert.deepStrictEqual(unixDay.offset(utc(2010, 11, 31, 23, 59, 59, 999), +1), utc(2011, 0, 1, 23, 59, 59, 999));
assert.deepStrictEqual(unixDay.offset(utc(2010, 11, 31, 23, 59, 59, 456), -2), utc(2010, 11, 29, 23, 59, 59, 456));
});

it("unixDay.offset(date, step) allows step to be negative", () => {
assert.deepStrictEqual(unixDay.offset(utc(2010, 11, 31), -1), utc(2010, 11, 30));
assert.deepStrictEqual(unixDay.offset(utc(2011, 0, 1), -2), utc(2010, 11, 30));
assert.deepStrictEqual(unixDay.offset(utc(2011, 0, 1), -1), utc(2010, 11, 31));
});

it("unixDay.offset(date, step) allows step to be positive", () => {
assert.deepStrictEqual(unixDay.offset(utc(2010, 11, 31), +1), utc(2011, 0, 1));
assert.deepStrictEqual(unixDay.offset(utc(2010, 11, 30), +2), utc(2011, 0, 1));
assert.deepStrictEqual(unixDay.offset(utc(2010, 11, 30), +1), utc(2010, 11, 31));
});

it("unixDay.offset(date, step) allows step to be zero", () => {
assert.deepStrictEqual(unixDay.offset(utc(2010, 11, 31, 23, 59, 59, 999), 0), utc(2010, 11, 31, 23, 59, 59, 999));
assert.deepStrictEqual(unixDay.offset(utc(2010, 11, 31, 23, 59, 58, 0), 0), utc(2010, 11, 31, 23, 59, 58, 0));
});

it("unixDay.count(start, end) counts days after start (exclusive) and before end (inclusive)", () => {
assert.strictEqual(unixDay.count(utc(2011, 0, 1, 0), utc(2011, 4, 9, 0)), 128);
assert.strictEqual(unixDay.count(utc(2011, 0, 1, 1), utc(2011, 4, 9, 0)), 128);
assert.strictEqual(unixDay.count(utc(2010, 11, 31, 23), utc(2011, 4, 9, 0)), 129);
assert.strictEqual(unixDay.count(utc(2011, 0, 1, 0), utc(2011, 4, 8, 23)), 127);
assert.strictEqual(unixDay.count(utc(2011, 0, 1, 0), utc(2011, 4, 9, 1)), 128);
});

it("unixDay.count(start, end) does not observe daylight saving", () => {
assert.strictEqual(unixDay.count(utc(2011, 0, 1), utc(2011, 2, 13, 1)), 71);
assert.strictEqual(unixDay.count(utc(2011, 0, 1), utc(2011, 2, 13, 3)), 71);
assert.strictEqual(unixDay.count(utc(2011, 0, 1), utc(2011, 2, 13, 4)), 71);
assert.strictEqual(unixDay.count(utc(2011, 0, 1), utc(2011, 10, 6, 0)), 309);
assert.strictEqual(unixDay.count(utc(2011, 0, 1), utc(2011, 10, 6, 1)), 309);
assert.strictEqual(unixDay.count(utc(2011, 0, 1), utc(2011, 10, 6, 2)), 309);
});

it("unixDay.count(start, end) returns 364 or 365 for a full year", () => {
assert.strictEqual(unixDay.count(utc(1999, 0, 1), utc(1999, 11, 31)), 364);
assert.strictEqual(unixDay.count(utc(2000, 0, 1), utc(2000, 11, 31)), 365); // leap year
assert.strictEqual(unixDay.count(utc(2001, 0, 1), utc(2001, 11, 31)), 364);
assert.strictEqual(unixDay.count(utc(2002, 0, 1), utc(2002, 11, 31)), 364);
assert.strictEqual(unixDay.count(utc(2003, 0, 1), utc(2003, 11, 31)), 364);
assert.strictEqual(unixDay.count(utc(2004, 0, 1), utc(2004, 11, 31)), 365); // leap year
assert.strictEqual(unixDay.count(utc(2005, 0, 1), utc(2005, 11, 31)), 364);
assert.strictEqual(unixDay.count(utc(2006, 0, 1), utc(2006, 11, 31)), 364);
assert.strictEqual(unixDay.count(utc(2007, 0, 1), utc(2007, 11, 31)), 364);
assert.strictEqual(unixDay.count(utc(2008, 0, 1), utc(2008, 11, 31)), 365); // leap year
assert.strictEqual(unixDay.count(utc(2009, 0, 1), utc(2009, 11, 31)), 364);
assert.strictEqual(unixDay.count(utc(2010, 0, 1), utc(2010, 11, 31)), 364);
assert.strictEqual(unixDay.count(utc(2011, 0, 1), utc(2011, 11, 31)), 364);
});

it("unixDay.every(step) returns every stepth day", () => {
assert.deepStrictEqual(unixDay.every(3).range(utc(2008, 11, 30, 0, 12), utc(2009, 0, 5, 23, 48)), [utc(2008, 11, 31), utc(2009, 0, 3)]);
assert.deepStrictEqual(unixDay.every(5).range(utc(2008, 11, 30, 0, 12), utc(2009, 0, 6, 23, 48)), [utc(2009, 0, 1), utc(2009, 0, 6)]);
assert.deepStrictEqual(unixDay.every(7).range(utc(2008, 11, 30, 0, 12), utc(2009, 0, 8, 23, 48)), [utc(2009, 0, 1), utc(2009, 0, 8)]);
});
7 changes: 3 additions & 4 deletions test/utcTicks-test.js
Expand Up @@ -152,10 +152,9 @@ it("utcTicks(start, stop, count) can generate 1-day ticks", () => {

it("utcTicks(start, stop, count) can generate 2-day ticks", () => {
assert.deepStrictEqual(utcTicks(utc(2011, 0, 2, 16, 28, 27), utc(2011, 0, 9, 21, 34, 12), 4), [
utc(2011, 0, 3, 0, 0),
utc(2011, 0, 5, 0, 0),
utc(2011, 0, 7, 0, 0),
utc(2011, 0, 9, 0, 0)
utc(2011, 0, 4, 0, 0),
utc(2011, 0, 6, 0, 0),
utc(2011, 0, 8, 0, 0)
]);
});

Expand Down

0 comments on commit 850c1c2

Please sign in to comment.