Giter Club home page Giter Club logo

d3-time's Introduction

d3-time

This module implements a convenient API for calendar math, allowing to work with the irregularities of conventional time units, where most months have 31 days but some have 28, 29 or 30; most years have 365 days but leap years have 366; and with daylight saving, most days have 24 hours but some have 23 or 25.

Resources

d3-time's People

Contributors

dependabot[bot] avatar fil avatar gilmoreorless avatar kentr avatar martgnz avatar mbostock avatar pjaspers avatar pluehne avatar ryanrabello avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

d3-time's Issues

day.ceil doesn’t always return boundary dates.

Related #1 #2 d3/d3#1197.

TZ=Asia/Amman node
> d = new Date(2014, 2, 27)
Thu Mar 27 2014 00:00:00 GMT+0200 (EET)
> time.day.ceil(+d + 1)
Thu Mar 27 2014 23:00:00 GMT+0200 (EET)

The expected answer is Fri Mar 28 2014 01:00:00 GMT+0300 (EEST) The problem is that day.ceil relies on offseti, which increments date.setDate.

Equivalent of d3.unixDay for local time

Ref. #58 (comment)

Also, it’s a bit confusing that d3.unixDay doesn’t have the d3.utc prefix like the other UTC time intervals. I wonder if it wouldn’t make more sense to

  1. Rename d3.utcDay to d3.utcMonthDay
  2. Rename d3.timeDay to d3.timeMonthDay
  3. Rename d3.unixDay to d3.utcDay
  4. Create a d3.timeDay that is analogous to the new d3.utcDay (formerly d3.unixDay)

This would make sure that d3.timeTicks is consistent with d3.utcTicks, and eliminate the occasional irregularly-spaced tick at the start of the month.

Date Object reference

The ranges function(timeMonts, timeDay) dont create new Date objects by floor, offset or ceil. It is the some object. In my use case I have a object there have 2 properties: 'from' and 'to'. I create a new Date Object with new Date(). A 'from' property = d3.timeMonth.floor(date) and 'to' property = d3.timeDay.offset(from, -1). If I change a 'from' property, is a 'to' property as too changed(to==from). I think is the same object or reference in memory.

Performance optimization for interval.count.

Datalib is now using d3-time for time calculations. When creating a histogram over large-ish tables with datetime fields, the count method can be called many times (100,000+) to compute bin indices. The multiple object allocations (new Date() calls) start to add up.

How about using temp Date objects instead? For example:

var a = new Date(),
    b = new Date();

if (count) interval.count = function(start, end) {
  a.setTime(+start), b.setTime(+end);
  floori(a), floori(b);
  return Math.floor(count(a, b));
};

(The temp dates might be moved out of the enclosing newInterval function scope.)

Some quick and dirty benchmarks in Chrome (Mac OS) suggest that this can reduce the running time by about 30%.

Expose time.interval?

It’d be nice to allow people to define custom time intervals without relying on interval.filter, if for some reason they want such a thing. Probably the existing API is fine as-is? It seems okay.

How to provide T-minus Time range

I am new to d3 graphs. Please let me know how to make a time range graph.
Angular 2 Version : 2.4.0
Webpack : 2.4

Thanks in advance.

Visualizing date based on Hijri date series

Hello @mbostock ,

I did some investigation in Hijri Date , I found some missing implementation need to be added as setTime, setHours, .. we request that from owner to be able to use it here.
Can you advise the best way to use external library like Hijri Date, with D3-Time. Especially if this library contain "require" function between files. If there an example you can share this will be great.

#23

interval.range should protect against infinite loops.

d3.timeWeek.range(new Date(2017, 6, 10), new Date(2017, 9, 10));

The code above works fine on chrome, but creates an infinite loop on firefox (-v 52.2.0, tested on two different linux machines).
Doing some debugging I ended up here, the do-while never halts. Placing some console.log calls in the code I got the following:

do {
	range.push(new Date(+start));
	if (_dbgstop++ >= 100) {
		throw 'stop';
	}
	console.log(start.toISOString());
	offseti(start, step);
	console.log(start.toISOString());
	floori(start);
	console.log(start.toISOString());
	console.log(stop, start < stop);
} while (start < stop);

