SimpleDateFormat wrong result Kotlin [duplicate] - android

This question already has answers here:
Add colon to 24 hour time in Java?
(7 answers)
Closed 1 year ago.
My input in this case is 2012-09-28 but I receive
01/01/2011 I would like to receive 09/28/2012
main(){
val scan = Scanner(System.`in`)
val originalFormat: DateFormat = SimpleDateFormat("YYYY-MM-DD", Locale.ENGLISH)
val targetFormat: DateFormat = SimpleDateFormat("MM/DD/YYYY")
val date = originalFormat.parse(scan.next())
val formattedDate = targetFormat.format(date)
println(formattedDate)
}
What is my code missing?

The modern API for parsing and formatting date and time is java.time, which was introduced with Java 8. You can either import the ThreeTenAbp or use Android API Desugaring in order to make it work in Android API versions below 26.
The following example uses java.time and considers the input of the two different formats you posted (one in your question and one as a comment to the first answer).
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.Scanner
fun main() {
val scan = Scanner(System.`in`)
// create a formatter that parses the two different EXPECTED input formats
val inputFormatter = DateTimeFormatter.ofPattern("[uu-MM-dd][uuuu-MM-dd]");
// parse the input
val localDate: LocalDate = LocalDate.parse(scan.next(), inputFormatter)
// define a formatter with the desired output format
val targetFormat: DateTimeFormatter = DateTimeFormatter.ofPattern("MM/dd/uuuu")
// then create a String with the desired output format
val formattedDate: String = localDate.format(targetFormat)
// and print it
println(formattedDate)
}
The result for the inputs 12-09-30 or 2012-09-30 is 09/30/2012 in both cases.

Colud you try this way?
fun main() {
val scan = Scanner(System.`in`)
val originalFormat = SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH)
val targetFormat = SimpleDateFormat("MM/dd/yyyy")
val date = originalFormat.parse(scan.next())
val formattedDate = targetFormat.format(date)
println(formattedDate)
}
d is a day in the month. (ex_10)
D is a day in the year. (ex_189)
y is the year. (ex_1996; 96)
Y is week year. (ex_2009; 09)

Use yyyy instead of YYYY and dd instead of DD.
DD is the day of year while dd is the day of month.
YYYY is the week year and yyyy is the regular year.
https://developer.android.com/reference/java/text/SimpleDateFormat?hl=en

Related

How can I add months Int to a choosen date on date picker in android Kotlin?

