🕐

Flutte YY/MM/DDとか時刻表示?

2025/02/05に公開

日付・時刻フォーマット一覧

仕事で時間の表示を扱う機能を実装することがあった。すでに出来上がっているものを使うのですが、YY/MM/DDってあんまりわかってなかったりする😅

仕事で使っているのは加工してViewに表示するときは、.toString()で表示するメソッドを使いますが今回は日付・時刻フォーマット一覧作りたいなと思い記事書くことにしました。

日付フォーマット

フォーマット説明例主な使用言語/地域YYYY/MM/DD4桁年/2桁月/2桁日2024/02/05日本、中国、韓国などYY/MM/DD2桁年/2桁月/2桁日24/02/05一般的DD/MM/YY2桁日/2桁月/2桁年05/02/24イギリス、オーストラリアなどDD/MM/YYYY2桁日/2桁月/4桁年05/02/2024イギリス、オーストラリアなどMM/DD/YY2桁月/2桁日/2桁年02/05/24アメリカMM/DD/YYYY2桁月/2桁日/4桁年02/05/2024アメリカYYYY-MM-DDISO 8601形式2024-02-05国際標準、データベース

時刻フォーマット

フォーマット説明例備考HH:MM:SS24時間表記14:30:45国際的に一般的HH:MM24時間表記(秒省略)14:30一般的hh:MM:SS AM/PM12時間表記02:30:45 PM英語圏で一般的hh:MM AM/PM12時間表記(秒省略)02:30 PM英語圏で一般的

日付時刻の組み合わせ

フォーマット説明例YYYY-MM-DD HH:MM:SSISO 8601準拠2024-02-05 14:30:45YYYY/MM/DD HH:MM:SS日本式2024/02/05 14:30:45DD/MM/YYYY HH:MM:SSイギリス式05/02/2024 14:30:45MM/DD/YYYY HH:MM:SSアメリカ式02/05/2024 14:30:45

プログラミング言語での一般的な記法

言語フォーマット例説明Javayyyy-MM-dd HH:mm:ssSimpleDateFormat使用Python%Y-%m-%d %H:%M:%Sstrftime使用PHPY-m-d H:i:sdate()関数使用JavaScriptYYYY-MM-DD HH:mm:ssMoment.js等のライブラリ使用Ruby%Y-%m-%d %H:%M:%Sstrftime使用SQLYYYY-MM-DD HH:MI:SSTIMESTAMP型

記号の意味

日付

  • Y/y: 年(YYYY=4桁年、YY=2桁年)
  • M/m: 月
  • D/d: 日

時刻

  • H/h: 時(H=24時間表記、h=12時間表記)
  • M/m: 分
  • S/s: 秒

注意点

  • 2桁年表記(YY)は世紀の判断があいまいになるため、4桁年表記(YYYY)が推奨
  • タイムゾーンの取り扱いに注意が必要
  • データベースでは ISO 8601形式(YYYY-MM-DD)が推奨
  • 国際化対応する場合は、地域ごとの日付形式の違いに注意が必要

Dartだとどうなる?

Dartでの日付時刻の扱いについて、主なポイントを説明します:

intlが必要なので追加する。

  1. 基本的な使い方:

    • Dartでは DateTime クラスを使用します
    • フォーマットには intl パッケージの DateFormat クラスを使用します
  2. 重要な特徴:

    • タイムゾーンの扱いが柔軟
    • 和暦表示にも対応
    • 国際化(i18n)に対応
  3. 実装時の注意点:

    • intl パッケージの追加が必要
    • タイムゾーンを意識した実装が重要
    • パターン文字の組み合わせで柔軟なフォーマットが可能
  4. よく使う機能:

    • 日付の計算(add/subtract)
    • フォーマット変換
    • タイムゾーン変換

Flutterで使用例

