feat(chat): 날짜 구분선 현지화 포매터를 추가한다
This commit is contained in:
@@ -1853,6 +1853,7 @@
|
||||
C0A74100000000000000000F /* UserCreatorChatRoomViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A74000000000000000000F /* UserCreatorChatRoomViewModel.swift */; };
|
||||
C0A741000000000000000010 /* UserCreatorChatRoomView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A740000000000000000010 /* UserCreatorChatRoomView.swift */; };
|
||||
C0A741000000000000000011 /* UserCreatorChatSessionNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A740000000000000000011 /* UserCreatorChatSessionNotification.swift */; };
|
||||
C0A741000000000000000012 /* UserCreatorChatDatePresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A740000000000000000012 /* UserCreatorChatDatePresentation.swift */; };
|
||||
C0A742000000000000000001 /* MainChatRoomsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A740000000000000000001 /* MainChatRoomsResponse.swift */; };
|
||||
C0A742000000000000000002 /* MainChatApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A740000000000000000002 /* MainChatApi.swift */; };
|
||||
C0A742000000000000000003 /* MainChatRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A740000000000000000003 /* MainChatRepository.swift */; };
|
||||
@@ -1877,6 +1878,7 @@
|
||||
C0A74300000000000000000F /* UserCreatorChatRoomViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A74000000000000000000F /* UserCreatorChatRoomViewModel.swift */; };
|
||||
C0A743000000000000000010 /* UserCreatorChatRoomView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A740000000000000000010 /* UserCreatorChatRoomView.swift */; };
|
||||
C0A743000000000000000011 /* UserCreatorChatSessionNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A740000000000000000011 /* UserCreatorChatSessionNotification.swift */; };
|
||||
C0A743000000000000000012 /* UserCreatorChatDatePresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A740000000000000000012 /* UserCreatorChatDatePresentation.swift */; };
|
||||
C0D6E325AEFEEF476E7044AB /* CommunityPostCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE82912F2F111593BE42E33C /* CommunityPostCard.swift */; };
|
||||
C3CFF5936F1BAC5BC12E9DDB /* UpdateContentPreferenceRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDFAA64C2CA4FCBBF00A024 /* UpdateContentPreferenceRequest.swift */; };
|
||||
C4A7064704896D68ACBA135F /* PushNotificationListItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FA7A276BF4A47206ED702A7 /* PushNotificationListItemView.swift */; };
|
||||
@@ -3097,6 +3099,7 @@
|
||||
C0A74000000000000000000F /* UserCreatorChatRoomViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserCreatorChatRoomViewModel.swift; sourceTree = "<group>"; };
|
||||
C0A740000000000000000010 /* UserCreatorChatRoomView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserCreatorChatRoomView.swift; sourceTree = "<group>"; };
|
||||
C0A740000000000000000011 /* UserCreatorChatSessionNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserCreatorChatSessionNotification.swift; sourceTree = "<group>"; };
|
||||
C0A740000000000000000012 /* UserCreatorChatDatePresentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserCreatorChatDatePresentation.swift; sourceTree = "<group>"; };
|
||||
C1165E3F4CA1AB019FC85067 /* LanguageRepository.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LanguageRepository.swift; sourceTree = "<group>"; };
|
||||
C40163E3E9DB325EA984D3C4 /* CreatorChannelFloatingIconButton.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CreatorChannelFloatingIconButton.swift; sourceTree = "<group>"; };
|
||||
C6B18C00DE256DCC53030630 /* Spacing.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Spacing.swift; sourceTree = "<group>"; };
|
||||
@@ -6165,6 +6168,7 @@
|
||||
children = (
|
||||
C0A740000000000000000008 /* UserCreatorChatModels.swift */,
|
||||
C0A740000000000000000009 /* UserCreatorChatDisplayMessage.swift */,
|
||||
C0A740000000000000000012 /* UserCreatorChatDatePresentation.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
@@ -7147,6 +7151,7 @@
|
||||
C0A741000000000000000007 /* MainChatFilter.swift in Sources */,
|
||||
C0A741000000000000000008 /* UserCreatorChatModels.swift in Sources */,
|
||||
C0A741000000000000000009 /* UserCreatorChatDisplayMessage.swift in Sources */,
|
||||
C0A741000000000000000012 /* UserCreatorChatDatePresentation.swift in Sources */,
|
||||
C0A74100000000000000000A /* UserCreatorChatApi.swift in Sources */,
|
||||
C0A74100000000000000000B /* UserCreatorChatRepository.swift in Sources */,
|
||||
C0A74100000000000000000C /* UserCreatorChatWebSocketModels.swift in Sources */,
|
||||
@@ -9031,6 +9036,7 @@
|
||||
C0A743000000000000000007 /* MainChatFilter.swift in Sources */,
|
||||
C0A743000000000000000008 /* UserCreatorChatModels.swift in Sources */,
|
||||
C0A743000000000000000009 /* UserCreatorChatDisplayMessage.swift in Sources */,
|
||||
C0A743000000000000000012 /* UserCreatorChatDatePresentation.swift in Sources */,
|
||||
C0A74300000000000000000A /* UserCreatorChatApi.swift in Sources */,
|
||||
C0A74300000000000000000B /* UserCreatorChatRepository.swift in Sources */,
|
||||
C0A74300000000000000000C /* UserCreatorChatWebSocketModels.swift in Sources */,
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import Foundation
|
||||
|
||||
enum UserCreatorChatDatePresentation {
|
||||
static func title(for date: Date, locale: Locale, calendar: Calendar, timeZone: TimeZone) -> String {
|
||||
var calendar = calendar
|
||||
calendar.timeZone = timeZone
|
||||
|
||||
let formatter = DateFormatter()
|
||||
formatter.locale = locale
|
||||
formatter.timeZone = timeZone
|
||||
formatter.calendar = calendar
|
||||
formatter.doesRelativeDateFormatting = false
|
||||
formatter.setLocalizedDateFormatFromTemplate("yMMMMdEEEE")
|
||||
return formatter.string(from: date)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import Foundation
|
||||
|
||||
@main
|
||||
enum UserCreatorChatDatePresentationCheck {
|
||||
static var assertions = 0
|
||||
|
||||
static func check(_ condition: Bool, _ message: String) {
|
||||
guard condition else { print("FAIL: \(message)"); exit(1) }
|
||||
assertions += 1
|
||||
}
|
||||
|
||||
static func checkTitles(for date: Date, calendar: Calendar, timeZone: TimeZone, expected: [String], label: String) {
|
||||
for (localeID, expectedTitle) in zip(["ko_KR", "en_US", "ja_JP"], expected) {
|
||||
let title = UserCreatorChatDatePresentation.title(
|
||||
for: date,
|
||||
locale: Locale(identifier: localeID),
|
||||
calendar: calendar,
|
||||
timeZone: timeZone
|
||||
)
|
||||
check(title == expectedTitle, "\(label) \(localeID): expected '\(expectedTitle)', got '\(title)'")
|
||||
}
|
||||
}
|
||||
|
||||
static func main() {
|
||||
let utc = TimeZone(secondsFromGMT: 0)!
|
||||
let seoul = TimeZone(identifier: "Asia/Seoul")!
|
||||
let losAngeles = TimeZone(identifier: "America/Los_Angeles")!
|
||||
var calendar = Calendar(identifier: .gregorian)
|
||||
calendar.timeZone = utc
|
||||
var seoulCalendar = calendar
|
||||
seoulCalendar.timeZone = seoul
|
||||
var losAngelesCalendar = calendar
|
||||
losAngelesCalendar.timeZone = losAngeles
|
||||
|
||||
let fixtures: [(label: String, timestamp: String, calendar: Calendar, timeZone: TimeZone, expected: [String])] = [
|
||||
("Gregorian UTC fixture", "2026-10-16T12:00:00Z", calendar, utc,
|
||||
["2026년 10월 16일 금요일", "Friday, October 16, 2026", "2026年10月16日 金曜日"]),
|
||||
("previous year", "2025-10-16T12:00:00Z", calendar, utc,
|
||||
["2025년 10월 16일 목요일", "Thursday, October 16, 2025", "2025年10月16日 木曜日"]),
|
||||
("UTC boundary", "2026-10-16T15:30:00Z", calendar, utc,
|
||||
["2026년 10월 16일 금요일", "Friday, October 16, 2026", "2026年10月16日 金曜日"]),
|
||||
("Seoul boundary in every app locale", "2026-10-16T15:30:00Z", seoulCalendar, seoul,
|
||||
["2026년 10월 17일 토요일", "Saturday, October 17, 2026", "2026年10月17日 土曜日"]),
|
||||
("Los Angeles boundary in every app locale", "2026-10-16T15:30:00Z", losAngelesCalendar, losAngeles,
|
||||
["2026년 10월 16일 금요일", "Friday, October 16, 2026", "2026年10月16日 金曜日"]),
|
||||
("Los Angeles calendar normalized to Seoul", "2026-10-16T15:30:00Z", losAngelesCalendar, seoul,
|
||||
["2026년 10월 17일 토요일", "Saturday, October 17, 2026", "2026年10月17日 土曜日"]),
|
||||
("Seoul calendar normalized to Los Angeles", "2026-10-16T15:30:00Z", seoulCalendar, losAngeles,
|
||||
["2026년 10월 16일 금요일", "Friday, October 16, 2026", "2026年10月16日 金曜日"])
|
||||
]
|
||||
let isoFormatter = ISO8601DateFormatter()
|
||||
for fixture in fixtures {
|
||||
checkTitles(
|
||||
for: isoFormatter.date(from: fixture.timestamp)!,
|
||||
calendar: fixture.calendar,
|
||||
timeZone: fixture.timeZone,
|
||||
expected: fixture.expected,
|
||||
label: fixture.label
|
||||
)
|
||||
}
|
||||
|
||||
let englishMonths = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
|
||||
let englishWeekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
|
||||
let koreanWeekdays = ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"]
|
||||
let japaneseWeekdays = ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"]
|
||||
let today = Date()
|
||||
let yesterday = calendar.date(byAdding: .day, value: -1, to: today)!
|
||||
for (label, date) in [("today without relative wording", today), ("yesterday without relative wording", yesterday)] {
|
||||
let components = calendar.dateComponents([.year, .month, .day, .weekday], from: date)
|
||||
let year = components.year!
|
||||
let month = components.month!
|
||||
let day = components.day!
|
||||
let weekday = components.weekday! - 1
|
||||
checkTitles(
|
||||
for: date,
|
||||
calendar: calendar,
|
||||
timeZone: utc,
|
||||
expected: [
|
||||
"\(year)년 \(month)월 \(day)일 \(koreanWeekdays[weekday])",
|
||||
"\(englishWeekdays[weekday]), \(englishMonths[month - 1]) \(day), \(year)",
|
||||
"\(year)年\(month)月\(day)日 \(japaneseWeekdays[weekday])"
|
||||
],
|
||||
label: label
|
||||
)
|
||||
}
|
||||
print("PASS: \(assertions) assertions")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
root=$(CDPATH= cd -- "$(dirname -- "$0")/../.." && pwd)
|
||||
tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
|
||||
export TMPDIR="$tmp"
|
||||
export CLANG_MODULE_CACHE_PATH="$tmp/clang-cache"
|
||||
export SWIFT_MODULECACHE_PATH="$tmp/swift-cache"
|
||||
export XDG_CACHE_HOME="$tmp/cache"
|
||||
|
||||
swiftc -swift-version 5 -module-cache-path "$SWIFT_MODULECACHE_PATH" \
|
||||
"$root/SodaLive/Sources/V2/Main/Chat/UserCreatorChat/Models/UserCreatorChatModels.swift" \
|
||||
"$root/SodaLive/Sources/V2/Main/Chat/UserCreatorChat/Models/UserCreatorChatDisplayMessage.swift" \
|
||||
"$root/SodaLive/Sources/V2/Main/Chat/UserCreatorChat/Models/UserCreatorChatDatePresentation.swift" \
|
||||
"$root/work/tests/UserCreatorChatDatePresentationCheck.swift" \
|
||||
-o "$tmp/user-creator-chat-date-presentation-check"
|
||||
|
||||
"$tmp/user-creator-chat-date-presentation-check"
|
||||
Reference in New Issue
Block a user