Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Date Sat Mar 11 2023 00:44:06 GMT+0800 (Chinese Standard Time) is recorgnized as Mar 10 in heatmap #337

Open
yaya3939 opened this issue Mar 18, 2023 · 16 comments

Comments

@yaya3939
Copy link

yaya3939 commented Mar 18, 2023

Hello.

There's my data :
[.....,{ date: Date Fri Mar 10 2023 08:00:00 GMT+0800 (Chinese Standard Time), rate: 0 },
{ date: Date Sat Mar 11 2023 00:44:06 GMT+0800 (Chinese Standard Time),rate: 1},.....]

My cal-heatmap should show like this :
In block Mar 10, opacity should be 0, value should be 0. In block Mar 11, opacity should be 0.2, value should be 1.

But now, it works like this :
In block Mar 10, opacity is 0.2, value is 1. In block Mar 11, opacity is 1, value is null.
This means that my data for Mar 11 is recorgnized as data for Mar 10, and Mar 11 become null.

Can you tell me why and how to fix it?

@wa0x6e
Copy link
Owner

wa0x6e commented Mar 18, 2023

How are declaring the date in your data ?

{ date: new Date('Fri Mar 10 2023 08:00:00 GMT+0800 (Chinese Standard Time)'), rate: 0 }

or

{ date: 'Fri Mar 10 2023 08:00:00 GMT+0800 (Chinese Standard Time)', rate: 0 }

@yaya3939
Copy link
Author

new Date() one

@wa0x6e
Copy link
Owner

wa0x6e commented Mar 18, 2023

Are you using a timezone ? https://cal-heatmap.com/docs/options/date#timezone

@yaya3939
Copy link
Author

No, I'm not setting it in my code, cause I want it to change with user's timezone.

@wa0x6e
Copy link
Owner

wa0x6e commented Mar 18, 2023

So I guess you're located yourself in the +8 timezone ?

@yaya3939
Copy link
Author

yes

@wa0x6e
Copy link
Owner

wa0x6e commented Mar 20, 2023

Do you see the same issue here ?

https://jsfiddle.net/3nsrpvL5/

If yes, does enabling the timezone (uncomment the timezone line) solve the issue ?

@yaya3939
Copy link
Author

yaya3939 commented Mar 20, 2023

I've tried this. However, it doesn't work for me.
And I've tried several different way to declare my date, such Date.parse(), make it string. All of these just didn't work.
Finally, I used date.setHours(8), then problem is solved.
So, I think this might not be a timezone issue, but caused by the definition of range of a day?

@wa0x6e
Copy link
Owner

wa0x6e commented Mar 22, 2023

