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.
Related
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
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
I have a date with that format: 2027-02-14T14:20:00.000
I would like to take hours and minutes from it like in that case: 14:20
I was trying to do something like this:
val firstDate = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US).parse("2027-02-14T14:20:00.000")
val firstTime = SimpleDateFormat("H:mm").format(firstDate)
but I got crash java.text.ParseException: Unparseable date
How to take hours and minutes from that string ?
One of the RECOMMENDED WAYs
In case you can use java.time, here's a commented example:
import java.time.LocalDateTime
import java.time.LocalDate
import java.time.format.DateTimeFormatter
fun main() {
// example String
val input = "2027-02-14T14:20:00.000"
// directly parse it to a LocalDateTime
val localDateTime = LocalDateTime.parse(input)
// print the (intermediate!) result
println(localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME))
// then extract the date part
val localDate = localDateTime.toLocalDate()
// print that
println(localDate)
}
This outputs 2 values, the intermediate LocalDateTime parsed and the extracted LocalDate (the latter simply invoking its toString() method implicitly):
2027-02-14T14:20:00
2027-02-14
NOT RECOMMENDED but still possible:
Still use the outdated API (might be necessary when it comes to large amounts of legacy code, which I doubt you will find written in Kotlin):
import java.text.SimpleDateFormat
fun main() {
val firstDate = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS")
.parse("2027-02-14T14:20:00.000")
val firstTime = SimpleDateFormat("yyyy-MM-dd").format(firstDate)
println(firstTime)
}
Output:
2027-02-14
I'm trying to parse a string date to a date . My string date is : 2021-12-16T11:00:00.000Z.
I have the follwing code to parse it to a date object:
val stringDate = "2021-12-16T16:42:00.000Z"
val sdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
var consultationDate = sdf.parse(stringDate)
And I keep getting this error:
java.text.ParseException: Unparseable date: "2021-12-16T11:00:00.000Z"
You should use Z the same way you use T for the parser to recognize the character in format
val stringDate = "2021-12-16T16:42:00.000Z"
val sdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
var consultationDate = sdf.parse(stringDate)
As #Leo Dabus mentioned You should never escape/ignore the Z. It means UTC timezone . - as it will parse it using current timezone.
Also you shouldn't be using SimpleDateFormat as it's outdated
Use ZonedDateTime and OffsetDateTime to parse the date in the specific zone.
val date = "2021-12-16T16:42:00.000Z" // your date
// date is already in Standard ISO format so you don't need custom formatted
val dateTime : ZonedDateTime = OffsetDateTime.parse(date).toZonedDateTime() // parsed date
// format date object to specific format if needed
val formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy HH:mm")
Log.e("Date 1", dateTime.format(formatter)) // output : Dec 16, 2021 16:42
Above date in the UTC timezone, if you want you can convert it into your system default timezone using withZoneSameInstant
val defaultZoneTime: ZonedDateTime = dateTime.withZoneSameInstant(ZoneId.systemDefault())
Log.e("Date 1", defaultZoneTime.format(formatter)) // output : Dec 16, 2021 22:12
Note: ZonedDateTime only works in android 8 and above, to use it below android 8 enable desugaring.
In your app module's build.gradle, add coreLibraryDesugaringEnabled
compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 8
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
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