How convert timestamp in Kotlin - android

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

How can I change the format of DateTime?

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.

convert timestamp to day of the week android

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)

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

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

Is there any getter options of time,date etc associated with Date() class in kotlin/android..?

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.

Categories

Resources