fix(live): 종료 라이브 상대시간을 로컬 기준으로 국제화한다

This commit is contained in:
2026-03-05 11:24:01 +09:00
parent 2e700d4385
commit d83c4b12ec
6 changed files with 123 additions and 2 deletions

View File

@@ -8,5 +8,6 @@ data class GetLatestFinishedLiveResponse(
@SerializedName("memberId") val memberId: Long,
@SerializedName("nickname") val nickname: String,
@SerializedName("profileImageUrl") val profileImageUrl: String,
@SerializedName("timeAgo") val timeAgo: String
@SerializedName("timeAgo") val timeAgo: String,
@SerializedName("dateUtc") val dateUtc: String
)

View File

@@ -5,7 +5,14 @@ import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.databinding.ItemLatestFinishedLiveBinding
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import java.util.TimeZone
class LatestFinishedLiveAdapter(
private val onClick: (Long) -> Unit
@@ -49,8 +56,87 @@ class LatestFinishedLiveAdapter(
.into(binding.ivProfile)
binding.tvNickname.text = item.nickname
binding.tvTimeAgo.text = item.timeAgo
binding.tvTimeAgo.text = relativeTimeText(item)
binding.root.setOnClickListener { onClick(item.memberId) }
}
private fun relativeTimeText(item: GetLatestFinishedLiveResponse): String {
val pastMillis = parseDateUtcToMillis(item.dateUtc)
if (pastMillis == null) {
return item.timeAgo
}
val timezone = TimeZone.getDefault()
val nowCalendar = Calendar.getInstance(timezone, Locale.getDefault())
val pastCalendar = Calendar.getInstance(timezone, Locale.getDefault()).apply {
timeInMillis = pastMillis
}
val minute = 60_000L
val hour = 60 * minute
val day = 24 * hour
val diff = (nowCalendar.timeInMillis - pastCalendar.timeInMillis).coerceAtLeast(0L)
return when {
diff < minute -> context.getString(R.string.latest_finished_live_time_just_now)
diff < hour -> {
val minutes = (diff / minute).toInt()
context.getString(R.string.latest_finished_live_time_minutes, minutes)
}
diff < day -> {
val hours = (diff / hour).toInt()
context.getString(R.string.latest_finished_live_time_hours, hours)
}
else -> {
val days = (diff / day).toInt()
context.getString(R.string.latest_finished_live_time_days, days)
}
}
}
private fun parseDateUtcToMillis(dateUtc: String?): Long? {
if (dateUtc.isNullOrBlank()) return null
val value = dateUtc.trim()
if (value.all { it.isDigit() }) {
return try {
val epoch = value.toLong()
if (value.length <= 10) epoch * 1000 else epoch
} catch (exception: NumberFormatException) {
null
}
}
val patterns = listOf(
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX",
"yyyy-MM-dd'T'HH:mm:ssXXX",
"yyyy-MM-dd'T'HH:mm:ss.SSSX",
"yyyy-MM-dd'T'HH:mm:ssX",
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
"yyyy-MM-dd'T'HH:mm:ss'Z'",
"yyyy-MM-dd'T'HH:mm:ss.SSS",
"yyyy-MM-dd'T'HH:mm:ss",
"yyyy-MM-dd HH:mm:ss",
"yyyy/MM/dd HH:mm:ss"
)
for (pattern in patterns) {
try {
val dateFormat = SimpleDateFormat(pattern, Locale.US)
dateFormat.timeZone = TimeZone.getTimeZone("UTC")
val parsed: Date? = dateFormat.parse(value)
if (parsed != null) {
return parsed.time
}
} catch (exception: ParseException) {
continue
}
}
return null
}
}
}

View File

@@ -272,6 +272,10 @@
<string name="character_comment_time_days">%1$d d ago</string>
<string name="character_comment_time_months">%1$d mo ago</string>
<string name="character_comment_time_years">%1$d y ago</string>
<string name="latest_finished_live_time_just_now">Just now</string>
<string name="latest_finished_live_time_minutes">%1$d min ago</string>
<string name="latest_finished_live_time_hours">%1$d h ago</string>
<string name="latest_finished_live_time_days">%1$d d ago</string>
<string name="character_comment_error_empty">Enter the details.</string>
<string name="character_comment_error_report_reason">Enter the reason for reporting.</string>
<string name="character_comment_report_submitted">Your report has been submitted.</string>

View File

@@ -272,6 +272,10 @@
<string name="character_comment_time_days">%1$d日前</string>
<string name="character_comment_time_months">%1$dヶ月前</string>
<string name="character_comment_time_years">%1$d年前</string>
<string name="latest_finished_live_time_just_now">たった今</string>
<string name="latest_finished_live_time_minutes">%1$d分前</string>
<string name="latest_finished_live_time_hours">%1$d時間前</string>
<string name="latest_finished_live_time_days">%1$d日前</string>
<string name="character_comment_error_empty">内容を入力してください。</string>
<string name="character_comment_error_report_reason">通報理由を入力してください。</string>
<string name="character_comment_report_submitted">通報を受け付けました。</string>

View File

@@ -271,6 +271,10 @@
<string name="character_comment_time_days">%1$d일전</string>
<string name="character_comment_time_months">%1$d개월전</string>
<string name="character_comment_time_years">%1$d년전</string>
<string name="latest_finished_live_time_just_now">방금 전</string>
<string name="latest_finished_live_time_minutes">%1$d분 전</string>
<string name="latest_finished_live_time_hours">%1$d시간 전</string>
<string name="latest_finished_live_time_days">%1$d일 전</string>
<string name="character_comment_error_empty">내용을 입력하세요</string>
<string name="character_comment_error_report_reason">신고 사유를 입력하세요</string>
<string name="character_comment_report_submitted">신고가 접수되었습니다.</string>