DartのDateTimeについて調べる

Dart APIリファレンスのDateTimeのページを読んでいく
動作確認にはDartPadを使う

現在時刻の表示
void main() {
final now = DateTime.now();
print(now); // 2022-11-04 10:16:07.562
}
Zがついてないのでローカルタイム

誕生日をUTCで表示
void main() {
final birthday = DateTime.utc(1987,8,27);
print(birthday); // 1987-08-27 00:00:00.000Z
}
ちゃんとZがついている
そして月がJavaScriptと使って1スタートなのが嬉しい

文字列からパース
void main() {
final birthday = DateTime.parse('1987-08-27T00:00:00Z');
print(birthday); // 1987-08-27 00:00:00.000Z
}
間のTはあってもなくても良い

DateTimeオブジェクトはUTCかローカルタイムにアンカーされると書いてある
A DateTime object is anchored either in the UTC time zone or in the local time zone of the current computer when the object is created.

DateTimeオブジェクトは時刻やタイムゾーンを後から変えられない
Once created, neither the value nor the time zone of a DateTime object may be changed.
void main() {
final birthday = DateTime.parse('1987-08-27T00:00:00Z');
birthday.day = 10;
print(birthday); // 1987-08-27 00:00:00.000Z
}
エラーメッセージ
Error compiling to JavaScript:
Info: Compiling with sound null safety
lib/main.dart:5:12:
Error: The setter 'day' isn't defined for the class 'DateTime'.
- 'DateTime' is from 'dart:core'.
birthday.day = 10;
^^^
Error: Compilation failed.
セッターが無いと言われている

year
などのプロパティで個々の数字にアクセスできる
void main() {
final birthday = DateTime.parse('1987-08-27T00:00:00Z');
print(birthday.year); // 1987
print(birthday.month); // 8
print(birthday.day); // 27
print(birthday.hour); // 0
print(birthday.minute); // 0
print(birthday.second); // 0
}
hour
以下も単数系、JavaScriptとは違う

DateTimeには定数がある
void main() {
print(DateTime.january); // 1
print(DateTime.monday); // 1
print(DateTime.sunday); // 7
}
月は1スタート、曜日は月曜日からの1スタート
ちなみに曜日はweekday
プロパティを使ってアクセスできる

UTCかどうかはisUtc
プロパティを使う
void main() {
final now = DateTime.now();
final birthday = DateTime.utc(1987, 8, 27);
print(now.isUtc); // false
print(birthday.isUtc); // true
}

toLocal
とtoUtc
メソッドを使って相互に変換できる
void main() {
final now = DateTime.now();
final birthday = DateTime.utc(1987, 8, 27);
print(now.toUtc()); // 2022-11-04 01:33:33.183Z
print(birthday.toLocal()); // 1987-08-27 09:00:00.000
}

timeZoneName
とtimeZoneOffset
プロパティを使うとタイムゾーンの名前やオフセットが確認できる。
void main() {
final now = DateTime.now();
final birthday = DateTime.utc(1987, 8, 27);
print(now.timeZoneName); // 日本標準時
print(now.timeZoneOffset); // 9:00:00.000000
print(birthday.timeZoneName); // UTC
print(birthday.timeZoneOffset); // 0:00:00.000000
}

isBefore
とisAfter
メソッドを使うと後先を確認できる
void main() {
final now = DateTime.now();
final birthday = DateTime.utc(1987, 8, 27);
print(now.isAfter(birthday)); // true
print(now.isBefore(birthday)); // false
}
isAtSameMomentAs
メソッドを使うと同じか否かを確認できる
ローカルかUTCかは考慮されない

Durationを使うと足し算(add)や引き算(subtract)ができる、便利
void main() {
final birthday = DateTime.utc(1987, 8, 27);
print(birthday.add(Duration(days: 100))); // 1987-12-05
}
Durationの引数は複数形、私の100日記念は12/5だった模様

日付を比較してDurationを作成することも可能
void main() {
final birthday = DateTime.utc(1987, 8, 27);
final birthdaySister = DateTime.utc(1985, 12, 9);
print(birthday.difference(birthdaySister)); // 15024:00:00.000000
print(birthday.difference(birthdaySister).inDays); // 626
}
私は姉の626日後に誕生したようだ

以上がDateTimeクラスのページの内容、説明が素晴らしいので機能がほぼ網羅されている
残りのプロパティやメソッドについても調べていく

その他のコンストラクタ
- DateTime:ローカルタイムであることを除いてDateTime.utcと同じ
- DateTime.fromMicrosecondsSinceEpoch:1970-01-01Zからのマイクロ秒で指定
- DateTime.fromMillisecondsSinceEpoch constructor:1970-01-01Zからのミリ秒で指定
SinceEpoch系のメソッドは第2引数としてisUtc
を受け取る、文字通りUtcであるか否か

microsecondsSinceEpoch
とmillisecondsSinceEpoch
プロパティはそれぞれエポックからのマイクロ秒とミリ秒

toIso8601String
を使うとISO8601日次文字列に変換できる
void main() {
final birthday = DateTime.utc(1987, 8, 27);
print(birthday.toIso8601String()); // 1987-08-27T00:00:00.000Z
}
API通信などの場面で便利そう

比較演算子==
はタイムゾーンまでチェックするので厳格
void main() {
final birthday = DateTime.utc(1987, 8, 27);
final birthdayLocal = DateTime(1987, 8, 27, 9, 0, 0);
print(birthday == birthdayLocal); // false
print(birthday.isAtSameMomentAs(birthdayLocal)); // true
}

DateTime.parse
とDateTime.tryParse
メソッドは文字列をパースしてDateTimeオブジェクトを作成する
parse
の方はパースできないと例外を発生させるが、tryParse
の方はNullを返す
かなり幅広いフォーマットに対応している
"2012-02-27"
"2012-02-27 13:27:00"
"2012-02-27 13:27:00.123456789z"
"2012-02-27 13:27:00,123456789z"
"20120227 13:27:00"
"20120227T132700"
"20120227"
"+20120227"
"2012-02-27T14Z"
"2012-02-27T14+00:00"
"-123450101 00:00:00 Z": in the year -12345.
"2002-02-27T14:00:00-0500": Same as "2002-02-27T19:00:00Z"

以上で一旦終わり
DartのDateTimeはJavaScriptのDateよりもとても使いやすそう

次はListについて調べよう