LocalDateTime plusDays() dont work when is the end of the month - android

I'm testing my app today(may 30) whith a custom hour and minute:
var today=LocalDateTime.now().withHour(hour).withMinute(minute).withSecond(0).withNano(0)
But, when i do:
today=today.plusDays(1) //today is: 2022-03-30T10:04
It's return in the Log:
2022-03-30T10:04
UPDATE: Here is the complete code. I'm testing on Android 8.1.0
fun calcEndTime(hour: Int, minute: Int, initinmilliseconds:Long):Long {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
var endtime =LocalDateTime.now().withHour(hour).withMinute(minute).withSecond(0).withNano(0)
val now = LocalDateTime.now().withSecond(0).withNano(0)
val inittime = Instant.ofEpochMilli(initinmilliseconds).atZone(ZoneOffset.UTC).toLocalDateTime()
val days=inittime.dayOfMonth-now.dayOfMonth
if(days==1||days<0){
endtime=endtime.plusDays(1)
Log.d("ZXCV","if ${endtime}")
}
if (endtime.isBefore(now)) {
endtime = endtime.plusDays(1)
}
return endtime.toInstant(ZoneOffset.UTC).toEpochMilli()
}
}

Tried doing it this way, it seems to work just fine šŸ§
fun calcEndTime(hour: Int, minute: Int, initinmilliseconds: Long): LocalDateTime {
var endtime = LocalDateTime.now().withHour(hour).withMinute(minute).withSecond(0).withNano(0)
val now = LocalDateTime.now().withSecond(0).withNano(0)
val inittime = Instant.ofEpochMilli(initinmilliseconds).atZone(ZoneOffset.UTC).toLocalDateTime()
val days = inittime.dayOfMonth - now.dayOfMonth
if (days == 1 || days < 0) {
endtime = endtime.plusDays(1)
Log.d("ZXCV", "if ${endtime}")
}
if (endtime.isBefore(now)) {
endtime = endtime.plusDays(1)
Log.d("ZXCV2", "if ${endtime}")
}
return endtime//.toInstant(ZoneOffset.UTC).toEpochMilli() // try commenting this out to return LocalDateTime instead
}
sample usage:
binding.buttonFirst.setOnClickListener {
val hour = 10
val minute = 4
var today = calcEndTime(hour, minute, 1648706400000)
var test = "TESTING today" + "\n"
test += today.toString() + "\n"
today = today.plusDays(1)
test += today.toString() + "\n"
binding.textviewFirst.text = test
}
Screenshot

Related

Get app usage from yesterday with UsageStatsManager

I tried to get the app usage from previous day 0 o'clock to today 0 o'clock.
Here is my Code:
val midnight = LocalTime.MIDNIGHT
val today = LocalDate.now()
val todayMidnight = LocalDateTime.of(today, midnight)
val todayMidnightMillis = toMillis(todayMidnight)
val yesterdayMidnightMillis = toMillis(todayMidnight.minusDays(1))
val usageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
val queryUsageStatsMap = usageStatsManager.queryAndAggregateUsageStats(yesterdayMidnightMillis, todayMidnightMillis)
val appInfoMap = getNonSystemAppsList()
for (packageName in appInfoMap) {
val usageStats = queryUsageStatsMap.get(packageName.key)
if (usageStats != null) {
if (usageStats.totalTimeVisible > 0) {
val name = usageStats.packageName
val hours = TimeUnit.MILLISECONDS.toHours(usageStats.totalTimeVisible) % 24
val minutes = TimeUnit.MILLISECONDS.toMinutes(usageStats.totalTimeVisible) % 60
val seconds = TimeUnit.MILLISECONDS.toSeconds(usageStats.totalTimeVisible) % 60
//insert into database
}
}
}
private fun toMillis(dateTime: LocalDateTime): Long {
return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
}
For example:
yesterdayMidnightMillis = 1673996400000 (18.01.2023-00:00)
todayMidnightMillis = 1674082800000 (19.01.2023-00:00)
For example, when I call this method(19.01.2023-15:00), the method gives me an app usage of 10 min. If I wait a minute and call the method again, the method gives me an app usage of 11 min.
Since I am not in the specified time interval during this time, the app usage must not increase.

Android Joda-Time with Kotlin

I am trying to create a function to check a given string time HH:mm is in range of another comparing to now.
Example: if the current hour is between 12:35 and 15:00 return true
But I always got false even if the current time is in range..
fun isTimeInRange(before: String, after: String): Boolean {
val now = DateTime.now()
val format = DateTimeFormat.forPattern("HH:mm")
return now >= DateTime.parse(before, format) && now <= DateTime.parse(after, format)
}
You need to do:
fun isTimeInRange(before: String, after: String): Boolean {
val now = DateTime.now()
val format = DateTimeFormat.forPattern("HH:mm")
return now.isAfter(DateTime.parse(before, format)) && now.isBefore(DateTime.parse(after, format))
}
Or use intervals.
You have to set before/after date to today's date. try this:
fun isTimeInRange(start: String, end: String): Boolean {
val now = DateTime.now()
val format = DateTimeFormat.forPattern("HH:mm")
val startTime: LocalTime = format.parseLocalTime(start)
val endTime: LocalTime = format.parseLocalTime(end)
val timeZone = DateTimeZone.getDefault()
val today: LocalDate = LocalDate.now(timeZone)
val startMoment: DateTime = today.toLocalDateTime(startTime).toDateTime(timeZone)
val endMoment: DateTime = today.toLocalDateTime(endTime).toDateTime(timeZone)
return now.isAfter(startMoment) && now.isBefore(endMoment)
}

