Skip to content

Instantly share code, notes, and snippets.

@hyuki

hyuki/chat.md Secret

Created April 9, 2023 07:40
Show Gist options
  • Save hyuki/9a914a6e6c206d6f9369359073c28ce8 to your computer and use it in GitHub Desktop.
Save hyuki/9a914a6e6c206d6f9369359073c28ce8 to your computer and use it in GitHub Desktop.
#ChatGPT と結城浩の対話:TypeScriptで日付のフォーマット変換を行うプログラムを書いてもらいました(IFTTT Proのフィルタ用)。

Model: GPT-4

Date: 2023-04-09

TypeScriptで"April 09, 2023 at 04:00PM"という文字列から、"2023-04-09" という文字列、すなわち"YYYY-MM-DD"を得るTypeScriptのコードを教えてください。

以下のTypeScriptコードを使用して、"April 09, 2023 at 04:00PM"という文字列から"2023-04-09"という形式の文字列を得ることができます。

function formatDate(input: string): string {
    const months = {
        January: '01',
        February: '02',
        March: '03',
        April: '04',
        May: '05',
        June: '06',
        July: '07',
        August: '08',
        September: '09',
        October: '10',
        November: '11',
        December: '12',
    };

    const datePattern = /(\w+)\s(\d+),\s(\d{4})/;
    const match = input.match(datePattern);

    if (match) {
        const month = months[match[1]];
        const day = match[2].padStart(2, '0');
        const year = match[3];

        return `${year}-${month}-${day}`;
    }

    throw new Error('Invalid date format');
}

const input = "April 09, 2023 at 04:00PM";
const formattedDate = formatDate(input);
console.log(formattedDate); // Output: "2023-04-09"

このコードでは、formatDate関数が入力文字列を解析し、年、月、日をそれぞれ抽出して、結果の文字列を"YYYY-MM-DD"形式で返します。辞書monthsは月の名前を対応する数字に変換するために使われています。

これは汎用的でいいのですが、TypeScriptのライブラリ関数としては存在しますか。

はい、TypeScriptではdate-fnsというライブラリを使用することで、簡単かつ汎用的に日付を操作できます。まず、date-fnsをプロジェクトにインストールしてください。

npm install date-fns

次に、以下のようにdate-fnsを使用して、指定された文字列から日付を変換できます。

import { parse, format } from 'date-fns';

const input = "April 09, 2023 at 04:00PM";
const parsedDate = parse(input, "MMMM dd, yyyy 'at' hh:mmaa", new Date());
const formattedDate = format(parsedDate, "yyyy-MM-dd");

console.log(formattedDate); // Output: "2023-04-09"

ここでは、parse関数で入力文字列を日付オブジェクトに変換し、format関数を使ってその日付オブジェクトを"YYYY-MM-DD"形式の文字列に変換しています。date-fnsライブラリは非常に強力で、様々な日付操作やフォーマット変換が可能です。

ありがとうございます。

どういたしまして!もし他にもTypeScriptやプログラミングに関する質問があれば、遠慮なくお聞きください。お手伝いできることがあれば喜んで対応いたします。

Property 'padStart' does not exist on type 'string'.というエラーがでるので、padStartを明示的に別関数で書いてもらえますか。

もちろんです。padStartの代わりに自作の関数padLeftを使って、文字列を指定した長さになるまで左側に特定の文字で埋めるようにしましょう。

function padLeft(str: string, targetLength: number, padChar: string): string {
    const padding = targetLength - str.length;

    if (padding <= 0) {
        return str;
    }

    return padChar.repeat(padding) + str;
}

function formatDate(input: string): string {
    const months = {
        January: '01',
        February: '02',
        March: '03',
        April: '04',
        May: '05',
        June: '06',
        July: '07',
        August: '08',
        September: '09',
        October: '10',
        November: '11',
        December: '12',
    };

    const datePattern = /(\w+)\s(\d+),\s(\d{4})/;
    const match = input.match(datePattern);

    if (match) {
        const month = months[match[1]];
        const day = padLeft(match[2], 2, '0');
        const year = match[3];

        return `${year}-${month}-${day}`;
    }

    throw new Error('Invalid date format');
}