I have a working date picker in my app that replaces an EditText after a date selection. I want to add duration through a RadioGroup button that prints an Int to provoke an end date. How can I do that? I've spent the last two days without getting the result I'm looking to get.
Here is what I've got so far.
val datePicker = findViewById<DatePicker>(R.id.date_Picker)
val today = Calendar.getInstance()
datePicker.init(
today.get(Calendar.YEAR),
today.get(Calendar.MONTH),
today.get(Calendar.DAY_OF_MONTH
) { view, year, month, day ->
val month = month + 1
val startDay = ("$day-$month-$year")
binding.fechadeinicio.text = fechainicio
val duration = when (binding.duracion.checkedRadioButtonId) {
R.id.doce -> 12
R.id.veinticuatro -> 24
R.id.treintayseis -> 36
else -> 36
}
// val endDate = startDate.plusMonths(Duration.toLong())
// binding.endDate.text = endDate.toString()
}
Here is the closest one to the result I'm looking to get. Yet, I want to use the selected date val startDay, instead of val date = LocalDate.parse("2020-05-03"). When I replace it, the app crashes.
val date = LocalDate.parse("2020-05-03")
// Displaying date
println("Date : $date")
// Add 2 months to the date
val newDate = date.plusMonths(2)
println("New Date : $newDate")
Please, let me know how I can get the desired result?
Thanks.
I want to use the selected date that is val startDay instead of val date = LocalDate.parse("2020-05-03"). When I replace it, the app crashes.
val startDay = ("$day-$month-$year") here you've created date as dd-MM-yyyy, but by default LocalDate.parse uses DateTimeFormatter.ISO_LOCAL_DATE to parse a string, that parses a string of format yyyy-MM-dd to LocalDate. That's why it's crashing as your date is invalid according to that format.
You have to provide a DateTimeFormatter of pattern dd-MM-yyyy to parse your date.
You can do it like this
val startDay = ("$day-$month-$year")
val dateFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy")
binding.fechadeinicio.text = fechainicio
val duration = when (binding.duracion.checkedRadioButtonId) {
R.id.doce -> 12
R.id.veinticuatro -> 24
R.id.treintayseis -> 36
else -> 36
}
val startDate = LocalDate.parse(startDay, dateFormatter)
val endDate = startDate.plusMonths(duration.toLong()).format(dateFormatter)
binding.endDate.text = endDate
DatePicker returns year, month and day int values, now on creating date like val startDay = ("$day-$month-$year") would result in single digit for days and months less than 10, which would return 1 Jan 2020 as 1-1-2020 but date formatter is expecting it to be 01-01-2020.
To deal with this, we've to format int values before assigning it to the startDay, we can use format method of String to return 2 digits like this "%02d".format(intValue)
Change
val startDay = ("$day-$month-$year")
to
val startDay = "${"%02d".format(day)}-${"%02d".format(month)}-$year"
You can use LocalDate using of function.
Example here:
val date = LocalDate.of(year, month, day)
// Displaying date
println("Date : $date")
// Add 2 months to the date
val newDate = date.plusMonths(2)
println("New Date : $newDate")

MaterialDatePicker constraints or limit available dates

I have a requirements where I need to limit the allowed date in DatePicker from year 2009 up to current date only. Meaning the supported date for example will be from Jan 1, 2009 up to current date only.
The current implementation we had with the old DatePickerDialog
val calendar = Calendar.getInstance()
val year = calendar[Calendar.YEAR]
val month = calendar[Calendar.MONTH]
val day = calendar[Calendar.DAY_OF_MONTH]
val datePickerDialog = DatePickerDialog(appContext,
R.style.AppDatePicker,
dateSetListener,
year,
month,
day)
//Oldest date will be 2009
calendar.add(Calendar.YEAR, 2009 - year)
datePickerDialog.datePicker.minDate = calendar.timeInMillis
//Latest date will be the current date
datePickerDialog.datePicker.maxDate = System.currentTimeMillis()
// datePickerDialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
//Pop up the DatePicker dialog
datePickerDialog.show()
Additional possible improvement is to limit the supported date by specifying the date statically.
Something like
val startDate = "01/01/2009"
val endDate = "03/27/2022"
calendarPicker.minDate = Date(startDate)
calendarPicker.maxDate = Date(endDate)
Currently looking on CalendarConstraints.DateValidator and CalendarConstraints.Builder() but do not know how to work with it base on my requirements.
I don't know if you still need it, but maybe it will help others too.
I had a similar problem where I needed only dates in the range from the previous day to 45 days behind the current date to be enabled. That is, today, January 18th, the calendar would only be enabled from 12-05-2022 to 01-17-2023.
I did it like this:
val dateValidatorMin: DateValidator =
DateValidatorPointForward.from(
Calendar.getInstance().timeInMillis - 45.days.toLong(DurationUnit.MILLISECONDS))
val dateValidatorMax: DateValidator =
DateValidatorPointBackward.before(
Calendar.getInstance().timeInMillis - 1.days.toLong(DurationUnit.MILLISECONDS))
enter code here
val dateValidator: DateValidator = CompositeDateValidator.allOf(listOf(dateValidatorMin, dateValidatorMax))
val constraints: CalendarConstraints =
CalendarConstraints.Builder()
.setValidator(dateValidator)
.build()
val builder = MaterialDatePicker.Builder.dateRangePicker()
.setCalendarConstraints(constraints)
.setTitleText(getString(R.string.label_select_date_range))
val picker = builder.build()
And the result was like this:
Hope this helps.

How to get current time from device in kotlin? [duplicate]

This question already has answers here:
How to get current time and date in Android
(42 answers)
Closed 1 year ago.
How can I get the current time from device? I need possibly ways in kotlin language.
Here simple way to get the time!
val c = Calendar.getInstance()
val year = c.get(Calendar.YEAR)
val month = c.get(Calendar.MONTH)
val day = c.get(Calendar.DAY_OF_MONTH)
val hour = c.get(Calendar.HOUR_OF_DAY)
val minute = c.get(Calendar.MINUTE)
try this...
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
ex) 2021-12-02 17:17:03
LocalDateTime.now() require API level 26.
so, if API level 26 below,
you add #RequiresApi(Build.VERSION_CODES.0) this code above your method.
Don't use old Calendar apis, it's outdated and troublesome.
Use LocalDateTime to get the system date and time
private fun getCurrentDate() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val dateTime = LocalDateTime.now() // date time object
val month = dateTime.month // result DECEMBER
val date = dateTime.dayOfMonth // result 2 (current date )
val formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
Log.d(
"Date:", parssed date ${dateTime.format(formatter)}"
)
}
}
Change FormatStyle to MEDIUM,SHORT,LONG,FULL to change date format accordingly or you can use custom date parser format.
Output: Dec 2, 2021
Note: DateTimeFormatter only works in android 8 and above, to use it below android 8 enable desugaring

