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()
}
}
Related
I'm trying to make a string format that, when a user post is uploaded, it expresses the upload time as "~ minutes ago" or "~ hours ago" and so on.
My application works in the way like below
upload post in PostActivity > firebase saves the data of the post (the post is consist of postId, writerId, message, writeTime, bgUri for image, commentCount) > MainActivity gets data from firebase and shows the post on RecycleView by MyAdapter.kt
Below is the PostActivity.kt
class PostActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_post)
supportActionBar?.title = "New Post"
val layoutManager = LinearLayoutManager(this#PostActivity)
layoutManager.orientation = LinearLayoutManager.HORIZONTAL
recyclerView2.layoutManager=layoutManager
recyclerView2.adapter = MyAdapter()
postButton.setOnClickListener {
val newRef = FirebaseDatabase.getInstance().getReference("Posts").push()
post.writeTime= DateTime().toString()
newRef.setValue(post)
finish()
}
}
The writeTime field of post is DateTime().toString().
For the string format, I made a function getdiffTimeText() at MyAdapter.kt which is below.
class MyAdapter(private val posts : MutableList<Post>) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() { //line 20
override fun onBindViewHolder(holder: MyAdapter.MyViewHolder, position: Int) {
val post = posts[position]
holder.timeTextView.text = getDiffTimeText(post.writeTime) //line 32
}
public class MyViewHolder(itemView : View) :
val timeTextView = itemView?.findViewById<TextView>(R.id.timeTextView) //line 51
}
}
fun getDiffTimeText(targetTime: String): String {
val curDateTime = DateTime()
val targetDateTime = DateTime(targetTime)
val diffDay = Days.daysBetween(curDateTime, targetDateTime).days
val diffHours = Hours.hoursBetween(targetDateTime, curDateTime).hours
val diffMinutes = Minutes.minutesBetween(targetDateTime, curDateTime).minutes
if (diffDay == 0) {
if (diffDay == 0 && diffMinutes == 0) {
return "just before"
}
return if (diffHours > 0) {
"" + diffHours + "hours ago"
} else "" + diffMinutes + "minutes ago"
} else {
val format = SimpleDateFormat("yyyy.MM.dd")
return format.format(Date(targetTime))
}
}
Below is the MainActivity
class MainActivity : AppCompatActivity() {
val posts: MutableList<Post> = mutableListOf()
private lateinit var dbref: DatabaseReference
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
getUserData()
}
private fun getUserData() {
dbref = FirebaseDatabase.getInstance().getReference("/Posts")
dbref.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.exists()) {
for (userSnapshot in snapshot.children) {
val post = userSnapshot.getValue(Post::class.java)
posts.add(post!!)
}
recyclerView_main.adapter = MyAdapter(posts)
}
}
override fun onCancelled(error: DatabaseError) {
Toast.makeText(this#MainActivity,"failed",Toast.LENGTH_SHORT).show()
}
})
}
}
Below is Post.kt the class of user's post.
class Post {
var postId = ""
var writerId = ""
var message = ""
var writeTime = ""
var bgUri = ""
var commentCount = ""
}
When I run the code, app crashes with the error below.
java.lang.IllegalArgumentException: Invalid format: "1661861458" is malformed at "8"
at org.joda.time.DateTime.<init>(DateTime.java:257)
at <<package name>>.MyAdapterKt.getDiffTimeText(MyAdapter.kt:51)
at <<package name>>.MyAdapter.onBindViewHolder(MyAdapter.kt:32)
at <<package name>>.MyAdapter.onBindViewHolder(MyAdapter.kt:20)
To test the fuction getDiffTimeText() I tried the code below in different activity.
val testTime = DateTime().toString()
val testText = findViewById<TextView>(R.id.testing)
val testText2 = findViewById<TextView>(R.id.testing2)
testText.text = testTime
testText2.text = getDiffTimeText(testTime)
The testTime is String type just like the Post.kt where the type of writeTime field is String.
As the result, textview testText shows 2022-08-31T05:37:55.778Z which is the current time, and testText2 shows just ago.
So it seems the function getDiffTimeText works in this way. But It doesn't work in holder.timeTextView.text = getDiffTimeText(post.writeTime) which is MyAdapter.kt line 32, and the app crashes.
How should I solve this?
*edited my question for clearence, codes that are less relevant are excluded.
Seem the timestamp you passed in line 32 holder.timeTextView.text = getDiffTimeText(post.writeTime) is counting with second instead of millis.
You can try to changed your remote time to millis or just do like that:
val timeInMillis = post.writeTime.toLong() * 1000L // maybe toLongOrNull() for safe usage.
holder.timeTextView.text = getDiffTimeText(timeInMillis.toString())
I used this approach to fix my issue: Though in my case I was just calculating the time and not date. But you can have some idea.
So I was trying to store the time in milliseconds and then retrieving it back to show in a desired format:
Here are the steps I followed:
First saving the time in database
Getting the time from Time Picker :
val h = picker.hour
val m = picker.minute
Converting the total time to milliseconds
val hour = TimeUnit.HOURS.toMillis(h.toLong())
val minute = TimeUnit.MINUTES.toMillis(m.toLong())
val totalTime = hour + minute
Saving the time as a string. (in my case it was Room DB, you can do on Firebase)
Now retrieving the time from database
Initially converted the entered time back to Long from String
val timeMilliseconds = totalTime.toLong()
Converting the milliseconds to hours, minutes and seconds with help of function
val startTime = formatToDigitalClock(timeMilliseconds)
The function
//Converting received long time to proper digital format
private fun formatToDigitalClock(milliseconds: Long): String {
val hours = TimeUnit.MILLISECONDS.toHours(milliseconds).toInt() % 24
val minutes = TimeUnit.MILLISECONDS.toMinutes(milliseconds).toInt() % 60
val seconds = TimeUnit.MILLISECONDS.toSeconds(milliseconds).toInt() % 60
return when {
hours > 0 -> String.format("%d:%02d:%02d", hours, minutes, seconds)
minutes > 0 -> String.format("%02d:%02d", minutes, seconds)
seconds > 0 -> String.format("00:%02d", seconds)
else -> {
"00:00"
}
}
}
You can further change the String format in a way so that you can show your time like ("2 hours ago")
If post.writeTime.toLong() causes a java.lang.NumberFormatException: For input string: "2022-08-31T04:20:45.265Z", I'll have to conclude that the type of post.writeTime is String in ISO standard.
There's a simple way to parse those ISO standards in java.time, in this case you can do
OffsetDateTime.parse(post.writeTime)
and use that to calculate the difference / time elapsed until now (in code: OffsetDateTime.now(ZoneOffset.UTC)). You will need a ZoneOffset because the String returned by post.writeTime also has one (the Z at the end is UTC resp. an offset of +00:00 hours).
The elapsed time can be calculated by means of a java.time.Duration:
val duration = Duration.between(
OffsetDateTime.parse(post.writeTime),
OffsetDateTime.now(ZoneOffset.UTC)
)
A Duration represents elapsed time in hours, minutes, seconds, millis and even nanos, I think. However, only hours, minutes and seconds should matter here (correct me if I'm wrong).
Now the Kotlin magic comes into play: We can write an extension function for Duration, one that simply checks the values top-down (hours first, if zero, use minutes, if zero, use seconds, if zero write some statement):
fun Duration.timeAgo(): String {
return when {
this.toHours() > 0 -> "${this.toHours()} hours ago"
this.toMinutes() > 0 -> "${this.toMinutes()} minutes ago"
this.toSeconds() > 0 -> "${this.toSeconds()} seconds ago"
else -> "a moment ago"
}
}
Example in a main using the time String from your comment below another answer and the code mentioned above (in this answer):
fun main() {
val duration = Duration.between(
OffsetDateTime.parse("2022-08-31T04:20:45.265Z"),
OffsetDateTime.now(ZoneOffset.UTC)
)
println(duration.timeAgo())
}
Result (attention, it depends on the runtime of the code):
3 hours ago
Some examples with Durations of differen values:
fun main() {
val durOne = Duration.ofHours(2).plusMinutes(13).plusSeconds(53)
val durTwo = Duration.ofMinutes(13).plusSeconds(53)
val durThree = Duration.ofSeconds(53).plusMillis(20)
val durFour = Duration.ofMillis(20)
println("${durOne.timeAgo()}")
println("${durTwo.timeAgo()}")
println("${durThree.timeAgo()}")
println("${durFour.timeAgo()}")
}
Output:
2 hours ago
13 minutes ago
53 seconds ago
a moment ago
there were data on my database which I stored before, and I missed that those data had different structure about writetime. So that caused the crash on loading data. After removing those, it worked well.
I am trying to convert a timestamp to a day of the week.
The goal would be to translate to something like ts -> MON or TUE ....
I have tried the code below but it's not working.
fun convertToReadableDate(timestamp: Long): String {
val formatter = SimpleDateFormat("dd-mm-yyyy")
val cal = Calendar.getInstance(Locale.ENGLISH)
cal.timeInMillis = timestamp * 1000
val date: LocalDate = LocalDate.parse(formatter.format(cal.time))
return date.dayOfWeek.toString()
}
Any idea ?
Thanks
get the day of the week from Unix timestamp:-
fun getDayOfWeek(timestamp: Long): String {
return SimpleDateFormat("EEEE", Locale.ENGLISH).format(timestamp * 1000)
}
getMonth:
fun getMonthFromTimeStamp(timestamp: Long): String {
return SimpleDateFormat("MMM", Locale.ENGLISH).format(timestamp * 1000)
}
getYear:
fun getYearFromTimeStamp(timestamp: Long): String {
return SimpleDateFormat("yyyy", Locale.ENGLISH).format(timestamp * 1000)
}
if you need all three combined in one function: (WED-MAY-2021)
fun getDayOfWeek(timestamp: Long): String {
return SimpleDateFormat("EEEE-MMM-yyyy", Locale.ENGLISH).format(timestamp * 1000)
}
if you need a combination of either of two in one function:(WED-MAY)
fun getDayOfWeek(timestamp: Long): String {
return SimpleDateFormat("EEEE-MMM", Locale.ENGLISH).format(timestamp * 1000)
}
You can use this formatter:
fun convertToReadableDate(timestamp: Long): String =
SimpleDateFormat("EEE", Locale.ENGLISH).format(timestamp)
.toUpperCase(Locale.ENGLISH)
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'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
I want to know if there any getter options to get time,date etc associated with Date() built-in class in kotlin..?
If yes then which are the options and how to use them..?
I have searched a lot but found nothing..I have provided my code below..
Inbox Activity
private fun refreshSmsInbox() {
try {
val smsList = ArrayList<SmsData>()
val cursor = contentResolver.query(Uri.parse("content://sms/inbox"),null,null,null,null)
cursor?.let{
if(it!!.moveToFirst()){
val nameID = it.getColumnIndex("address")
val messageID = it.getColumnIndex("body")
//val dateID = it.getColumnIndex("date")
val timestamp = it.getColumnIndexOrThrow("date")
do{
val dateString = it.getString(timestamp)
val date : Date = Date(dateString.toLong())
val formatter = SimpleDateFormat("hh:mm a")
val displayTime = formatter .format(date)
val sms = SmsData(getContactName(this,it.getString(nameID!!.toInt()).toString()),it.getString(messageID),displayTime)
smsList.add(sms)
}while (it.moveToNext())
}
it.close()
}
val adapter = ListAdapter(this, smsList)
sms_list_view.adapter = adapter
} catch (ex: Exception) {
if (this != null) {
Toast.makeText(this, ex.localizedMessage, Toast.LENGTH_SHORT).show()
}
}
}
List Adapter
class ListAdapter (val context: Context, val list : ArrayList<SmsData>): BaseAdapter(){
#SuppressLint("ViewHolder", "SimpleDateFormat")
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val view = LayoutInflater.from(context).inflate(R.layout.rowlayout,parent,false)
/*view.clickable.setOnClickListener {
val intent = Intent(this, MainActivity1::class.java)
startActivity(intent)
}*/
list[position].senderName?.let{
view.sender.text = it.substring(0,1).toUpperCase()
}
view.sms_sender.text = list[position].senderName
view.sms_message.text = list[position].message
view.sms_date.text = list[position].date.toString()
view.clickable.setOnClickListener { View ->
val intent = Intent(context,MainActivity1::class.java)
intent.putExtra("address",list[position].senderName)
context.startActivity(intent)
}
return view
}
Model class
data class SmsData(val senderName: String?, val message: String, val date: Date){
}
Expected:
Time 11:45 am/pm
Actual:
Mon 12 jul 2019 GMT +05:00
to answer your question, you need something like this :
val date = Date()
val formatter = SimpleDateFormat("hh:mm a")
val displayTime = formatter .format(date)
this gives you : 09:00 PM
Try this:
val dateString = it.getString(timestamp)
val dateFormat = SimpleDateFormat("HH:mm a")
dateFormat.timeZone = TimeZone.getTimeZone("GMT") //Your timezone if necessary
val date = dateFormat.format(dateString)
Hope it helps.