仕事だとロジック書いて時間を加工して、toStringで返すメソッドを何種類か作りますが今回は単純なデジタル時計かな。これを表示してみるだけのコードにしました。仕事だとねー名前つきコンストラクタに、年・日付・日渡したり複雑なコードになってしまうので単純化しました。

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'dart:async';
import 'package:intl/date_symbol_data_local.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await initializeDateFormatting('ja_JP', null);
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const DateTimeDisplay(),
    );
  }
}

class DateTimeDisplay extends StatefulWidget {
  const DateTimeDisplay({super.key});

  
  _DateTimeDisplayState createState() => _DateTimeDisplayState();
}

class _DateTimeDisplayState extends State<DateTimeDisplay> {
  late Timer _timer;
  DateTime _currentDateTime = DateTime.now();
  String _selectedFormat = 'standard';

  
  void initState() {
    super.initState();
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      setState(() {
        _currentDateTime = DateTime.now();
      });
    });
  }

  
  void dispose() {
    _timer.cancel();
    super.dispose();
  }

  String _formatDate(DateTime date, String format) {
    switch (format) {
      case 'standard':
        return DateFormat('yyyy/MM/dd HH:mm:ss').format(date);
      case 'iso':
        return date.toIso8601String();
      case 'japanese':
        return DateFormat('GGGGy年MM月dd日 HH時mm分ss秒', 'ja_JP').format(date);
      default:
        return DateFormat('yyyy/MM/dd HH:mm:ss').format(date);
    }
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('日付時刻表示'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Card(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                // 時刻表示
                Container(
                  padding: const EdgeInsets.all(16.0),
                  decoration: BoxDecoration(
                    color: Colors.grey[100],
                    borderRadius: BorderRadius.circular(8.0),
                  ),
                  child: Text(
                    _formatDate(_currentDateTime, _selectedFormat),
                    style: const TextStyle(
                      fontSize: 24,
                      fontFamily: 'monospace',
                    ),
                  ),
                ),
                const SizedBox(height: 16),

                // フォーマット切り替えボタン
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    ElevatedButton(
                      onPressed: () =>
                          setState(() => _selectedFormat = 'standard'),
                      style: ButtonStyle(
                        backgroundColor: WidgetStateProperty.all(
                          _selectedFormat == 'standard'
                              ? Colors.blue
                              : Colors.grey,
                        ),
                      ),
                      child: const Text('標準'),
                    ),
                    const SizedBox(width: 8),
                    ElevatedButton(
                      onPressed: () => setState(() => _selectedFormat = 'iso'),
                      style: ButtonStyle(
                        backgroundColor: WidgetStateProperty.all(
                          _selectedFormat == 'iso' ? Colors.blue : Colors.grey,
                        ),
                      ),
                      child: const Text('ISO'),
                    ),
                    const SizedBox(width: 8),
                    ElevatedButton(
                      onPressed: () =>
                          setState(() => _selectedFormat = 'japanese'),
                      style: ButtonStyle(
                        backgroundColor: WidgetStateProperty.all(
                          _selectedFormat == 'japanese'
                              ? Colors.blue
                              : Colors.grey,
                        ),
                      ),
                      child: const Text('和暦'),
                    ),
                  ],
                ),
                const SizedBox(height: 16),

                // 説明テキスト
                Container(
                  alignment: Alignment.centerLeft,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: const [
                      Text(
                        '表示フォーマット:',
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                          fontSize: 16,
                        ),
                      ),
                      SizedBox(height: 8),
                      Text('• 標準: YYYY/MM/DD HH:mm:ss'),
                      Text('• ISO: YYYY-MM-DDTHH:mm:ss.sssZ'),
                      Text('• 和暦: 令和YY年MM月DD日 HH時mm分ss秒'),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

最後に

時間の表示って難しいですよね😅
算数の知識が必要か知らないですが仕事で使うことあるのでその時に合わせてこれがいいのかってフォーマットで試してますね。YYyyと英語の大文字・小文字で内容も変わるようです。

https://e-words.jp/w/YYYYMMDD形式.html#:~:text=4桁の西暦を,0101」のように表す。
https://www.ibm.com/docs/ja/cmofz/10.5.0?topic=reference-date-time-formats

Discussion