const input = "April 09, 2023 at 04:00PM";
const formattedDate = formatDate(input);
console.log(formattedDate); // Output: "2023-04-09"

padLeft関数は、入力文字列strtargetLengthの長さになるまで、左側にpadCharで指定された文字を追加します。この関数を使って、日付の部分を2桁に揃えることができます。

それから、const month = months[match[1] as keyof typeof months];のようにしないとエラーになったので、直しておきました。

すみません、その点を見逃していました。ご指摘いただいたように、const month = months[match[1] as keyof typeof months];とすることで、TypeScriptの型チェックに対応できます。以下に、修正したコードを示します。

function padLeft(str: string, targetLength: number, padChar: string): string {
    const padding = targetLength - str.length;

    if (padding <= 0) {
        return str;
    }

    return padChar.repeat(padding) + str;
}

function formatDate(input: string): string {
    const months = {
        January: '01',
        February: '02',
        March: '03',
        April: '04',
        May: '05',
        June: '06',
        July: '07',
        August: '08',
        September: '09',
        October: '10',
        November: '11',
        December: '12',
    };

    const datePattern = /(\w+)\s(\d+),\s(\d{4})/;
    const match = input.match(datePattern);

    if (match) {
        const month = months[match[1] as keyof typeof months];
        const day = padLeft(match[2], 2, '0');
        const year = match[3];

        return `${year}-${month}-${day}`;
    }

    throw new Error('Invalid date format');
}

const input = "April 09, 2023 at 04:00PM";
const formattedDate = formatDate(input);
console.log(formattedDate); // Output: "2023-04-09"

この修正により、monthsオブジェクトから正しい型で月を取得できます。これで、コンパイルエラーが解消されるはずです。

何度もすみません。padChar.repeat(padding) + str;のrepeatもないと言われましたので、明示的に書いてもらえますか。

もちろんです。repeatメソッドがない場合に対応するため、repeatStringという別の関数を使って同様の処理を行うようにしましょう。

function padLeft(str: string, targetLength: number, padChar: string): string {
    const padding = targetLength - str.length;

    if (padding <= 0) {
        return str;
    }

    return repeatString(padChar, padding) + str;
}

function repeatString(str: string, count: number): string {
    let repeated = '';
    for (let i = 0; i < count; i++) {
        repeated += str;
    }
    return repeated;
}

function formatDate(input: string): string {
    const months = {
        January: '01',
        February: '02',
        March: '03',
        April: '04',
        May: '05',
        June: '06',
        July: '07',
        August: '08',
        September: '09',
        October: '10',
        November: '11',
        December: '12',
    };

    const datePattern = /(\w+)\s(\d+),\s(\d{4})/;
    const match = input.match(datePattern);

    if (match) {
        const month = months[match[1] as keyof typeof months];
        const day = padLeft(match[2], 2, '0');
        const year = match[3];

        return `${year}-${month}-${day}`;
    }

    throw new Error('Invalid date format');
}

const input = "April 09, 2023 at 04:00PM";
const formattedDate = formatDate(input);
console.log(formattedDate); // Output: "2023-04-09"

repeatString関数は、指定された文字列を指定された回数繰り返して連結した結果の文字列を返します。padLeft関数では、このrepeatString関数を使って、padCharを指定された回数繰り返すようにしています。これで、repeatメソッドが存在しない環境でも正常に動作するはずです。

ありがとうございました。うまく動きました。感謝です。

どういたしまして!お力になれてうれしいです。これからもTypeScriptやプログラミングに関する質問があれば、いつでもお気軽にお聞きください。お手伝いできることがあれば喜んで対応いたします。良い一日をお過ごしください!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment