Convert UTC Date to LocalDateTime (with support to older Android APIs) - android

I'm looking for a way to convert UTC date to LocalDateTime without limiting to API 26 (Android O) and above. Is there an alternate way to do this that will support API levels below API 26? I've currently got this and it works for devices running 26 and above:
#RequiresApi(Build.VERSION_CODES.O)
override fun convertUtcToLocalDateTime(utcVal: String): LocalDateTime {
return convertUtcToDate(utcVal).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime()
}
override fun convertUtcToDate(utcDate: String): Date {
val formats = arrayListOf<String>(
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
"yyyy-MM-dd'T'HH:mm:ss.SS'Z'",
"yyyy-MM-dd'T'HH:mm:ss'Z'",
"yyyy-MM-dd'T'HH:mm:ss.SSS"
)
var date: Date? = null
formats.forEach {
if (date == null) {
try {
val parser = SimpleDateFormat(it, Locale.getDefault())
parser.timeZone = TimeZone.getTimeZone("UTC")
date = parser.parse(utcDate)
} catch (e: Exception) {
date = null
}
}
}
return date ?: Date()
}
Sample value that gets sent as utcVal: 2021-09-05T13:55:35.097Z
Please let me know if theres an alternate that supports older APIs as well.

TLDR: When to use ThreeTenABP
The predecessor to LocalDateTime (JSR-310) is Joda-Time
Although you probably should look at ThreeTenABP
which references the Joda-Time Android specific version.
Also be aware of: Differences between Java 8 Date Time API (java.time) and Joda-Time

Related

Output "from Now" string in Kotlin using UTC timezone

I'm trying to write a Kotlin function which replicates the behaviour of fromNow in the moment library.
I have the following code:
fun formatDuration(dateTime: String): String {
try {
val parsedDateTime = Instant.parse(dateTime)
val prettyTime = PrettyTime()
prettyTime.reference = Instant.now().atZone(ZoneOffset.UTC).toInstant()
return prettyTime.format(parsedDateTime)
} catch (e: DateTimeParseException) {
e.printStackTrace()
return "Invalid date/time format"
}
}
The problem is when the device time is 9:44 and the input string is 2023-02-19T11:48:09.958Z, and the current UTC time is 15:19 it will output 2 hours from now, even though it should output 3 hours ago like the moment function does as the timestamp is in UTC.
How can I fix this to always take into account UTC time not local time when calculating the difference?
Have you tried to change:
from:
val parsedDateTime = Instant.parse(dateTime)
to:
val parsedDateTime = Instant.parse(dateTime).atZone(ZoneOffset.UTC).toInstant()

How to parse date "2022-07-18T08:24:18Z" in android

I have tried these format but none worked.
yyyy-MM-dd'T'HH:mm:ss'Z'
yyyy-MM-dd'T'HH:mm:ssZ
yyyy-MM-dd'T'HH:mm:ssZZ
yyyy-MM-dd'T'HH:mm:ss
Also tried "ZonedDateTime", but it is not available below Android O.
If your minSDK is 25 or lower you have to use Java 8+ API desugaring support to be able to use the java.time package from Java 8.
With that enabled you can simply use e.g.
OffsetDateTime.parse("2022-07-18T08:24:18Z")
ZonedDateTime.parse("2022-07-18T08:24:18Z")
(you can find many resources about the differences of these date formats).
You can do it like this
fun parseDate(
inputDateString: String?,
inputDateFormat: SimpleDateFormat,
outputDateFormat: SimpleDateFormat
): String? {
var date: Date? = null
var outputDateString: String? = null
try {
date = inputDateFormat.parse(inputDateString)
outputDateString = outputDateFormat.format(date)
} catch (e: ParseException) {
e.printStackTrace()
}
return outputDateString
}
inputString will be your Date, ex:"2022-07-18T08:24:18Z"
inputDateFormat : SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",
Locale.US)
outputDateFormat : in whichever format you want to show the date
I hope you get your answer from this

Convert Date String to Date object in Kotlin? How to calculate number of days between today and specific date in Kotlin?

Part 1:
I have date as string in the following format: "2020-10-15T22:54:54Z"
I have to convert it into date object.
Tried the following:
val dateString = "2020-10-15T22:54:54Z"
val dateFormatter = DateTimeFormatter.ofPattern("%Y-%m-%dT%H:%M:%SZ")
val updatedAtDate = LocalDate.parse(dateString, dateFormatter)
val today = LocalDateTime.now()
println("Updated At: $updatedAtDate")
Gives the following error: "Unknown pattern letter: T"
Part 2:
Once I have the date object from above, I have to calculate the difference between today (Current Date) and the above date. How to do it in Kotlin?
tl;dr You don't need to create a custom formatter…
… for the val dateString = "2020-10-15T22:54:54Z" here, it is formatted in an ISO standard. Therefore, you can simply do this (if you want a LocalDate, just year, month and day):
val thatDate: LocalDate = OffsetDateTime.parse(dateString).toLocalDate()
Fully adressing all the aspects of your post:
You can utilize a java.time.Period.between(LocalDate, LocalDate) in order to calculate the difference between two LocalDates. You only have to make sure the older date is the first argument, otherwise you will get a negative result. Here's a full example:
import java.time.OffsetDateTime
import java.time.LocalDate
import java.time.Period
fun main(args: Array<String>) {
val dateString = "2020-10-15T22:54:54Z"
// create an OffsetDateTime directly
val thatDate = OffsetDateTime.parse(dateString)
// and extract the date
.toLocalDate()
// get the current day (date only!)
val today = LocalDate.now()
// calculate the difference in days and make sure to get a positive result
val difference = if (today.isBefore(thatDate))
Period.between(today, thatDate).days
else
Period.between(thatDate, today).days
// print something containing both dates and the difference
println("[$today] Updated At: $thatDate, difference: $difference days")
}
Output at Dec 10, 2021:
[2021-12-10] Updated At: 2020-10-15, difference: 25 days

Selected date Month looks like a code not a string

Everyone
I'm using MaterialDatePicker to show the date and it was working fine and get the date like I want Aug 5,2021 and suddenly out of nowhere I get now Month like this M08 and that makes the date like this M08 5,2021
and below is the gradle dependency:
implementation "com.google.android.material:material:1.3.0"
Can anyone help me, please?
you can try this code
private fun showDatePicker() {
val selectedDateInMillis = currentSelectedDate ?: System.currentTimeMillis()
MaterialDatePicker.Builder.datePicker().setSelection(selectedDateInMillis).build().apply {
addOnPositiveButtonClickListener { dateInMillis -> onDateSelected(dateInMillis) }
}.show(supportFragmentManager, MaterialDatePicker::class.java.canonicalName)
}
// result onDateSelected
private fun onDateSelected(dateTimeStampInMillis: Long) {
currentSelectedDate = dateTimeStampInMillis
val dateTime: LocalDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(currentSelectedDate), ZoneId.systemDefault())
val dateAsFormattedText: String = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
// view for result
findViewById<TextView>(R.id.output).text = dateAsFormattedText
}
I found the issue. It was a localization issue need to verify localization for the material date picker before using it.

Start week with SUNDAY format using Kotlin in android

I am working on Calendar dates, where I am making 7 Days week value from below method. But I need to start my week days from SUNDAY specific only.
fun getWeekDay(): Array<String?>? {
weekDaysCount--
val now1 = Calendar.getInstance()
now1.set(2021, 1, 29)
val now = now1.clone() as Calendar
val format = SimpleDateFormat("yyyy-MM-dd")
val days = arrayOfNulls<String>(7)
val delta = -now[GregorianCalendar.DAY_OF_WEEK] + 1
now.add(Calendar.WEEK_OF_YEAR, weekDaysCount)
now.add(Calendar.DAY_OF_MONTH, delta)
for (i in 0..6) {
days[i] = format.format(now.time)
now.add(Calendar.DAY_OF_MONTH, 1)
}
return days
}
I am getting an output like this:
I need to make a method where if i give any Date, it should adjust as per SUNDAY format.
As per Date 29/1/2021, output should be like:
24(Sun), 25 (Mon), 26 (Tue), 27 (Wed), 28 (Thur) 29 (Fri), 30 (Sat)
What you want to achieve is much easier using Java 8's date / time library (java.time) instead of Calendar.
import java.time.DayOfWeek
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.time.temporal.TemporalAdjusters
fun getWeekDay(): Array<String?> {
var date = LocalDate.of(2021, 1, 29)
date = date.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY))
val formatter = DateTimeFormatter.ofPattern("dd (EEE)")
val days = arrayOfNulls<String>(7)
for (i in 0 until 7) {
days[i] = formatter.format(date)
date = date.plusDays(1)
}
return days
}
The code starts from a given date (I have hard-coded it here but you can adjust it), goes back to the previous or same Sunday and simply adds seven days.
To be able to use it in all android versions, add this dependency to your build.gradle file:
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1'
and these compile options:
android {
...
compileOptions {
coreLibraryDesugaringEnabled true
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
...
Now you will be able to use a lot of Java 8 features and libraries.

Categories

Resources