For consistency, date format should always follow ISO 8601 (https://cal-heatmap.com/docs/options/data#x), using any other format may lead to bug, such as the timezone now recognized.

'2018-04-04T16:00:00.000Z'
'2018-04-13 19:18:17.040+02:00'
'2018-04-13 19:18'

The best and robust way will be to use a timestamp format for your dataset

@wa0x6e
Copy link
Owner

wa0x6e commented Mar 23, 2023

Just try with new Date('Fri Mar 10 2023 08:00:00 GMT+0800 (Chinese Standard Time)') on a javascript console (such as Google Chrome dev tools), and you will see that the returned date has lost the timezone setting (unless you're on GMT+8)

@wa0x6e wa0x6e closed this as completed Mar 23, 2023
@yaya3939
Copy link
Author

yaya3939 commented Mar 27, 2023

Hello, sorry to bother you again.
I feel like my explanation about declaration of date is not very clear.
Actually, I did not declare date with timezone.
Here's my code.

const datesMonth = getDatesInRange(firstDay, lastDay);

const dataset = datesMonth.map((d) => {
    const exist= records.find(
      (record) => new Date(record.date).getDate() === d.getDate()
    );
    if (exist) {
      return { ...exist, date: new Date(exist.date).getTime() };
    } else {
      return { date: d.getTime(), rate: 0 };
    }
  });

records is my meaningful data, including rates and dates(not everyday in the month), the format of date is ISO 8601 format.
datesMonth includes every date(time is 00:00:00) in the current month, format of date is Date().
dataset is the data source of cal-heatmap.

No matter I use origin format (mix of 2 types)
or using getTime() to make them all timestamps
or use new Date() make them all Date(),
the result shown in heatmap is the same :
all values of dates before records[n].date and last date of month are null. And timezone related issues occured in some data.
That's why I finally choosed .setHours(8), even obviously this is not a best way.

Would you like to tell me what my problem is? Is it because there is anything wrong with my stitched data?

@wa0x6e
Copy link
Owner

wa0x6e commented Mar 27, 2023

Why don't you just pass datesMonth to the calendar ? There is no need to filter it, and conditionally check for exist.

@galenhuntington
Copy link

I am having the same problem. A date of 2023-05-02T03:00Z (whether in string form or as a numeric time) will be put in the May 2 bucket instead of the May 1 bucket in the heatmap regardless of the time zone. Since my browser is PDT, it should default to May 1.

It suspect the problem is here:

.tz(this.timezone)
.utcOffset(0)

It sets the time zone to this.timezone, but immediately sets it back to UTC using .utcOffset(0). As a result, the .startOf("day") sets the bucket to the UTC midnight:

start = start.startOf(interval as ManipulateType);

This makes the cut-off for the buckets always UTC and ignores the time zone. I may be misunderstanding the code but that's what seems to be happening.

@wa0x6e wa0x6e reopened this May 14, 2023
@empireshades
Copy link

empireshades commented Jan 22, 2024

I am having the same issue even though I set the timestamp to my local time.

My domain is day and subdomain is hour (and also a custom hour template).

My data looks like this:

1703419200000,0
1703422800000,2
1703426400000,5
1703430000000,3
1703433600000,45
1703437200000,3
1703440740000,0
1703444400000,7

But the graphs always render as only UTC. Could it be because of the utcOffset(0) mentioned above? I tried removing this but then got some other errors.

Thanks.

@empireshades
Copy link

Further context

Here is what I am using to draw the calendar:

// Custom template to draw hours in one vertical column
const RowHourTemplate = function (DateHelper) {
    return {
        name: 'hour_same_row',
        parent: 'hour',
        rowsCount() {
          return 24
        },
        columnsCount() {
          return 1
        },
        mapping: (startDate, endDate, defaultValues) =>
            DateHelper.intervals('hour', startDate, DateHelper.date(endDate)).map(
                (d, index) => ({
                  t: d,
                  x: 0,
                  y: index,
                  ...defaultValues,
                })
            ),
    };
};

const cal = new CalHeatmap();
cal.addTemplates(RowHourTemplate);

cal.paint(
    {
        data: {
            source: './usage_hr.csv',
            type: 'csv',
            x: d => +d['epoch'],
            y: d => +d['gallons'],
        },
        date: {
            start: new Date('2023-10-27'),
            highlight: [
                new Date(), // today
            ],
            //timezone: 'America/Los_Angeles', // does not matter if this is uncommented
        },
    range: 90,
    scale: {
        color: {
            range: ['#efefef', 'blue', 'red'],
            type: 'linear',
            interpolate: 'rgb',
            domain: [0, 70, 100],
        },
    },
    domain: {
        type: 'day',
        label: { text: null },
    },
    subDomain: { type: 'hour_same_row', width:6, height: 10, gutter: 1 },
    //subDomain: { type: 'hour'}, // this yields the same output in UTC
    },
);

and here is a snippet of the CSV that is being called:

epoch,gallons
1698440400000,0
1698444000000,0
1698447600000,1
1698451200000,32
1698454800000,43
1698458400000,23
1698462000000,60
1698465600000,0
1698469200000,2
1698472800000,1
1698476400000,0
1698480000000,0
1698483600000,0
1698487200000,0
1698490800000,0
1698494400000,3
1698498000000,11
1698501600000,3
1698505200000,0
1698508800000,16
1698512400000,2
1698516000000,10
1698519600000,54
1698523200000,0
1698526800000,4
1698530400000,7
1698534000000,0

@Wugensheng3
Copy link

Do you see the same issue here ?

你在这里看到同样的问题了吗?

https://jsfiddle.net/3nsrpvL5/

https://jsfiddle.net/3nsrpvL5/

If yes, does enabling the timezone (uncomment the timezone line) solve the issue ?

如果是,启用时区(取消注释时区线)是否解决了问题?

Thank you, buddy. You helped me solve a problem that had been bothering me all night

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants