728x90
시나리오
- 백엔드의 데이터베이스에는 UTC 기준시로 날짜시각을 저장한다.
- 백엔드와 프론트엔드는 ISO-8601 표준 날짜시각 형식 문자열로 주고 받는다.
- UTC 기준 마이크로초를 제거한 ISO-8601 표준 형식 예시는 2022-06-24T10:37:34+00:00와 같다.
- 백엔드에서 생성한 날짜시각 객체는 이력, 로그와 관련된 경우가 많으므로 프론트엔드에서는 출력만 가능할 뿐 변경할 수 없다.
- 프론트엔드에서 생성한 날짜시각 객체는 사용자의 일정과 관련된 경우가 많으므로 백엔드에 저장 시 폼 검증이 상대적으로 느슨하다.
백엔드에서 날짜시각 문자열을 받아 출력해야 하는 경우
UTC 기준 ISO-8601 문자열을 객체로 만든다. DateTime.parse()
final utc = DateTime.parse('2022-06-24T20:39:35+00:00');
print(utc.toIso8601String()); // 2022-06-24T20:39:35.000Z
print(utc.timeZoneName); // UTC
print(utc.timeZoneOffset); // 0:00:00.000000
UTC 기준 객체를 지역시간 기준으로 변경한다. toLocal()
final kst = utc.toLocal();
print(kst.toIso8601String()); // 2022-06-25T05:39:35.000
print(kst.timeZoneName); // 한국 표준시
print(kst.timeZoneOffset); // 9:00:00.000000
프론트엔드에서 날짜시각 객체를 생성해 백엔드에 저장해야 하는 경우
DateTimePicker 등으로 사용자가 선택한 날짜시각으로 객체를 생성한다. DateTime(연, 월, 일, 시, 분, 초)
final birthday = DateTime(2016, 2, 12);
print(birthday.toIso8601String()); // 2016-02-12T00:00:00.000
print(birthday.timeZoneName); // 한국 표준시
print(birthday.timeZoneOffset); // 9:00:00.000000
DateTime(연, 월, 일, 시, 분, 초)로 객체를 만들 경우 지역시 기준으로 날짜시각 객체를 생성한다.
현재 날짜시각으로 객체를 생성한다. DateTime.now()
final now = DateTime.now();
print(now.toIso8601String()); // 2022-06-27T23:12:28.181
print(now.timeZoneName); // 한국 표준시
print(now.timeZoneOffset); // 9:00:00.000000
DateTime.now() 정적 메소드 호출로 현재 날짜시각 객체를 얻을 수 있다.
지역시 기준 날짜시각 객체를 UTC 기준 ISO-8601 문자열 만들기
다트에서 별도의 함수, 메소드를 지원하지 않으므로 직접 toIsoStringAware 같은 헬퍼 함수를 만들어 써야 한다.
String toIsoStringAware(DateTime dt) {
final iso8601 = dt.toIso8601String().substring(0, 19);
if (dt.isUtc) {
return '$iso8601+00:00';
} else {
if (dt.timeZoneOffset.inHours >= 0) {
return '$iso8601+${dt.timeZoneOffset.inHours.toString().padLeft(2, "0")}:00';
} else {
return '$iso8601-${dt.timeZoneOffset.inHours.toString().padLeft(2, "0")}:00';
}
}
}
위 헬퍼 함수 사용 예시이다.
final utc = now.toUtc(); // 지역시 기준으로 UTC 기준으로 변환한다.
print(utc.toIso8601String()); // 2022-06-27T14:35:35.213Z
print(utc.timeZoneName); // UTC
print(utc.timeZoneOffset); // 0:00:00.000000
print(toIsoStringAware(utc)); // 2022-06-27T14:35:35+00:00
이제 2022-06-27T14:35:35+00:00 UTC 기준 ISO-8601 날짜시각 문자열을 백엔드 서버에 전송할 수 있다.
날짜시각 더하고 빼기
날짜시각 객체를 Duration 기간 객체로 더하고 뺄 수 있다.
final now = DateTime.now();
final threeHoursAgo = now.subtract(const Duration(hours: 3)); // 3시간 전
final inHundredDays = now.add(const Duration(days: 100)); // 100일 후
print(now); // 2022-06-28 01:34:51.588
print(threeHoursAgo); // 2022-06-27 22:34:51.588
print(inHundredDays); // 2022-10-06 01:34:51.588
intl 패키지 지역화 출력
import 'dart:async';
import 'package:intl/intl.dart';
import 'package:intl/date_symbol_data_local.dart';
void main() async {
final now = DateTime.now();
// ISO-8601 문자열
print(now.toIso8601String()); // 2022-06-28T11:25:39.000
// 기본 라이브러리
print(DateFormat('yyyy-MM-dd').format(now)); // 2022-06-28
print(DateFormat('HH:mm:ss').format(now)); // 11:25:39
// intl 초기화
await initializeDateFormatting('ko_KR', null);
// 한국어
print(DateFormat.yMMMMd('ko').add_Hms().format(now)); // 2022년 6월 28일 11시 25분 39초
print(DateFormat.yMMMMd('ko').add_jms().format(now)); // 2022년 6월 28일 오전 11:25:39
print(DateFormat.yMd('ko').format(now)); // 2022. 6. 28.
print(DateFormat.Hm('ko').format(now)); // 11:25
print(DateFormat.jm('ko').format(now)); // 오전 11:25
// 영어
print(DateFormat.yMMMMd('en').add_Hms().format(now)); // June 28, 2022 11:25:39
print(DateFormat.yMMMMd('en').add_jms().format(now)); // June 28, 2022 11:25:39 AM
print(DateFormat.yMd('en').format(now)); // 6/28/2022
print(DateFormat.Hm('en').format(now)); // 11:25
print(DateFormat.jm('en').format(now)); // 11:25 AM
}
날짜형식 메소드를 호출하기 전에 Future<void> initializeDateFormatting([String? locale, String? ignored]) 메소드를 호출해서 반드시 초기화해야 한다. 최소한 하나의 로케일은 지정해야 하나 만약 locale, ignored 둘다 지정하지 않으면 모든 로케일을 불러온다.
Future로 반환하는 비동기 함수이므로 await로 기다린다.
Hm 형식은 시간이 두 자리수 0으로 패딩되지만 jm은 패딩되지 않는다. 단, 둘다 분은 또 두 자리수 0으로 패딩된다.
- Hm: 01:02
- jm: 오전 1:02 또는 1:02 AM
단순히 숫자 형식으로만 출력한다면 굳이 intl 패키지 없이 그냥 기본 라이브러리로 충분히 포맷팅 가능하다.
728x90
LIST
'Flutter' 카테고리의 다른 글
Flutter - abstract class (0) | 2023.11.08 |
---|---|
Flutter - 화페 & 숫자 (0) | 2023.11.08 |
Flutter - WebScoket (2) | 2023.11.07 |
Flutter - JWT (1) | 2023.11.07 |
Flutter - 동시성 , 병렬성 , 콜백함수 (0) | 2023.11.07 |