firefox:

 d3.timeWeek.range(
    new Date(2017, 6, 10),
    new Date(2017, 9, 10)
);
2017-07-16T03:00:00.000Z  d3-time.js:45:3
2017-07-23T03:00:00.000Z  d3-time.js:47:3
2017-07-23T03:00:00.000Z  d3-time.js:49:3
Date 2017-10-10T03:00:00.000Z true  d3-time.js:50:3
2017-07-23T03:00:00.000Z  d3-time.js:45:3
2017-07-30T03:00:00.000Z  d3-time.js:47:3
2017-07-30T03:00:00.000Z  d3-time.js:49:3
Date 2017-10-10T03:00:00.000Z true  d3-time.js:50:3
2017-07-30T03:00:00.000Z  d3-time.js:45:3
2017-08-06T03:00:00.000Z  d3-time.js:47:3
2017-08-06T03:00:00.000Z  d3-time.js:49:3
Date 2017-10-10T03:00:00.000Z true  d3-time.js:50:3
2017-08-06T03:00:00.000Z  d3-time.js:45:3
2017-08-13T03:00:00.000Z  d3-time.js:47:3
2017-08-13T03:00:00.000Z  d3-time.js:49:3
Date 2017-10-10T03:00:00.000Z true  d3-time.js:50:3
2017-08-13T03:00:00.000Z  d3-time.js:45:3
2017-08-20T03:00:00.000Z  d3-time.js:47:3
2017-08-20T03:00:00.000Z  d3-time.js:49:3
Date 2017-10-10T03:00:00.000Z true  d3-time.js:50:3
2017-08-20T03:00:00.000Z  d3-time.js:45:3
2017-08-27T03:00:00.000Z  d3-time.js:47:3
2017-08-27T03:00:00.000Z  d3-time.js:49:3
Date 2017-10-10T03:00:00.000Z true  d3-time.js:50:3
2017-08-27T03:00:00.000Z  d3-time.js:45:3
2017-09-03T03:00:00.000Z  d3-time.js:47:3
2017-09-03T03:00:00.000Z  d3-time.js:49:3
Date 2017-10-10T03:00:00.000Z true  d3-time.js:50:3
2017-09-03T03:00:00.000Z  d3-time.js:45:3
2017-09-10T03:00:00.000Z  d3-time.js:47:3
2017-09-10T03:00:00.000Z  d3-time.js:49:3
Date 2017-10-10T03:00:00.000Z true  d3-time.js:50:3
2017-09-10T03:00:00.000Z  d3-time.js:45:3
2017-09-17T03:00:00.000Z  d3-time.js:47:3
2017-09-17T03:00:00.000Z  d3-time.js:49:3
Date 2017-10-10T03:00:00.000Z true  d3-time.js:50:3
2017-09-17T03:00:00.000Z  d3-time.js:45:3
2017-09-24T03:00:00.000Z  d3-time.js:47:3
2017-09-24T03:00:00.000Z  d3-time.js:49:3
Date 2017-10-10T03:00:00.000Z true  d3-time.js:50:3
2017-09-24T03:00:00.000Z  d3-time.js:45:3
2017-10-01T03:00:00.000Z  d3-time.js:47:3
2017-10-01T03:00:00.000Z  d3-time.js:49:3
Date 2017-10-10T03:00:00.000Z true  d3-time.js:50:3
2017-10-01T03:00:00.000Z  d3-time.js:45:3
2017-10-08T03:00:00.000Z  d3-time.js:47:3
2017-10-08T03:00:00.000Z  d3-time.js:49:3
Date 2017-10-10T03:00:00.000Z true  d3-time.js:50:3
2017-10-08T03:00:00.000Z  d3-time.js:45:3
2017-10-15T02:00:00.000Z  d3-time.js:47:3
2017-10-08T03:00:00.000Z  d3-time.js:49:3
Date 2017-10-10T03:00:00.000Z true  d3-time.js:50:3
2017-10-08T03:00:00.000Z  d3-time.js:45:3
2017-10-15T02:00:00.000Z  d3-time.js:47:3
2017-10-08T03:00:00.000Z
.... (more of the same)
Error: stop

so offseti increases 2017-10-08T03:00:00.000Z to 2017-10-15T02:00:00.000Z and then floori decreases it back to 2017-10-08T03:00:00.000Z and this keeps going on forever.

for chrome we have:

(sameas ff)...
2017-09-24T03:00:00.000Z
d3-time.js:47 2017-10-01T03:00:00.000Z
d3-time.js:49 2017-10-01T03:00:00.000Z
d3-time.js:50 Tue Oct 10 2017 00:00:00 GMT-0300 (-03) true
d3-time.js:45 2017-10-01T03:00:00.000Z
d3-time.js:47 2017-10-08T03:00:00.000Z
d3-time.js:49 2017-10-08T03:00:00.000Z
d3-time.js:50 Tue Oct 10 2017 00:00:00 GMT-0300 (-03) true
d3-time.js:45 2017-10-08T03:00:00.000Z
d3-time.js:47 2017-10-15T03:00:00.000Z
d3-time.js:49 2017-10-15T03:00:00.000Z
d3-time.js:50 Tue Oct 10 2017 00:00:00 GMT-0300 (-03) false

UTC ticks render at the end of the month instead of the start

If I use utcMonth vs timeMonth as ticks(), the month renders at the end vs the start.

Is it necessary to set both the UTC Date to 1 and UTC Hours to 0,0,0,0? Or am I doing something wrong?

Stack overflow question with image: http://stackoverflow.com/questions/41985959/d3js-x-axis-dates-display-month-at-the-end-not-in-the-front

> date = new Date()
< Wed Feb 01 2017 13:54:32 GMT-0500 (EST)
> date.setUTCDate(1)
< 1485975272606
> date.getUTCMonth()
< 1
> date.getMonth()
< 1
> date.setUTCHours(0, 0, 0, 0)
< 1485907200000
> date.getUTCMonth()
< 1
> date.getMonth()
< 0

Half years for time axis

The time axis seems to consider 3 months or 12 months when it should decide how many ticks to generate. That's a big jump and often leaves the axis with a single tick at the beginning of a year. Axes with a single label are always very hard to read, so a second label at the middle of the year would be necessary. And when jumping from 3 to 12 months interval, there's still plenty of space for selecting 6 months until the time span gets so long that two beginnings of a year appear.

I can halfway work around that by generating ticks and counting them. If the result is 1, I need to suggest more ticks, no matter the available space. But it still has the problem that an axis with ticks at January and July is never displayed and so month names overlap quite a bit before only years are generated. A single tick doesn't tell the user anything. Overlapping labels at least tell the user to assign more space.

interval.every and interval.range generate different result with the same step

the document says

The meaning of step is dependent on this interval’s parent interval as defined by the field function.

and

d3.timeDay’s parent interval is d3.timeMonth, and thus the interval number resets at the start of each month.

but I don't really understand why interval.every and interval.range generate different result with the same step

d3.timeDay.every(3).range(new Date(2022, 2, 25), new Date(2022, 3, 5))
// [
//   2022-03-24T16:00Z,
//   2022-03-27T16:00Z,
//   2022-03-30T16:00Z,
//   2022-03-31T16:00Z, <- why include this value
//   2022-04-03T16:00Z
// ]
d3.timeDay.range(new Date(2022, 2, 25), new Date(2022, 3, 5), 3)
// [
//   2022-01-27T16:00Z,
//   2022-01-30T16:00Z,
//   2022-01-31T16:00Z,
//   2022-02-03T16:00Z
// ]

timeInterval.every(x).count undefined for x > 1

Hi,
I want to be able to count boundaries of interval created from every method, but it seems not to wokr.

d3.timeMinute.every(1).count(from, to); - this works, as expected
d3.timeMinute.every(5).count(form, to); - but in this case count is undefiend, why?

I think it is a bug.

interval.range function fails for Day interval when crossing daylight savings time in Brazilian time zone.

There's seems to be a bug is Safari on iOS (12.0.1, 12.1) and Mac. It's causing the interval.range function to fail for the Day interval in the Brazilian time zone when crossing daylight savings time (Nov 3 - 4). For me it breaks when trying to draw a bottom axis.

The problem is with setDate() which fails on Nov 3, never getting to Nov 4 and going into an infinite loop.

For example if you go to the console of safari on a mac that's been switched to the Brazilian time zone and type:

d = new Date("11/1/2018 00:00");
d.setDate(d.getDate() + 1);d.setHours(0,0,0,0); d;
d.setDate(d.getDate() + 1);d.setHours(0,0,0,0); d;
d.setDate(d.getDate() + 1);d.setHours(0,0,0,0); d;
d.setDate(d.getDate() + 1);d.setHours(0,0,0,0); d;

You'll get:
< Thu Nov 01 2018 00:00:00 GMT-0300 (-03)
< Fri Nov 02 2018 00:00:00 GMT-0300 (-03)
< Sat Nov 03 2018 00:00:00 GMT-0300 (-03)
< Sat Nov 03 2018 00:00:00 GMT-0300 (-03)
< Sat Nov 03 2018 00:00:00 GMT-0300 (-03)

