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

No updates from 2024 #29

Open
jrobbl opened this issue Jan 2, 2024 · 3 comments
Open

No updates from 2024 #29

jrobbl opened this issue Jan 2, 2024 · 3 comments

Comments

@jrobbl
Copy link

jrobbl commented Jan 2, 2024

First of all, great plugin!
I've been using it for some weeks now and noticed it shows no statistics for the two days of 2024 (I mean in the panel).
Any ideas?

@jrobbl
Copy link
Author

jrobbl commented Jan 3, 2024

I think this might have to do with the way the count is being stored at .obsidian/plugins/obsidian-daily-stats/data.json
See for example the "2024/0/1": 448?

Screenshot from 2024-01-03 07-25-40

@Wensupu-Yang
Copy link

I'm having the same problem. My last day it working was on 2024-01-01, after that, I write everyday but no states
Screenshot 2024-01-12 at 2 28 02 PM

@aiurye
Copy link

aiurye commented Jan 4, 2025

我询问了gemini,根据指示修改之后ok了,唯一的问题是之前的记录都往前移了一个月:

你提供的代码主要是一个日历热图的React组件。问题在于日期在存储和展示过程中,月份的处理方式不一致,导致data.json中月份显示为0。

问题根源:

JavaScript的Date对象中,getMonth()方法返回的月份是从0开始计数的(0代表一月,1代表二月,以此类推)。而我们通常习惯用1-12来表示月份。你的代码中,在从data.json读取日期数据并传递给reactCalendarHeatmap_umd组件时,以及在titleForValue函数中显示日期时,没有正确处理这个差异。

错误代码及修改:

  1. StatsTrackerView组件中的数据转换:

    JavaScript

    reactDom.render(react.createElement(Heatmap, {
        data: Object.keys(this.dayCounts).map(day => {
            return { "date": new Date(new Date(day).setMonth(new Date(day).getMonth() + 1)), "count": this.dayCounts[day] };
        }),
    }), this.contentEl);
    

    这段代码是导致data.json中月份错误的关键。你在这里创建了一个新的Date对象,然后又调用了setMonth方法,并且把原月份加1,导致重复加1。

    正确修改:

    JavaScript

    reactDom.render(react.createElement(Heatmap, {
        data: Object.keys(this.dayCounts).map(day => {
            return { "date": new Date(day), "count": this.dayCounts[day] }; // 直接使用 day 字符串创建 Date 对象
        }),
    }), this.contentEl);
    

    直接使用new Date(day)day的格式是yyyy/mm/ddDate构造函数会自动处理月份的转换,无需手动加1。

  2. titleForValue函数中的日期显示:

    JavaScript

    titleForValue: (value) => !value || value.date === null ? '' : value.count + ' words on ' + new Date(value.date).toLocaleDateString()
    

    这段代码在显示日期时使用了toLocaleDateString()方法,这个方法会根据用户的locale设置来格式化日期,通常会正确显示月份(1-12)。但是,如果value.date本身就是一个月份错误的Date对象(比如通过上面的错误代码创建的),那么显示出来的日期也会是错误的。

    虽然这段代码本身没有直接的错误(它只是显示日期),但是需要配合上面的修改一起使用,才能确保显示正确的日期。

完整修改示例(StatsTrackerView部分):

JavaScript

class StatsTrackerView extends obsidian.ItemView {
    // ... 其他代码

    onOpen() {
        return __awaiter(this, void 0, void 0, function* () {
            reactDom.render(react.createElement(Heatmap, {
                data: Object.keys(this.dayCounts).map(day => {
                    return { "date": new Date(day), "count": this.dayCounts[day] }; // 正确的日期转换
                }),
                horizontal: false,
                showMonthLabels: true,
                showWeekdayLabels: true,
                weekdayLabels: ["S", "M", "T", "W", "T", "F", "S"],
                classForValue: (value) => {
                    if (!value || value.count == 0) {
                        return 'color-empty';
                    }
                    return `color${getColorLevel(value.count)}`;
                },
                titleForValue: (value) => !value || value.date === null ? '' : value.count + ' words on ' + new Date(value.date).toLocaleDateString() // 正确显示日期
            }), this.contentEl);
        });
    }

    // ... 其他代码
}

总结:

通过以上修改,你可以避免在data.json中存储错误的日期,并确保在热图上正确显示日期。核心是直接使用日期字符串创建Date对象,避免手动操作月份导致重复加1。修改后,data.json中应该会存储正确的日期格式,例如"2025/1/2"而不是"2025/0/2"

希望以上解释能够帮助你理解并解决问题。如果还有其他问题,欢迎继续提问。


你提到修改了代码之后,原本的数据可以正常显示了,但是新生成的日期仍然是 "2025/0/4": 11 这样的格式,说明问题不仅仅在于读取数据时的转换,还在于写入数据时的格式化。

根据你提供的代码,日期字符串的生成是在 updateDate() 函数中:

JavaScript

updateDate() {
    const d = new Date();
    this.today = d.getFullYear() + "/" + d.getMonth() + "/" + d.getDate();
}

这里 d.getMonth() 返回的是从 0 开始的月份索引(0 代表一月,1 代表二月,以此类推),所以当月份是 1 月时,d.getMonth() 返回 0,导致日期字符串变成 "2025/0/4" 这样的错误格式。

正确的修改方法是使用 String.prototype.padStart() 方法来格式化月份和日期,确保始终是两位数:

JavaScript

updateDate() {
    const d = new Date();
    const year = d.getFullYear();
    const month = String(d.getMonth() + 1).padStart(2, '0'); // 月份加 1 并补零
    const day = String(d.getDate()).padStart(2, '0');       // 日期补零
    this.today = `${year}/${month}/${day}`;
}

解释:

  • d.getMonth() + 1:将月份索引从 0-11 转换为 1-12。
  • String(...):将数字转换为字符串。
  • padStart(2, '0'):在字符串前面填充 0,直到字符串长度为 2。例如,数字 1 会被转换为字符串 "01",数字 12 则保持不变。

完整修改示例:

JavaScript

class DailyStats extends obsidian.Plugin {
    // ... 其他代码

    updateDate() {
        const d = new Date();
        const year = d.getFullYear();
        const month = String(d.getMonth() + 1).padStart(2, '0');
        const day = String(d.getDate()).padStart(2, '0');
        this.today = `${year}/${month}/${day}`; // 使用模版字符串
    }

    // ... 其他代码
}

**此外,为了代码的健壮性,建议在其他地方也进行类似的格式化,比如在将日期显示在界面上时。**虽然 toLocaleDateString() 通常能正确显示日期,但在内部存储和处理日期时,使用统一的格式(例如 yyyy/MM/dd)会更清晰和可靠。

总结:

通过修改 updateDate() 函数,使用 padStart() 方法格式化月份和日期,可以确保新生成的日期字符串格式正确,避免 data.json 中出现月份为 0 的错误。同时,保持日期格式的一致性,有助于提高代码的可读性和维护性。

修改后,新生成的日期应该是 "2025/01/04" 这样的格式。如果还有其他问题,欢迎继续提问。

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

3 participants