I am trying to figure out how this works. My initial date is: "2022-11-06T08:39:16.307Z"
So now I did this:
val sdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
sdf.timeZone = TimeZone.getTimeZone("UTC")
val time: Long = sdf.parse("2022-11-06T08:39:16.307Z").time
val calendar = Calendar.getInstance()
val currentTime = calendar.timeInMillis
val diff = (currentTime - time) / 1000
Difference is negative number but it should be positive as other date is in past. Yes I hate working with dates in general but can not figure out why it works like this.
What I expect: the 'for loop' brings the number of columns that will be displayed in the table, the start date, and the end date are taken by an object. the transaction date is taken by a different object. The start date variable gets the exception and the transaction date gets the value without a problem.
Code:
if(date >0){//no of dates for the selected week
for (i in 0 until date) {
val dateFormat = SimpleDateFormat("yyyy-MM-dd")
val tv_Date = TextView(this)
val transDate = SortedDateHashMap[i].transactionDate
val start = SortedExpenseDateHashMap[i]!!.weekStart
val end = SortedExpenseDateHashMap[i]!!.weekEnd
val startDate = dateFormat.parse(start)
val endDate = dateFormat.parse(end)
var transactionDat = dateFormat.parse(transDate)
if(transactionDat.before(endDate) && transactionDat.after(startDate)){
setColor(tv_Date)
tv_Date.setPadding(10, 15, 10, 10)
tv_Date.gravity = Gravity.CENTER
tv_Date.layoutParams = params3
tv_Date.text = SortedDateHashMap[i].transactionDate
}
}
}
Used null safe and wrote the code in the try..catch exception. Worked
I have a Date Range Picker(Material Design) and I want to disable previous dates(so minimum date will be current day), and maximum date will be 6 months later. I tried something like this:
val calendar = Calendar.getInstance()
val constraintsBuilderRange = CalendarConstraints.Builder()
val dateValidatorMin: CalendarConstraints.DateValidator = DateValidatorPointForward.from(calendar.timeInMillis)
val dateValidatorMax: CalendarConstraints.DateValidator = DateValidatorPointBackward.before(calendar.timeInMillis+100000000)
val listValidators = ArrayList<CalendarConstraints.DateValidator>()
listValidators.add(dateValidatorMin)
listValidators.add(dateValidatorMax)
val validators = CompositeDateValidator.allOf(listValidators)
constraintsBuilderRange.setValidator(validators)
val datePicker = MaterialDatePicker.Builder.dateRangePicker()
.setTitleText("Select range")
.setCalendarConstraints(constraintsBuilderRange.build())
.build()
datePicker.show(
this.requireFragmentManager(),"date_range_picker"
)
This worked but I randomly give 100000000 to dateValidatorMax. So how can I achieve 6 months later in milliseconds? And how can I get 1 day before currentDate in dateValidatorMin?
So I solved this problem thanks to Kotlin, there is a really easy method:
val dateValidatorMin: CalendarConstraints.DateValidator = DateValidatorPointForward.from(calendar.timeInMillis - 1.days.toLong(
DurationUnit.MILLISECONDS))
val dateValidatorMax: CalendarConstraints.DateValidator = DateValidatorPointBackward.before(calendar.timeInMillis+ 180.days.toLong(
DurationUnit.MILLISECONDS))
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))
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.
I have a data class as below in Kotlin.
data class ProductData(
val code: String,
var value: Double)
There are two list for the above data class as
lstToday: List<ProductData> contains such as
("P1", 110)
("P2", 109)
("P3", 102)
("P4", 110)
..... 100+ records
and
lstYesterday: List<ProductData> contains such as
("P1", 112)
("P2", 109)
("P3", 110)
("P4", 90)
..... 100+ records
Both has the identical and exact number of records.
The output I am looking for is as below.
Output 1: Difference between yesterday and today
lstDifference: List<ProductData> contains such as
("P1", -2)
("P2", 0)
("P3", 8)
("P4", -20)
..... 100+ records
Output 2: Today Price and Difference between yesterday and today
using the data class below.
data class ProductDisplayData(
val code: String,
var value: Double,
var diff: Double
)
With list as below
lstDifference: List<ProductData> contains such as
("P1", 112, -2)
("P2", 109, 0)
("P3", 110, 8)
("P4", 90, -20)
..... 100+ records
Can this be achieved using any functions Kotlin, or is it we have loop each element and get the result.
Thanks
I would say this is not the most efficient solution. We're talking 0n ish. This could definitely be optimized. To note, this is fault tolerant of the code itself not being included in both days, and assumes 0 for a non-existent value between days.
Trying to guarantee that both data sets will always be the same, is going to be more maintenance than writing code that will tolerate that mistake.
data class ProductData(
val code: String,
var value: Double
)
val dayOne = listOf(
ProductData("P1", 110.0),
ProductData("P2", 109.0),
ProductData("P3", 102.0),
ProductData("P4", 110.0),
ProductData("P5", 105.0),
ProductData("P6", 104.0),
ProductData("P8", 32.0) // Not in set 2
)
val dayTwo = listOf(
ProductData("P1", 110.0),
ProductData("P2", 109.0),
ProductData("P3", 102.0),
ProductData("P4", 90.0),
ProductData("P5", 49.0),
ProductData("P6", 123.0),
ProductData("P7", 239.0) // Not in set 1
)
fun periodDataDifference(dayOne: List<ProductData>, dayTwo: List<ProductData>): List<ProductData> {
val mapOne = dayOne.associate { it.code to it.value }
val mapTwo = dayTwo.associate { it.code to it.value }
val keys = mapOne.keys + mapTwo.keys
return keys.map { key ->
val first = mapOne[key] ?: 0.0
val second = mapTwo[key] ?: 0.0
ProductData(key, second - first)
}
}
val out = periodDataDifference(dayOne, dayTwo)
println(out)
/*
[ProductData(code=P1, value=0.0),
ProductData(code=P2, value=0.0),
ProductData(code=P3, value=0.0),
ProductData(code=P4, value=-20.0),
ProductData(code=P5, value=-56.0),
ProductData(code=P6, value=19.0),
ProductData(code=P8, value=-32.0), // Set 1 only
ProductData(code=P7, value=239.0)] // Set 2 only
*/
If today and yesterday lists are gonna be same size this is the quickest solution I have
val lstYesterday: List<ProductData> = listOf(
ProductData("P1", 112.0),
ProductData("P2", 109.0),
ProductData("P3", 110.0)
)
val lstToday: List<ProductData> = listOf(
ProductData("P1", 110.0),
ProductData("P2", 109.0),
ProductData("P3", 102.0)
)
val lstDifference: MutableList<ProductData> = mutableListOf()
for ((index,j) in lstToday.withIndex()){
val code = lstToday[index].code
val value = lstToday[index].value-lstYesterday[index].value
lstDifference.add(ProductData(code,value))
}
binding.etFirstTime.setOnClickListener{
val picker = MaterialTimePicker.Builder ()
.setTimeFormat(TimeFormat.CLOCK_12H)
. setHour( 12 )
.setMinute(10)
.setTitleText("Select Shop's Timing")
.build()
picker.showNow(childFragmentManager,"Time")
picker.addOnPositiveButtonClickListener{
}
}
You don't need to get the time format.
Just use picker.hour. It returns the hour of day in the range [0, 23]
Try this
val selectedTime = Calendar.getInstance()
selectedTime[0, 0, 0, picker.hour, picker.minute] = 0
val formattedTime = SimpleDateFormat("hh:mm:ss a", Locale.getDefault()).format(selectedTime.time)
Output example: 09:45:00 PM