Kotlin - Issue in getting milliseconds for Time passed

I have created below method to get the milliseconds from 12 hour format time :
fun getMillisecondsFromTime(time: String): String {
val formatter = SimpleDateFormat("hh aa")
formatter.isLenient = false
val oldDate = formatter.parse(getLocaleTime(time,"hh aa"))
val oldMillis = oldDate.time
return "" + oldMillis
}
I am calling this method as below for four different times:
var strTime1:String = DateUtils.getMillisecondsFromTime("1 PM")//13 * 3600
var strTime2:String = DateUtils.getMillisecondsFromTime("2 PM")//14 * 3600
var strTime3:String = DateUtils.getMillisecondsFromTime("1 AM")//1 * 3600
var strTime4:String = DateUtils.getMillisecondsFromTime("2 AM")//2 * 3600
Result am getting is wrong. i.e. for 1 PM milliseconds should be 48600 But, am getting :
1Ā PMĀ >>>>>: 45000000, should be 48600
2Ā PMĀ >>>>>: 48600000, should be 50400
What might be the issue?
EDIT : getting local time as below :
fun getLocaleTime(date: String, timeFormat: String): String {
val df = SimpleDateFormat(timeFormat, Locale.ENGLISH)
df.timeZone = TimeZone.getTimeZone("UTC")
val date = df.parse(date)
df.timeZone = TimeZone.getDefault()
val formattedDate = df.format(date)
return formattedDate
}
You need to get hours of the day using Calendar. And then multiply it with 3600. Like
fun getMillisecondsFromTime(time: String): String {
val formatter = SimpleDateFormat("hh aa")
formatter.isLenient = false
val oldDate = formatter.parse(getLocaleTime(time,"hh aa"))
// val oldMillis = oldDate.time
val cal = GregorianCalendar.getInstance()
cal.time = oldDate
val hourIn24Format = cal.get(Calendar.HOUR_OF_DAY)
return "" + (hourIn24Format * 3600)
}
Your current code is returning time in millies from milliseconds since January 1, 1970, 00:00:00 GMT to the time you gave as input.
Note:
I am not sure what you are trying to achieve in this way, but this seems not a good way. If you can explain more about your requirements, I or any other can guide you for better ways.

How to format in Kotlin date in string or timestamp to my preferred format?

I'm getting date data from weather API in two versions. The first one is just string like this: 2019-08-07 09:00:00 and like this: 1565209665. How do I change it to just the name of the day or day and month?
For example Monday, August.
I tried something like this in few configurations but it works only in full version. If I cat something then it throws an error:
var date = list.get(position).dt_txt
val formatter = DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd HH:mm:ss").toFormatter()
formatter.parse(date)
First API format:
val firstApiFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
val date = LocalDate.parse("2019-08-07 09:00:00" , firstApiFormat)
Log.d("parseTesting", date.dayOfWeek.toString()) // prints Wednesday
Log.d("parseTesting", date.month.toString()) // prints August
Second API format:
val secondApiFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")
val timestamp = 1565209665.toLong() // timestamp in Long
val timestampAsDateString = java.time.format.DateTimeFormatter.ISO_INSTANT
.format(java.time.Instant.ofEpochSecond(timestamp))
Log.d("parseTesting", timestampAsDateString) // prints 2019-08-07T20:27:45Z
val date = LocalDate.parse(timestampAsDateString, secondApiFormat)
Log.d("parseTesting", date.dayOfWeek.toString()) // prints Wednesday
Log.d("parseTesting", date.month.toString()) // prints August
This is really simple
val dateFormated = SimpleDateFormat("dd/MM/yyyy").format(trans.created_date.toDate())
I hope this works for everybody, thanks to https://www.datetimeformatter.com/how-to-format-date-time-in-kotlin/
Try this code to get dayOfWeek and month name
Code
To String Date
Method
fun getAbbreviatedFromDateTime(dateTime: String, dateFormat: String, field: String): String? {
val input = SimpleDateFormat(dateFormat)
val output = SimpleDateFormat(field)
try {
val getAbbreviate = input.parse(dateTime) // parse input
return output.format(getAbbreviate) // format output
} catch (e: ParseException) {
e.printStackTrace()
}
return null
}
*How to use
val monthName=getAbbreviatedFromDateTime("2019-08-07 09:00:00","yyyy-MM-dd HH:mm:ss","MMMM")
println("monthName--"+monthName)
val dayOfWeek=getAbbreviatedFromDateTime("2019-08-07 09:00:00","yyyy-MM-dd HH:mm:ss","EEEE")
println("dayOfWeek--"+dayOfWeek)
To Timemillis
Methods
fun convertStringToCalendar( timeMillis: Long) {
//get calendar instance
val calendarDate = Calendar.getInstance()
calendarDate.timeInMillis = timeMillis
val month=getAbbreviatedFromDateTime(calendarDate,"MMMM");
val day=getAbbreviatedFromDateTime(calendarDate,"EEEE");
Log.d("parseTesting", month)// prints August
Log.d("parseTesting",day)// prints Wednesday
}
fun getAbbreviatedFromDateTime(dateTime: Calendar, field: String): String? {
val output = SimpleDateFormat(field)
try {
return output.format(dateTime.time) // format output
} catch (e: Exception) {
e.printStackTrace()
}
return null
}
Use
val timestamp = "1565209665".toLong()
convertStringToCalendar(timestamp)
Try this
val stringDate="2019-08-07 09:00:00"
val dateFormat_yyyyMMddHHmmss = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.ENGLISH
)
val date = dateFormat_yyyyMMddHHmmss.parse(stringDate)
val calendar = Calendar.getInstance()
calendar.setTime(date)
val dayOfWeekString = calendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.ENGLISH)
Output:
dayOfWeekString : wednesday
val timeInMillis = 1565242471228
val calendar = Calendar.getInstance()
calendar.setTimeInMillis(timeInMillis)
val dayOfWeekString = calendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.ENGLISH)
val parsedDate: String? = if(monthOfYear < 10 && dayOfMonth > 10){
"${dayOfMonth}/0${monthOfYear + 1}/${year}"
} else if(dayOfMonth < 10 && monthOfYear > 10) {
"0${dayOfMonth}/${monthOfYear + 1}/${year}"
} else if(dayOfMonth < 10 && monthOfYear < 10){
"0${dayOfMonth}/0${monthOfYear + 1}/${year}"
}else{
"0${dayOfMonth}/${monthOfYear + 1}/${year}"
}
date?.text = parsedDate
I tried different things but in Date picker this works for me in kotlin

