일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 안드로이드 라이선스
- 스택 큐 차이
- android retrofit login
- 플러터 설치 2022
- 안드로이드 레트로핏 crud
- 자바 다형성
- 2022 플러터 안드로이드 스튜디오
- rxjava disposable
- 서비스 쓰레드 차이
- 안드로이드 유닛 테스트
- rxjava cold observable
- 큐 자바 코드
- ANR이란
- ar vr 차이
- 객체
- 2022 플러터 설치
- Rxjava Observable
- 안드로이드 os 구조
- jvm 작동 원리
- jvm이란
- 안드로이드 라이선스 종류
- 멤버변수
- 안드로이드 유닛 테스트 예시
- 스택 자바 코드
- 안드로이드 레트로핏 사용법
- 서비스 vs 쓰레드
- 안드로이드 유닛테스트란
- rxjava hot observable
- 클래스
- android ar 개발
- Today
- Total
나만을 위한 블로그
[Android] 날짜 변환 시 사용하는 enum과 확장 함수 모음 본문
이 포스팅은 아래의 미디엄 링크를 보고 작성했다.
Android How to Convert your dateTime to different formats using extension function
A very useful extension function for converting your date to different formats by using extension function.
medium.com
날짜를 1분 전, 4시간 전 등으로 바꿔야 하는 경우도 있지만 가끔은 yyyy-MM-dd 형태로 바꿔야 하는 경우도 있기 마련이다.
위 포스팅이 이것에 대해 다루는데, 앞으로 유용하게 쓸 수 있을 것 같아 포스팅으로 남겨둔다. 그 전에 밑준비부터 한다.
먼저 values 폴더에 format_date.xml 파일을 만들고 아래 내용을 복붙한다.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="format_date">
<item>Default format</item>
<item>Date time YYYY MM DD Format</item>
<item>Date time YYYY MM DD HH:mm Format</item>
<item>Date time YYYY MM DD HH:mm:ss Format</item>
<item>MONTH AND YEAR MM DD YYYY Format</item>
<item>Date time DD MM YYYY HH:mm:ss Format</item>
<item>Date YYYY MM DD Format</item>
<item>Date / Name of Week/ year Format</item>
<item>Week name / Date Month Format</item>
<item>Date / Name of Month</item>
<item>Date time DD MM YYYY - HH:mm:ss Format</item>
<item>AM / PM Format</item>
</string-array>
</resources>
스피너 클릭 시 보여줄 리스트에 들어갈 문장들이다. 저 형식대로 바뀐 날짜를 보여줄 것이다.
XML은 아래와 같이 작성한다.
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".other.DateTimeActivity">
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textColor="@color/cardview_dark_background"
android:textSize="28sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Spinner
android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text1"
android:layout_marginTop="30dp"
android:background="@android:color/transparent"
android:gravity="center"
android:spinnerMode="dropdown" />
<TextView
android:id="@+id/welcomeFormatText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/spinner" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
그리고 미디엄 포스팅에선 enum class를 활용하기 때문에 포스팅과 똑같이 enum class를 만든다.
enum class DateFormats(
val format: String
) {
DEFAULT_FORMAT("yyyy-MM-dd'T'HH:mm:ss"), // 2021-05-20T11:28:24Z
DEFAULT_FORMAT_WITHOUT_TIME("yyyy-MM-dd"), // 2021-05-20
DATE_TIME_YY_MM_FORMAT("yyyy-MM-dd'T'HH:mm"), // 2021-05-20T11:28
DATE_TIME_YY_MM_FULL_TIME_FORMAT("yyyy-MM-dd'T'HH:mm:ss"), // 2021-05-20T11:28
DATE_MM_DD_YY_FORMAT("MM-dd-yyyy"), // 05-20-2021
DATE_MM_DD_FORMAT("MMM dd, yyyy"), // May 20,2021
FULL_DATE_TIME_DD_MM_FORMAT("dd-MM-yyyy'T'HH:mm:ss"), // 2021-05-20T11:28:24
DATE_YY_MM_FORMAT("yyyy-MM-dd"), // 2021-05-20
DATE_MONTH_OF_YEAR_FORMAT("d MMMM, yyyy"), // 20 May, 2021
DAY_OF_WEEK_MONTH_FORMAT("EEE, d MMM"), // Thu, 20 May
DATE_MONTH_FORMAT("d MMM"), // 20 MAY
DATE_TIME_FORMAT_CUSTOM_FORMAT("dd.MM.yyyy' - ' HH:mm:ss"), // 21.06.2021 - 10:10:18
}
그리고 확장 함수를 만들 파일을 만든다. 파일의 이름은 StringDateUtil이다.
import java.text.SimpleDateFormat
import java.util.*
fun String.convertDefaultWithoutTime(format: String): String? {
val dateFormat = SimpleDateFormat(format, Locale.getDefault())
val parsedDate = dateFormat.parse(this)
val dayMonthFormat =
SimpleDateFormat(DateFormats.DEFAULT_FORMAT_WITHOUT_TIME.format, Locale.getDefault())
return parsedDate?.let { dayMonthFormat.format(parsedDate) }
}
fun String.convertDateToYMDTime(format: String): String? {
val dateFormat = SimpleDateFormat(format, Locale.getDefault())
val parsedDate = dateFormat.parse(this)
val dayMonthFormat =
SimpleDateFormat(DateFormats.DATE_TIME_YY_MM_FULL_TIME_FORMAT.format, Locale.getDefault())
return parsedDate?.let { dayMonthFormat.format(parsedDate) }
}
fun String?.formatStringDate(inputFormat: String, outputFormat: String): String {
return if (this.isNullOrEmpty()) {
""
} else {
val dateFormatter = SimpleDateFormat(inputFormat, Locale.getDefault())
val date = dateFormatter.parse(this)
date?.let { SimpleDateFormat(outputFormat, Locale.getDefault()).format(it) }.orEmpty()
}
}
fun String.convertDateToYMDFullTimeDate(format: String): String? {
val dateFormat = SimpleDateFormat(format, Locale.getDefault())
val parsedDate = dateFormat.parse(this)
val dayMonthFormat =
SimpleDateFormat(DateFormats.DATE_TIME_YY_MM_FORMAT.format, Locale.getDefault())
return parsedDate?.let { dayMonthFormat.format(parsedDate) }
}
fun String.trimTimeFromDateMDY(format: String): String? {
val dateFormat = SimpleDateFormat(format, Locale.getDefault())
val parsedDate = dateFormat.parse(this)
val trimmed = SimpleDateFormat(DateFormats.DATE_MM_DD_YY_FORMAT.format, Locale.getDefault())
return parsedDate?.let { trimmed.format(parsedDate) }
}
fun String.convertDateToDMYFullTimeDate(format: String): String? {
val dateFormat = SimpleDateFormat(format, Locale.getDefault())
val parsedDate = dateFormat.parse(this)
val dayMonthFormat =
SimpleDateFormat(DateFormats.FULL_DATE_TIME_DD_MM_FORMAT.format, Locale.getDefault())
return parsedDate?.let { dayMonthFormat.format(parsedDate) }
}
fun String.convertDateToYMD(format: String): String? {
val dateFormat = SimpleDateFormat(format, Locale.getDefault())
val parsedDate = dateFormat.parse(this)
val dayMonthFormat = SimpleDateFormat(DateFormats.DATE_YY_MM_FORMAT.format, Locale.getDefault())
return parsedDate?.let { dayMonthFormat.format(parsedDate) }
}
fun String.convertDateToMonthNameYear(format: String): String? {
val dateFormat = SimpleDateFormat(format, Locale.getDefault())
val parsedDate = dateFormat.parse(this)
val dayMonthFormat =
SimpleDateFormat(DateFormats.DATE_MONTH_OF_YEAR_FORMAT.format, Locale.getDefault())
return parsedDate?.let { dayMonthFormat.format(parsedDate) }
}
fun String.convertDateToWeekNameYear(format: String): String? {
val dateFormat = SimpleDateFormat(format, Locale.getDefault())
val parsedDate = dateFormat.parse(this)
val dayMonthFormat =
SimpleDateFormat(DateFormats.DAY_OF_WEEK_MONTH_FORMAT.format, Locale.getDefault())
return parsedDate?.let { dayMonthFormat.format(parsedDate) }
}
fun String.convertDateMonthName(format: String): String? {
val dateFormat = SimpleDateFormat(format, Locale.getDefault())
val parsedDate = dateFormat.parse(this)
val dayMonthFormat = SimpleDateFormat(DateFormats.DATE_MONTH_FORMAT.format, Locale.getDefault())
return parsedDate?.let { dayMonthFormat.format(parsedDate) }
}
fun String.convertDateCustom(format: String): String? {
val dateFormat = SimpleDateFormat(format, Locale.getDefault())
val parsedDate = dateFormat.parse(this)
val dayMonthFormat =
SimpleDateFormat(DateFormats.DATE_TIME_FORMAT_CUSTOM_FORMAT.format, Locale.getDefault())
return parsedDate?.let { dayMonthFormat.format(parsedDate) }
}
fun String.convertDateToAmPm(format: String): String? {
val dateFormat = SimpleDateFormat(format, Locale.getDefault())
val parsedDate = dateFormat.parse(this)
val dayMonthFormat = SimpleDateFormat("hh:mm a", Locale.getDefault())
return parsedDate?.let { dayMonthFormat.format(parsedDate) }
}
이제 액티비티 코틀린 파일을 아래처럼 바꿔준다.
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Toast
import com.example.kotlinprac.R
import com.example.kotlinprac.databinding.ActivityDateTimeBinding
import kotlinx.android.synthetic.main.activity_date_time.*
class DateTimeActivity : AppCompatActivity() {
private val TAG = this.javaClass.simpleName
var date1 = "2022-11-10T10:10:00"
var result: String = ""
private val binding by lazy {
ActivityDateTimeBinding.inflate(layoutInflater)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
ArrayAdapter.createFromResource(this, R.array.format_date, android.R.layout.simple_spinner_item).also { adapter ->
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
this.spinner.adapter = adapter
this.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parentView: AdapterView<*>?,
selectedItemView: View,
position: Int,
id: Long
) {
when (position) {
1 -> {
var dayMonth = date1
dayMonth = dayMonth.convertDefaultWithoutTime(DateFormats.DEFAULT_FORMAT.format).toString()
result = dayMonth
}
2 -> {
var trimHour = date1
trimHour = trimHour.convertDateToYMDFullTimeDate(DateFormats.DEFAULT_FORMAT.format).toString()
result = trimHour
}
3 -> {
var timeAMPM = date1
timeAMPM = timeAMPM.convertDateToYMDFullTimeDate(DateFormats.DEFAULT_FORMAT.format)
.toString()
result = timeAMPM
}
4 -> {
var timeAMPM = date1
timeAMPM = timeAMPM.trimTimeFromDateMDY(
DateFormats.DEFAULT_FORMAT.format,
).toString()
result = timeAMPM
}
5 -> {
var timeAMPM = date1
timeAMPM = timeAMPM.convertDateToDMYFullTimeDate(
DateFormats.DEFAULT_FORMAT.format
).toString()
result = timeAMPM
}
6 -> {
var timeAMPM = date1
timeAMPM = timeAMPM.convertDateToYMD(
DateFormats.DEFAULT_FORMAT.format
).toString()
result = timeAMPM
}
7 -> {
var timeAMPM = date1
timeAMPM = timeAMPM.convertDateToMonthNameYear(
DateFormats.DEFAULT_FORMAT.format
).toString()
result = timeAMPM
}
8 -> {
var timeAMPM = date1
timeAMPM = timeAMPM.convertDateToWeekNameYear(
DateFormats.DEFAULT_FORMAT.format
).toString()
result = timeAMPM
}
9 -> {
var timeAMPM = date1
timeAMPM = timeAMPM.convertDateMonthName(
DateFormats.DEFAULT_FORMAT.format
).toString()
result = timeAMPM
}
10 -> {
var timeAMPM = date1
timeAMPM = timeAMPM.convertDateCustom(
DateFormats.DEFAULT_FORMAT.format
).toString()
result = timeAMPM
}
11 -> {
var timeAMPM = date1
timeAMPM = timeAMPM.convertDateToAmPm(
DateFormats.DEFAULT_FORMAT.format
).toString()
result = timeAMPM
}
}
text1.text = result
Toast.makeText(this@DateTimeActivity, "변환 결과 : $result", Toast.LENGTH_SHORT).show()
}
override fun onNothingSelected(parentView: AdapterView<*>?) {}
}
}
}
}
대충 스피너에서 뭐 선택했냐에 따라서 date1 프로퍼티에 담긴 날짜를 바꾸고 변환 결과를 토스트로 띄운다.
앱이 실행되자마자 변환 결과가 없는 토스트가 표시되지만 값이 잘 변경되는지 확인하기 위해 내가 임의로 넣은 토스트기 때문에 무시해도 된다.
실행하면 아래와 같이 실행된다.

프로퍼티에 담겨있던 시간 형태는 "2022-11-10T10:10:00"인데 스피너를 눌러 선택한 아이템에 따라 변환된 결과가 텍스트뷰와 토스트에 표시되는 걸 볼 수 있다.
이걸 응용하면 서버에서 UTC 시간을 넘겨줄 때 내가 원하는 시간으로 바꿔서 표시할 수 있을 것이다.
'Android' 카테고리의 다른 글
[Android] EventBus란? EventBus 사용법 (0) | 2022.11.21 |
---|---|
[Android] 코틀린으로 registerForActivityResult() 써서 갤러리에서 이미지 가져오기 (0) | 2022.11.10 |
[Android] 코틀린으로 안드로이드 KG이니시스 결제 연동하는 법 [2022 Ver] (0) | 2022.11.09 |
[Android] 이미지 캐시 (0) | 2022.10.03 |
[Android] BindingAdapter란? BindingAdapter 사용법 (0) | 2022.09.12 |