How to display different date/time format in textview using hr, day and calender

I am trying to work on displaying dates and I am experiencing a challenge. So I have this one textview in my adapter class and I want the time displayed to be in 3 different format, Say for instance when its past 24hrs say date e.g Saturday if its very old just display date 02/9/2021 and if a day has not ended just display time 12:00am my problem is how do I achieve this on Android using Kotlin? here is a sample image I got
It's simple just get difference between now and your date and use SimpleDateFormat to formate date
fun getDate(date:Long){
val nowCal = Calendar.getInstance()
val dateCal = Calendar.getInstance().apply {
//just for test, replace with your date timestamp
timeInMillis += TimeUnit.DAYS.toMillis(9)
}
val nowDay = TimeUnit.MILLISECONDS.toDays(nowCal.timeInMillis)
val dateDay = TimeUnit.MILLISECONDS.toDays(dateCal.timeInMillis)
when {
(dateDay - nowDay) <= 1L -> {
val formatter = SimpleDateFormat("hh:mm a")
val dateStr = formatter.format(dateCal.time)
println(dateStr)
}
(dateDay - nowDay) <= 6L -> {
val dateStr = dateCal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.ENGLISH)
println(dateStr)
}
else ->{
val formatter = SimpleDateFormat("M/d/yy")
val dateStr = formatter.format(dateCal.time)
println(dateStr)
}
}
}

How to get date 7 days ago to today in Kotlin? [duplicate]

This question already has answers here:
Android get date before 7 days (one week)
(8 answers)
Closed 5 years ago.
I want to get date from 7 days ago to today in Kotlin. Any suggestions? This is what I have so far
val date = Calendar.getInstance()
val yesterday = Calendar.getInstance()
yesterday.add(Calendar.DATE,-1)
var todayOrYesterday:String?
var todayDate = date.time
while (todayDate > yesterday.time){
val formatter = SimpleDateFormat("EEEE, d MMMM yyyy")
val format = formatter.format(todayDate)
println(format)
todayOrYesterday = if (DateUtils.isToday(date.timeInMillis)) {
"Today"
}else "Yesterday"
date.add(Calendar.DATE,-7)
}
Use this function, pass the days ago you want:
fun getDaysAgo(daysAgo: Int): Date {
val calendar = Calendar.getInstance()
calendar.add(Calendar.DAY_OF_YEAR, -daysAgo)
return calendar.time
}
Simply use,
val date = Calendar.getInstance() // 19-01-2018
date.add(Calendar.DATE, -7) // 12-01-2018
An alternative is to use Joda Time (Joda Time for Android). This library has a really nice API.
DateTime.now().minusDays(7)
And you can call .toDate() if you need a Java-Date object.
Link: Why Joda Time?

Categories

Resources