i'm trying to subtract two long(timestamp) but it kept crashing the application
heres the code
//converting timestamp to actual time;
val calendar = Calendar.getInstance(Locale.ENGLISH)
calendar.timeInMillis = chat!!.timestamp!!.toLong()
val t24 = 86400000 //24hrs in milliseconds
val currentTime = System.currentTimeMillis().toInt()
val chatTime: Int = chat.timestamp!!.toInt()
val date = holder.date
if ((currentTime - chatTime ) < t24 ) {
val time =
DateFormat.format("hh:mm aa", calendar).toString()
date!!.text = time
}else{
val time =
DateFormat.format("dd/MM//yyyy hh:mm aa", calendar).toString()
date!!.text = time
}
and this is the error
java.lang.NumberFormatException: For input string: "1594502477561"
at java.lang.Integer.parseInt(Integer.java:618)
at java.lang.Integer.parseInt(Integer.java:650)
at com.google.meetchat.Adapters.ChatAdapter.onBindViewHolder(ChatAdapter.kt:64)
at com.google.meetchat.Adapters.ChatAdapter.onBindViewHolder(ChatAdapter.kt:18)
line 64 is where chatTIme Variable is initialized
You are using not-null assertion operator (!!) on some variables. It converts any value to a non-null type and throws an exception if the value is null.
I suspect you are getting NullPointerException when you use that operator on a variable. Please make sure that these variables are initialized before using operator !! on them:
chat, chat.timestamp, holder.date
UPDATE:
Please use Long for timestamps, don't convert them to Int. For example replace:
val currentTime = System.currentTimeMillis().toInt()
val chatTime: Int = chat.timestamp!!.toInt()
with:
val currentTime = System.currentTimeMillis()
val chatTime = chat.timestamp!!.toLong()
That's because timestamps are represented in milliseconds (or seconds if it is Unix timestamp) and the value can be higher than max value of Int type which is public const val MAX_VALUE: Int = 2147483647.
Related
I need to get this week startdate like 2023-02-20 and last week startdate and end date.
startdate will be monday.
so I create 4 variables like below.
private var thisWeekStart : Long = 0
private var thisWeekEnd : Long = 0
private var lastWeekStart : Long = 0
private var lastWeekEnd : Long = 0
And I tried to assign something like below..
var cal = Calendar.getInstance()
cal.time = Date()
thisWeekEnd = cal.timeInMillis
// 이번주 시작
cal.get(Calendar.DAY_OF_WEEK)
thisWeekStart = cal.timeInMillis
cal.add(Calendar.DAY_OF_WEEK, -1)
lastWeekStart = cal.timeInMillis
cal.clear()
cal.set(Calendar.DAY_OF_WEEK, -1)
lastWeekStart = cal.timeInMillis
But it throws milliseconds not like yyyy-MM-dd format.
And I'm not sure is that correct way of keep clearing calendar like above.
Most of all, I can't get last week's end date with above way.
Is there any good way to get this weed and last week start, end date?
At first, we define our desired output format. In this case we will use yyyy-MM-dd. In the next step we save the current date in a variable. In the third line we define timezone in which we are working (I used Europe/Berlin for testing purposes, bacause I'm in germany).
In the next steps we create Calendar instance for each desired date and manipulate the date to our needs.
Important: You have to add the line firstDayOfWeek = Calendar.MONDAY only if your week starts at another date than Sunday.
val dateFormat = SimpleDateFormat("yyyy-MM-dd")
val today = Calendar.getInstance()
val timeZone = TimeZone.getTimeZone("Europe/Berlin")
val startOfWeek = Calendar.getInstance(timeZone).apply {
firstDayOfWeek = Calendar.MONDAY
set(Calendar.DAY_OF_WEEK, Calendar.MONDAY)
}.time
val endOfWeek = Calendar.getInstance(timeZone).apply {
firstDayOfWeek = Calendar.MONDAY
set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
}.time
val startOfLastWeek = Calendar.getInstance(timeZone).apply {
firstDayOfWeek = Calendar.MONDAY
set(Calendar.WEEK_OF_YEAR, today.get(Calendar.WEEK_OF_YEAR) - 1)
set(Calendar.DAY_OF_WEEK, Calendar.MONDAY)
}.time
val endOfLastWeek = Calendar.getInstance(timeZone).apply {
firstDayOfWeek = Calendar.MONDAY
set(Calendar.WEEK_OF_YEAR, today.get(Calendar.WEEK_OF_YEAR) - 1)
set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
}.time
val startOfWeekAsString = dateFormat.format(startOfWeek)
val endOfWeekAsString = dateFormat.format(endOfWeek)
val startOfLastWeekAsString = dateFormat.format(startOfLastWeek)
val endOfLastWeekAsString = dateFormat.format(endOfLastWeek)
println("Start of week: $startOfWeekAsString")
println("End of week: $endOfWeekAsString")
println("Start of last week: $startOfLastWeekAsString")
println("End of last week: $endOfLastWeekAsString")
Expected output:
Start of week: 2023-02-13
End of week: 2023-02-19
Start of last week: 2023-02-06
End of last week: 2023-02-12
fun getStartAndEndDayByToday(today: Calendar): ArrayList<String> {
val startAndEndDayArray = ArrayList<String>()
// Get the day of this week today
val todayWeekDay = today.get(Calendar.DAY_OF_WEEK)
// Below you can get the start day of week; it would be changeable according to local time zone
today.add(Calendar.DAY_OF_MONTH, 1 - todayWeekDay)
val calStartDayOfWeek = today.time
// Below you can get the end day of week; it would be changeable according to local time zone
today.add(Calendar.DAY_OF_MONTH, 6)
val calEndDayOfWeek = today.time
// Here you can set the date format by using SimpleDateFormat
val sdfStartDayOfWeek = SimpleDateFormat("yyyy-MM-dd")
val sdfEndDayOfWeek = SimpleDateFormat("yyyy-MM-dd")
// Make the array with start date and end date
startAndEndDayArray.add(sdfStartDayOfWeek.format(calStartDayOfWeek))
startAndEndDayArray.add(sdfEndDayOfWeek.format(calEndDayOfWeek))
return startAndEndDayArray
}
Hope this would help!
What I am trying to do is given a list of objects responseList<Object> in which the objects have a date field on string format "2015-01-16", filter the list to only get objects form last month or the current year and add the filtered objects to a new list.
The first thing that I have done is convert the string into date and the result is "Fri Jan 16 00:00:00 GMT-05:00 2015".
using:
val dateformated = getFormatedDate(object.date)
val cal = Calendar.getInstance()
cal.time = dateFormated; //date formatted is the string converted to date
var responseMonth = cal.get(Calendar.MONTH)
var responseYear = cal.get(Calendar.YEAR)
I am able to retrieve both month and year of the response and using this:
val now: LocalDate = LocalDate.now()
val lastMonth = now.minusMonths(1).month
val thisYear = now.year
I get the current year and month
What I am failing to is filtering the object list based on the requirement to create another list.
Any help or suggestions would be great, thanks
#Test
fun filterDateListByLastMonthOrThisYear() {
val fakeDateOne = LocalDate.of(2023, 2, 1)
val fakeDateTwo = LocalDate.of(2020, 3, 12)
val fakeDateThree = LocalDate.of(1999, 12, 31)
val fakeDateFour = LocalDate.of(2023, 2, 2)
val fakeDateFive = LocalDate.of(2023, 1, 3)
val datesList = listOf(
fakeDateOne,
fakeDateTwo,
fakeDateThree,
fakeDateFour,
fakeDateFive
)
val today = LocalDate.now()
val lastMonth = today.month.minus(1)
val thisYear = today.year
val expected = listOf(fakeDateOne, fakeDateFour, fakeDateFive)
val actual = datesList.filter { it.year == thisYear || it.month == lastMonth }
assertEquals(expected, actual)
}
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")
I believe this question and answer explains how to format time series data into readable date labels in Java. How do you do the same thing in Kotlin?
You could create a custom formatter class extending the IAxisValueFormatter:
class MyCustomFormatter() : IAxisValueFormatter
{
override fun getFormattedValue(value: Float, axis: AxisBase?): String
{
val dateInMillis = value.toLong()
val date = Calendar.getInstance().apply {
timeInMillis = dateInMillis
}.time
return SimpleDateFormat("dd MMM", Locale.getDefault()).format(date)
}
}
Then assign it to your chart with
chart?.xAxis?.valueFormatter = MyCustomFormatter()
Using version 3.0+ of the MPAndroidChart:
Set formatter to the x axis:
// Formatter to adjust epoch time to readable date
lineChart.xAxis.valueFormatter = LineChartXAxisValueFormatter()
Create a new class LineChartXAxisValueFormatter:
class LineChartXAxisValueFormatter : IndexAxisValueFormatter() {
override fun getFormattedValue(value: Float): String? {
// Convert float value to date string
// Convert from seconds back to milliseconds to format time to show to the user
val emissionsMilliSince1970Time = value.toLong() * 1000
// Show time in local version
val timeMilliseconds = Date(emissionsMilliSince1970Time)
val dateTimeFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault())
return dateTimeFormat.format(timeMilliseconds)
}
}
When the entries are added to the ChartDataArray they are added in seconds, not milliseconds, to avoid potential precision issues with inputting as a float (i.e. milliseconds divided by 1000).
chartDataArray.add(Entry(secondsSince1970.toFloat(), yValue.toFloat()))
Happy coding!
In Kotlin how to parse a double or float number from string like this:
var st: String? = "90 min"
tried to use toDoubleOrNull but always returns 0 or null.
If you are certain that the number is always at the start, then use split() with space as delimiter and from the returned list take the 1st item and parse it to Double:
val value = st!!.split(" ")[0].toDoubleOrNull()
If there is a case of spaces at the start or in between, use this:
val value = st!!.trim().split("\\s+".toRegex())[0].toDoubleOrNull()
And another way with substringBefore():
val value = st!!.trim().substringBefore(" ").toDoubleOrNull()
Or if there is only 1 integer number in the string, remove every non numeric char with replace():
val value = st!!.replace("\\D".toRegex(), "").toDoubleOrNull()
You can try (assuming you have only one sequence of numbers in your string).
Otherwise, check other answers
val inputString = "123. Test"
val regex = "\\d+(\\.\\d+)?".toRegex()
val match = regex.find(inputString)
if (match != null) {
println("Result: " + match.value)
} else {
println("Result: Not found")
}
This should work...
val pattern = Pattern.compile("\\d+") // the regex
val matcher = pattern.matcher("hello123hgj") // your string
val doubles = ArrayList<Double>() // results
while (matcher.find())
{ // for each match
doubles.add(Double.parseDouble(matcher.group())) // convert to double
}
It depends on what you need. If you just have to get 90 and the string is formatted always in the same way you can just
var string = "90 min"
var floatFromString = string.substring(0,2).toFloat()
but it's better to learn how to use LocalDate and DateTimeFormatter