Note without the setHours() it looks like this:

d = new Date("11/1/2018 00:00");
< Thu Nov 01 2018 00:00:00 GMT-0300 (-03)
d.setDate(d.getDate() + 1); d;
< Fri Nov 02 2018 00:00:00 GMT-0300 (-03)
d.setDate(d.getDate() + 1); d;
< Sat Nov 03 2018 00:00:00 GMT-0300 (-03)
d.setDate(d.getDate() + 1); d;
< Sat Nov 03 2018 23:00:00 GMT-0300 (-03) <-- oops. Didn't quite make it.

Off by one hour.

The d3 code is "correct" and the underlying iOS/Mac Safari code is broken. However it still crashes my app (the os eventually kills the runaway thread). For me it's breaking when a bottom axis is drawn that crosses nov 3/4 (in the Brazilian time zone).

I wonder if you'd have any suggestions on how to fix or work around this problem.

PS: Chrome is fine on Mac. Didn't check it on iOS though I heard it's based on Safari or probably WKWebview (which is actually what's crashing for me...iOS app has a big blank page.).

Add ticks, tickInterval?

Now that d3-array has ticks and tickStep extracted from d3-scale, it seems like it’d be nice to provide an equivalent API for time-based ticks. We’d probably have a function named tickInterval instead of tickStep for time intervals, since it will return a time interval.

Related d3/d3-scale#36.

Week starts on Monday

I need to draw a time X axis in a line chart. The exact scale format depends on the total time span and the available screen width, so it's very dynamic. When the axis decides to place ticks only on weeks, it always chooses Sundays. That's not when a week starts here, I need Mondays. I couldn't find anything about that common situation in the documentation. How would I do that? An explanation in the documentation would be helpful.

Please forgive my imprecise wording, I'm still totally confused about the D3 concepts and only find my way through it by copy&paste&try&error.

Incomplete TS type def for `timeTicks`?

Hi,

I'm quite new to TS and this probably isn't the repo for the fix but I wanted to hear from you anyway:

I've got a TS linting error on that that piece of code:

Argument of type 'CountableTimeInterval' is not assignable to parameter of type 'number'

timeTicks(min, max, timeDay)

Unless I'm mistaken the third parameter (count) can either be a number or a time interval. Code is working as expected and it's looking like a false negative from our TS linter probably because this type definition is incomplete?

export function timeTicks(start: Date, stop: Date, count: number): Date[];

Any thoughts?

`timeSecond.every(x)`, x modulo 60 is a restriction?

I try to use d3time.timeSecond.every(x) to create interval, which i use to generate ticks for time scale. The x is dynamic, meaning it depends on the time scale domain and range. Whenever x changes i create new interval for tick creation.

I am almost sure, that it is not a bug. But i would rather ask a question to be 100% sure, or may be to alter the behaviour of the timeSecond interval.

It seems, that x in d3time.timeSecond.every(x) is rounded modulo 60.
When i create interval with say x=320, and pass it to timeScale.ticks i get ticks distributed evenly with 60s distance between one another.

How can i solve my task, given the x may be greater then 60?

I expected that d3time.timeSecond(320) creates an interval, which passed to timeScale.ticks() will produce ticks distributed evenly with 320s distance to one another.
May be i do not see the reason or the restriction which makes mentioned behaviour impossible

p.s.: huh, sounds messy, sorry for that, i did my best to describe my case.
p.s.2: i will try to provide a sample code for clarification soon

Time format incorrect result

I stumbled across a case where format returns the wrong time:

var format = d3.time.format("%Y-%m-%d %H:%I:%S");
console.log(format(new Date("2016-12-08T08:10:58.844Z")));
console.log(format(new Date("2016-12-08T08:11:00.751Z")));

Returns

2016-12-08 10:10:58
2016-12-08 10:10:00

Build breaks with latest Rollup

After upgrading to Rollup 0.27.0 (on d3-time 0.2.5), I see the following error:

A module cannot have multiple exports with the same name ('utcSecond')
Error: A module cannot have multiple exports with the same name ('utcSecond')
    at /Users/curran/repos/reactive-vis/node_modules/rollup/src/Module.js:144:13
    at Array.forEach (native)
    at Module.addExport (/Users/curran/repos/reactive-vis/node_modules/rollup/src/Module.js:139:21)
    at /Users/curran/repos/reactive-vis/node_modules/rollup/src/Module.js:183:51
    at Array.forEach (native)
    at Module.analyse (/Users/curran/repos/reactive-vis/node_modules/rollup/src/Module.js:181:19)
    at new Module (/Users/curran/repos/reactive-vis/node_modules/rollup/src/Module.js:59:8)
    at /Users/curran/repos/reactive-vis/node_modules/rollup/src/Bundle.js:188:20

Indeed utcSecond is being exported twice:

Line 38

export var utcSecond = second;

Line 70

export {
  ...
  utcSecond,
  ...
};

d3.timeMonth.offset() returns not the best thing for final days of the month

console.log(data.pDate); //Mon Dec 31 2018 00:00:00 GMT-0500 (Eastern Standard Time)
console.log(d3.timeMonth.offset(data.pDate, 2)); //Sun Mar 03 2019 00:00:00 GMT-0500 (Eastern Standard Time)

Im not sure this is "wrong", but it seems as though if I add month intervals from a date value that is higher than the shortest month of the year (29 or 28 i guess), I will either continue to accumulate extra days indefinitely, or just regularly run into the next month.

How can I insure the last day of the month always returns the last day of the month, but the 7th always returns the 7th?

Hours may not be 60 minutes due to DST.

I don’t think any current DST algorithm has non-whole-hour offset, but it was definitely true in the past:

Today clocks are almost always set one hour back or ahead, but throughout history there have been several variations, like half adjustment (30 minutes) or double adjustment (two hours), and adjustments of 20 and 40 minutes have also been used. A two-hour adjustment was used in several countries during the 1940s and elsewhere at times.

A half adjustment was sometimes used in New Zealand in the first half of the 20th century. Australia's Lord Howe Island (UTC+10:30) follows a DST schedule in which clocks are moved 30 minutes forward to UTC+11, which is Australian Eastern Daylight Time (AEDT) during DST.

Filtered intervals' offset() function doesn't work correctly when step is negative

The offset() function of filtered intervals doesn't seem to work as intended when the given step is negative:

const interval = d3.utcMinute.every(15);
const date = new Date("Fri, 14 Jul 2017 12:07:23 GMT");
console.log(interval.offset(date, 1).toUTCString()); // Fri, 14 Jul 2017 12:15:23 GMT (correct)
console.log(interval.offset(date, -1).toUTCString()); // Fri, 14 Jul 2017 12:07:23 GMT (incorrect)

(Here's a runnable version on CodePen.)

Looking at the D3 code, the problem is pretty clear:

if (date >= date) while (--step >= 0) while (offseti(date, 1), !test(date)) {}

Infinite loop in d3.timeHour.range.

Sometimes date.setMinutes loses an hour rather than rounding down to the start of the current hour:

var date = new Date(1478419200000); // Sun Nov 06 2016 01:00:00 GMT-0700 (PDT)
date.setTime(+date + 1 * 36e5); // Sun Nov 06 2016 01:00:00 GMT-0800 (PST)
date.setMinutes(0, 0, 0); // Sun Nov 06 2016 01:00:00 GMT-0700 (PDT)

Request: export `ticker`

Hey guys,
Thanks for maintaining this.

Is there any chance of exporting ticker() from src/ticks? There are a few projects around that try to use this machinery to build a timezone-aware scale (e.g. https://github.com/yamass/d3-luxon/blob/main/src/scale/scaleZoned.js) . Without ticker being exported, these have to reimplement it from scratch.
I'm aware that you probably don't want it part of your stable API, but even exporting it from the internal module in src would be appreciated so users can swim with sharks if they accept the risk.

Thanks again!
Jarrad

day.range doesn’t always return boundary dates.

Related #1 d3/d3#1197. Even if we apply the fix in #1, we can’t simply increment using date.setDate to return the next boundary date:

TZ=Asia/Amman node
> d = new Date(2014, 2, 28, 1)
Fri Mar 28 2014 01:00:00 GMT+0300 (EEST)
> d.setDate(d.getDate() + 1), d
Sat Mar 29 2014 01:00:00 GMT+0300 (EEST)
> time.day(d)
Sat Mar 29 2014 00:00:00 GMT+0300 (EEST)

The slightly weird thing is that interval.offset isn’t supposed to floor—it retains the date’s local offset relative to the boundary. (So if you have 12:34 PM and you advance by one day, you should still get 12:34 PM on the following day.) But this means that interval.range isn’t implemented correctly since by calling offseti(date, 1), the date may no longer be a boundary date.

I’m not sure that calling floori(date) after offseti(date, 1) is the right fix either, is it? Are there any situations where calling offseti with a step of 1 could skip a day?

range in descending order?

I am expecting this to return current months' all dates in descending order, but it returns empty [] instead

d3.utcDay.range(d3.utcMonth.ceil(now), d3.utcMonth.floor(now), -1)

I know it's easy to call .reverse() on the ascending range, but is there any particular reason no to have it?

day.floor isn’t always idempotent.

Our strategy for the day time interval doesn’t quite work in Asia/Amman:

TZ=Asia/Amman node
> d = new Date(2014, 2, 28, 12)
Fri Mar 28 2014 12:00:00 GMT+0300 (EEST)
> d.setHours(0, 0, 0, 0), d
Thu Mar 27 2014 23:00:00 GMT+0200 (EET)
> d.setHours(0, 0, 0, 0), d
Thu Mar 27 2014 00:00:00 GMT+0200 (EET)

Adapting @jasondavies’ day.floor might be something like this:

function floor(date) {
  var hi = +date,
      dateHi = new Date(hi);
  date.setHours(0, 0, 0, 0);
  var lo = +date,
      dateLo = new Date(lo - 1);
  while (dayEqual(dateLo, date) && lo < hi) {
    var mid = Math.floor((lo + hi) / 2);
    date.setTime(mid), dateLo.setTime(mid - 1);
    if (dayEqual(date, dateHi)) hi = mid;
    else lo = mid + 1;
  }
}

function dayEqual(a, b) {
  return a.getDate() === b.getDate()
      && a.getMonth() === b.getMonth()
      && a.getFullYear() === b.getFullYear();
}

Related d3/d3#1197.

Visualizing data based on Hijri date series

Hello,

As Islamic countries use Hijri date in their day-to-day activities. I suggest to add hijri calculations also to d3 to use its great power of visualizing time series data.

From my point of view, I have two designs for that :

  1. Integrate Hijri calculations module into d3-time library.
    or
  2. Create a separate library let us call it "D3-time-hijri" as an example, it will be exactly like d3-time but generating Hijri dates

interval.range() with option to include the stop interval boundary

If you have a begin and an end date and want to loop through every day including the end date with d3.utcDay.range(), my understanding is I would call:
d3.utcDay.range(new Date("2022-03-08"), nextDay(new Date("2022-04-13")))

with

function nextDay(currentDay) {
  let nextDay = new Date(currentDay);
  nextDay.setDate(currentDay.getDate() + 1);
  return nextDay;
}

If interval range would include an option exclusive which defaults to true, but can be set to false, then one could get the desired result easier.

rangeInclusive

Several times I've faced the situation where .range is desired, but with an inclusive range rather than an exclusive one.

Here's the solution I've been using so for this:

timeDay.range(minDate, timeDay.offset(maxDate, 1))

It occurred to me that it might be nice to have an additional method that does this, maybe called rangeInclusive. That way the above code could be simplified to:

timeDay.rangeInclusive(minDate, maxDate)

It's a minor improvement, but I think a viable improvement. Thoughts?

(FWIW here's the a full example with this need in context https://vizhub.com/curran/e7f414a4a4f942398749e8ea58fe2f4a?edit=files&file=index.js#L47 )

interval.every can return intervals of inconsistent length

It’s weird that d3.utcMonth.every(9) alternates between 3- and 9-month intervals since the field number resets when the year changes. It’d be more obvious if this irregular interval were called d3.utcYearMonth, like we do with d3.utcMonthDay. Same for local time.

Related #62 #63.

timeMinute, timeHour are sometimes wrong (Chrome 67).

For example, given the date 1732-02-22T00:07:00.766:

date = new Date(-7506057601234)

d3.timeSecond works as expected:

d3.timeSecond(date) // 1732-02-22T00:07

d3.timeMinute should return 1732-02-22T00:07, but doesn’t:

d3.timeMinute(date) // 1732-02-22T00:06:02

d3.timeHour should return 1732-02-22T00:00, but doesn’t:

d3.timeHour(date) // 1732-02-21T23:59:02

https://beta.observablehq.com/d/3a8558e7a5a27d6e

The implementation of timeHour and timeMinute assume that minutes are 60-second and 3,600-second multiples from UNIX epoch, but apparently that’s no longer the case in the latest version of Chrome (leap seconds maybe?), so we may require a slower strategy.

Tests are broken on Node 6?

It seems to be related to how Node parses the TZ environment variable and the behavior of date.toString, and not a bug in d3-time.

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.