2

In case I have a Date and I want to check if the time is DST I can use a method, such as the following:

function isDST(d) {
  let jan = new Date(d.getFullYear(), 0, 1).getTimezoneOffset();
  let jul = new Date(d.getFullYear(), 6, 1).getTimezoneOffset();
  return Math.max(jan, jul) != d.getTimezoneOffset();    
}

(source here)

In case I use MomentJS library I reach the same in this way:

moment().isDST();

Anyone knows how to do the same with the upcoming Temporal?

Justin Grant
  • 44,807
  • 15
  • 124
  • 208
smartmouse
  • 13,912
  • 34
  • 100
  • 166
  • That assumes that the greater offset is DST, which is not necessarily true. Ireland has two offsets: Irish Standard Time which is +1 and Greenwich Mean Time, which is +0. There is no DST. – RobG Sep 18 '22 at 08:44

2 Answers2

2

I'd recommend not doing this, at least not in this form.

Aside from the Ireland example mentioned in the comment, there are other time zone jurisdictions where there are one-time or non-semiannual changes in the offset from UTC that occurred for other reasons than DST, and any possible isDST() implementation will, by definition, malfunction in these cases. Another example is that Morocco observes year-round DST except during the month of Ramadan. For most of the world's population, "DST" has no meaning at all.

To solve this, I'd start by asking what you are going to use the information for?

If it's, for example, to specify "Daylight" or "Standard" time in the name of a time zone, you could instead use Intl.DateTimeFormat with the { timeZoneName: 'long' } option, which will give you the name of the time zone with this information included.

If you need it as a drop-in replacement for Moment's isDST() method so that you can port an existing system from Moment to Temporal, I'd recommend reimplementing the Moment function exactly, and plan to move away from the concept of "is DST" in the future. (Note, that the Moment documentation also describes this function as a hack that sometimes doesn't provide correct information.)

The body of the Moment function can be found here and the equivalent for Temporal would be:

function isDST(zdt) {
    return (
        zdt.offsetNanoseconds > zdt.with({ month: 1 }).offsetNanoseconds ||
        zdt.offsetNanoseconds > zst.with({ month: 6 }).offsetNanoseconds
    );
}

Another thing that you might need this information for is to interface with other systems that include an "is DST" bit in their data model (which is an incorrect concept, but you might have no choice.) In this case I'd recommend restricting the "is DST" function to a list of allowed time zones that are known to employ the concept of "DST" and returning false in other cases, which should at least filter out some of the false positives.

if (!listOfTimeZoneIDsWithDST.includes(zdt.timeZone.id))
  return false;
ptomato
  • 56,175
  • 13
  • 112
  • 165
1

the temporal api has a offsetNanoseconds read-only property

zdt = Temporal.ZonedDateTime.from('2020-11-01T01:30-07:00[America/Los_Angeles]');
zdt.offsetNanoseconds;
  // => -25200000000000

also there's the with method which returns a new object with specified field being overwritten.

i have to admit i haven't tested it but something like this should basically be the equivalent to your function. (month index starts at 1)

function isDST(d) {
  let jan = d.with({month: 1}).offsetNanoseconds ;
  let jul = d.with({month: 7}).offsetNanoseconds ;

  return Math.min(jan, jul) != d.offsetNanoseconds ;    
}

zoned DateTime

refine dev

web dev simplified

s.Bergmann
  • 194
  • 9
  • 3 issues ... 1: `jul` is undefined and 2: in Temporal, `offset` is inverse of the regular Date offset (i.e, west of GMT is negative as it should be) ... 3. `offset` is a STRING – Jaromanda X Sep 17 '22 at 23:35
  • fix point 2: use `Math.min`, point 3: use `.offsetNanoseconds` – Jaromanda X Sep 17 '22 at 23:39
  • oh whelp. thanks for your debugging. editted it. – s.Bergmann Sep 17 '22 at 23:41
  • I'm using a playground with `@js-temporal/polyfill` version 0.4.2 and I'm getting this error: **with is not a function**. Any hint? – smartmouse Sep 18 '22 at 21:34
  • according to documentation [zonedDateTime proposal - with method](https://tc39.es/proposal-temporal/docs/zoneddatetime.html#with). in github [zonedDate](https://github.com/js-temporal/temporal-polyfill/blob/main/lib/zoneddatetime.ts) it's also included. you passed a zonedDateTime object to the function? – s.Bergmann Sep 19 '22 at 09:28
  • 1
    Ops, solved, thank you! – smartmouse Sep 20 '22 at 17:22