1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Obsidian Full Calendar Plugin で Google Calendar を ICS 形式で取り込んだときの Timezone を JST に修正する

Last updated at Posted at 2024-11-17

はじめに

普段、Obsidianを使ってタスク管理をしています。
これまでは、Daily Note(Periodic Notes)+ Day Planner を使っていましたが、予定を月表示できる点などに惹かれ、Full Calendar プラグインを試しています。

ここで、Google CalendarをICS形式で取り込んだときに、時刻同期がうまくいかない(JSTに合わない)問題がありました。
GitHubのIssuesに解決方法がまとめてありましたが、少し躓いたのでJST用にまとめておきます。

環境

  • Obsidian v1.7.6
  • Full Calendar 0.10.7

リンク

やり方

  1. ~/.obsidian/plugins/obsidian-full-calendar/main.js を開く
  2. function getDate2 を検索する
  3. function getDate2, function getTime3 は書き換えない
  4. function getTime3 をコピーしてその下などにペーストする
  5. ペーストしたものを以下のようなfunction getTime4に変更する
    function getTime3(t3) {
      if (t3.isDate) {
        return "00:00";
      }
      return DateTime2.fromSeconds(t3.toUnixTime(), { zone: "UTC" }).toISOTime({
        includeOffset: false,
        includePrefix: false,
        suppressMilliseconds: true,
        suppressSeconds: true
      });
    }
    + // setting for JST(UTC+9)
    + // https://github.com/obsidian-community/obsidian-full-calendar/issues/311
    + function getTime4(t3) {
    +   if (t3.isDate) {
    +     return "00:00";
    +   }
    +   return DateTime2.fromSeconds(t3.toUnixTime(), { zone: "UTC+9" }).toISOTime({
    +     includeOffset: false,
    +     includePrefix: false,
    +     suppressMilliseconds: true,
    +     suppressSeconds: true
    +   });
    + }
    
  6. その下にある、function icsToOFC を書き換える
    function icsToOFC(input) {
      if (input.isRecurring()) {
        const rrule = rrulestr(input.component.getFirstProperty("rrule").getFirstValue().toString());
        const allDay = input.startDate.isDate;
        const exdates = input.component.getAllProperties("exdate").map((exdateProp) => {
          const exdate = exdateProp.getFirstValue();
          return getDate2(exdate);
        });
        return __spreadValues({
          type: "rrule",
          title: input.summary,
          id: `ics::${input.uid}::${getDate2(input.startDate)}::recurring`,
          rrule: rrule.toString(),
          skipDates: exdates,
          startDate: getDate2(input.startDate.convertToZone(import_ical.default.Timezone.utcTimezone))
        }, allDay ? { allDay: true } : {
          allDay: false,
          startTime: getTime3(input.startDate.convertToZone(import_ical.default.Timezone.utcTimezone)),
          endTime: getTime3(input.endDate.convertToZone(import_ical.default.Timezone.utcTimezone))
        });
      } else {
        const date = getDate2(input.startDate);
        const endDate = specifiesEnd2(input) && input.endDate ? getDate2(input.endDate) : void 0;
        const allDay = input.startDate.isDate;
        return __spreadValues({
          type: "single",
          id: `ics::${input.uid}::${date}::single`,
          title: input.summary,
          date,
          endDate: date !== endDate ? endDate : void 0
        }, allDay ? { allDay: true } : {
          allDay: false,
    +     // startTime: getTime3(input.startDate),
    +     // endTime: getTime3(input.endDate)
    +     startTime: getTime4(input.startDate),
    +     endTime: getTime4(input.endDate)
        });
      }
    }
    
  7. Obsidianを再起動すると反映されているはずです。

まとめ

他に良い方法等を知っている方がいれば教えてください。
変更した部分をコピーできるように下に貼っておきます。

// src/calendars/parsing/ics.ts
var import_ical = __toModule(require_ical());
function getDate2(t3) {
  return DateTime2.fromSeconds(t3.toUnixTime(), { zone: "UTC" }).toISODate();
}
function getTime3(t3) {
  if (t3.isDate) {
    return "00:00";
  }
  return DateTime2.fromSeconds(t3.toUnixTime(), { zone: "UTC" }).toISOTime({
    includeOffset: false,
    includePrefix: false,
    suppressMilliseconds: true,
    suppressSeconds: true
  });
}
//setting for JST(UTC+9)
//https://github.com/obsidian-community/obsidian-full-calendar/issues/311
function getTime4(t3) {
  if (t3.isDate) {
    return "00:00";
  }
  return DateTime2.fromSeconds(t3.toUnixTime(), { zone: "UTC+9" }).toISOTime({
    includeOffset: false,
    includePrefix: false,
    suppressMilliseconds: true,
    suppressSeconds: true
  });
}
function specifiesEnd2(iCalEvent) {
  return Boolean(iCalEvent.component.getFirstProperty("dtend")) || Boolean(iCalEvent.component.getFirstProperty("duration"));
}
function icsToOFC(input) {
  if (input.isRecurring()) {
    const rrule = rrulestr(input.component.getFirstProperty("rrule").getFirstValue().toString());
    const allDay = input.startDate.isDate;
    const exdates = input.component.getAllProperties("exdate").map((exdateProp) => {
      const exdate = exdateProp.getFirstValue();
      return getDate2(exdate);
    });
    return __spreadValues({
      type: "rrule",
      title: input.summary,
      id: `ics::${input.uid}::${getDate2(input.startDate)}::recurring`,
      rrule: rrule.toString(),
      skipDates: exdates,
      startDate: getDate2(input.startDate.convertToZone(import_ical.default.Timezone.utcTimezone))
    }, allDay ? { allDay: true } : {
      allDay: false,
      startTime: getTime3(input.startDate.convertToZone(import_ical.default.Timezone.utcTimezone)),
      endTime: getTime3(input.endDate.convertToZone(import_ical.default.Timezone.utcTimezone))
    });
  } else {
    const date = getDate2(input.startDate);
    const endDate = specifiesEnd2(input) && input.endDate ? getDate2(input.endDate) : void 0;
    const allDay = input.startDate.isDate;
    return __spreadValues({
      type: "single",
      id: `ics::${input.uid}::${date}::single`,
      title: input.summary,
      date,
      endDate: date !== endDate ? endDate : void 0
    }, allDay ? { allDay: true } : {
      allDay: false,
      // startTime: getTime3(input.startDate),
      // endTime: getTime3(input.endDate)
      startTime: getTime4(input.startDate),
      endTime: getTime4(input.endDate)
    });
  }
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?