How convert timestamp in Kotlin

l am try to convert timeestamp coming from data json url
TimeFlight.text = list[position].TimeFlight.getDateTime(toString())
l am use list view in my app
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val view : View = LayoutInflater.from(context).inflate(R.layout.row_layout,parent,false)
val TimeFlight = view.findViewById(R.id.time_id) as AppCompatTextView
val LogoAriline = view.findViewById(R.id.logo_image) as ImageView
status.text= list[position].Stauts
TimeFlight.text = list[position].TimeFlight.getDateTime(toString())
Picasso.get().load(Uri.parse("https://www.xxxxxxxxx.com/static/images/data/operators/"+status.text.toString()+"_logo0.png"))
.into(LogoAriline)
return view as View
}
private fun getDateTime(s: String): String? {
try {
val sdf = SimpleDateFormat("MM/dd/yyyy")
val netDate = Date(Long.parseLong(s))
return sdf.format(netDate)
} catch (e: Exception) {
return e.toString()
}
}
Data class for json
data class FlightShdu (val Airline : String ,val TimeFlight : String)
l used that code getDateTime but the format unknown
Assuming TimeFlight is a stringified epoch timestamp (in milliseconds), you should pass that to your getDateTime() function:
TimeFlight.text = getDateTime(list[position].TimeFlight)
(if they are not millis but seconds, then simply multiply them by 1000 before passing them to the Date constructor)
On a side note, depending on the exact use case, creating a new SimpleDateFormat object might not be necessary on every getDateTime() call, you can make it an instance variable.
Also, i'd advise you to take a look at (and follow) the Java naming conventions for both Java and Kotlin applications.
The problem here is that the Date constructor take long as the milliseconds count since 1/1/1970 and the number you are getting is the seconds count.
my suggestion is the following code( you can change the formate):
const val DayInMilliSec = 86400000
private fun getDateTime(s: String): String? {
return try {
val sdf = SimpleDateFormat("MM/dd/yyyy")
val netDate = Date(s.toLong() * 1000 ).addDays(1)
sdf.format(netDate)
} catch (e: Exception) {
e.toString()
}
}
fun Date.addDays(numberOfDaysToAdd: Int): Date{
return Date(this.time + numberOfDaysToAdd * DayInMilliSec)
}
private fun getDateTime(s: String): String? {
return try {
val date = SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(Date(s.toLong()*1000))
// current timestamp in sec
val epoch = System.currentTimeMillis()/1000
// Difference between two epoc
val dif = epoch - s.toLong()
val timeDif: String
when {
dif<60 -> {
timeDif = "$dif sec ago"
}
dif/60 < 60 -> {
timeDif = "${dif/60} min ago"
}
dif/3600 < 24 -> {
timeDif = "${dif/3600} hour ago"
}
dif/86400 < 360 -> {
timeDif = "${dif/86400} day ago"
}
else ->{
timeDif = "${dif/31556926} year ago"
}
}
"($timeDif) $date"
} catch (e: Exception) {
e.toString()
}
}

Categories

Resources