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
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.
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)
}
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.
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
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()
}
}