Formatting a date time string - kotlin

I have the following date which we get from an API 2022-11-23 06:12:31
I am wondering if my approach is the best.
And I need to display in this format 23 November 2022
I am using substringbefore to remove the time portion so I am left with the following: "2022-11-23"
I am using org.threeten.bp
val DAY_MONTH_YEAR_DISPLAY_FORMATTER =
DateTimeFormatter.ofPattern("dd MMMM yyyy").withZone(ZoneOffset.systemDefault())
fun formatAsFullMonthDisplayDate(localDateTime: String): String {
return try {
LocalDate.parse(localDateTime.substringBefore(" "), DAY_MONTH_YEAR_DISPLAY_FORMATTER).buildDate()
} catch (ignored: Exception) {
""
}
}
private fun LocalDate.buildDate(): String {
return buildString {
append(this#buildDate.dayOfMonth)
append(" ")
append(this#buildDate.month)
append(" ")
append(this#buildDate.year)
}
}

You can try this:
val inputDate = "2022-11-23 06:12:31"
val outputFormat = "dd MMMM yyyy"
val inputFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
val outputFormatter = DateTimeFormatter.ofPattern(outputFormat)
val date = LocalDateTime.parse(inputDate, inputFormat)
val formattedDate = date.format(outputFormatter)
println(formattedDate) // "23 November 2022"

Related

How to know pattern of string date in kotlin

I want to convert in ZonedDateTime. How can I recognise pattern to pass in DateTimeFormatter.ofPattern(????????).
val string = "May 9, 2020 8:09:03 PM"
private fun getFormatDate(date: String): ZonedDateTime {
val dateTimeFormatter = DateTimeFormatter.ofPattern(????????)
return ZonedDateTime.parse(date, dateTimeFormatter)
}
Many Thanks
You can do:
private fun getFormatDate(date: String): ZonedDateTime {
val dateTimeFormatter =
DateTimeFormatter
.ofPattern("MMM d, yyyy h:mm:ss a")
.withZone(ZoneId.systemDefault()) // or some other zone that you would like to use
.withLocale(Locale.ENGLISH)
return ZonedDateTime.parse(date, dateTimeFormatter)
}
Note that it is important that you do .withZone which specifies the zone that the ZonedDateTime is going to have, and also .withLocale, so that the parser interprets things like "May" and "PM" in the correct language.
Try It Online
See all the pattern letters here

Date format using kotlin

I would like to reformat a string from
14 Sep 2021 to 14 Sep using the SimpleDateFormat or any other APIs.
Currently my code looks like this:
private fun convertToDayAndMonth(date: String): String{
val dateFormat: Date = SimpleDateFormat("dd MMM yyyy").parse(date)!!
return SimpleDateFormat("d MMM").format(dateFormat)
but i am getting an error that says "14 Sep 2021" cannot be parsed
must be just syntax errors in your code.
both of these work for me:
println(myConvertToDayAndMonth("14 Sep 2021"))
fun myConvertToDayAndMonth(dateString: String): String {
val sdf: SimpleDateFormat = SimpleDateFormat("dd MMM yyyy")
val date: Date = sdf.parse(dateString)
return SimpleDateFormat("d MMM").format(date)
}
println(convertToDayAndMonth("14 Sep 2021"))
fun convertToDayAndMonth(date: String): String {
val javaDate: Date = SimpleDateFormat("dd MMM yyyy").parse(date)!!
return SimpleDateFormat("d MMM").format(javaDate)
}

How to add spaces between numbers with Kotlin

How can I format string "2000000.00" into "2 000 000.00" with Kotlin?
You can do this with DecimalFormat():
val dec = DecimalFormat(<pattern> [, <optional, but recommended locale>])
and then replace , with :
val number = 2000000.00
val dec = DecimalFormat("###,###,###,###,###.00", DecimalFormatSymbols(Locale.ENGLISH))
val formattedNumber = dec.format(number).replace(",", " ")
println(formattedNumber)
.00 is needed to keep the digits!!!
This will print:
2 000 000.00
here as a test:
#Test
fun testDecimalFormat() {
val number = 2000000.00
val dec = DecimalFormat("###,###,###,###,###.00", DecimalFormatSymbols(Locale.ENGLISH))
val formattedNumber = dec.format(number).replace(",", " ")
assertThat(formattedNumber).isEqualTo("2 000 000.00")
}
#Test
fun testDecimalFormatWithDigitValue() {
val number = 2000000.01
val dec = DecimalFormat("###,###,###,###,###.00", DecimalFormatSymbols(Locale.ENGLISH))
val formattedNumber = dec.format(number).replace(",", " ")
assertThat(formattedNumber).isEqualTo("2 000 000.01")
}
Link: https://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html

Docx TableWith FieldsMetadata and Velocity

I'm trying to make a docx table with FieldsMetadata and Velocity but in the output file, each cell of the table contains the list itself and not the value of the cell.
Here my code :
// Build Docx
private fun buildDocxReport(): SystemFile {
try {
val resource = this.javaClass.classLoader.getResourceAsStream("reports/code.docx")
val report = XDocReportRegistry.getRegistry().loadReport(resource, TemplateEngineKind.Velocity)
val metadata = report.createFieldsMetadata()
metadata.load("codes", Code::class.java, true)
val context = report.createContext()
context.put("codes", getAllCodes()); // getAllCodes() : return Listof<Code>
val tempFile = File.createTempFile("${DateUtil.format(Date(), "yyyyMMdd")}_${IDs.short()}", ".docx")
val fos = FileOutputStream(tempFile)
// convert to pdf
//val options = Options.getTo(ConverterTypeTo.PDF).via(ConverterTypeVia.XWPF)
//report.convert(context, options, fos)
report.process(context, fos)
fos.close()
return SystemFile(tempFile).attach(tempFile.name)
} catch (e: Throwable) {
e.printStackTrace()
throw FunctionalException("Impossible de gérer le document. Une erreur s'es produite.")
}
}
My class Code :
data class Code (
val code: String,
val libelle: String,
val base: String,
val taux: String? = "",
val gain: String? = "",
val retenue: String? = "")
Here my template :
code.docx
And here my outpu docx :
listeCode.docx
It's because the cells aren't typed MergedField in the template File.

Kotlin convert TimeStamp to DateTime

I'm trying to find out how I can convert timestamp to datetime in Kotlin, this is very simple in Java but I cant find any equivalent of it in Kotlin.
For example: epoch timestamp (seconds since 1970-01-01) 1510500494 ==> DateTime object 2017-11-12 18:28:14.
Is there any solution for this in Kotlin or do I have to use Java syntax in Kotlin? Please give me a simple sample to show how I can resolve this problem.
this link is not an answer to my question
private fun getDateTime(s: String): String? {
try {
val sdf = SimpleDateFormat("MM/dd/yyyy")
val netDate = Date(Long.parseLong(s) * 1000)
return sdf.format(netDate)
} catch (e: Exception) {
return e.toString()
}
}
It's actually just like Java. Try this:
val stamp = Timestamp(System.currentTimeMillis())
val date = Date(stamp.time)
println(date)
class DateTest {
private val simpleDateFormat = SimpleDateFormat("dd MMMM yyyy, HH:mm:ss", Locale.ENGLISH)
#Test
fun testDate() {
val time = 1560507488
println(getDateString(time)) // 14 June 2019, 13:18:08
}
private fun getDateString(time: Long) : String = simpleDateFormat.format(time * 1000L)
private fun getDateString(time: Int) : String = simpleDateFormat.format(time * 1000L)
}
Notice that we multiply by 1000L, not 1000. In case you have an integer number (1560507488) muliplied by 1000, you will get a wrong result: 17 January 1970, 17:25:59.
Although it's Kotlin, you still have to use the Java API. An example for Java 8+ APIs converting the value 1510500494 which you mentioned in the question comments:
import java.time.*
val dt = Instant.ofEpochSecond(1510500494)
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
Here is a solution in Kotlin
fun getShortDate(ts:Long?):String{
if(ts == null) return ""
//Get instance of calendar
val calendar = Calendar.getInstance(Locale.getDefault())
//get current date from ts
calendar.timeInMillis = ts
//return formatted date
return android.text.format.DateFormat.format("E, dd MMM yyyy", calendar).toString()
}
val sdf = SimpleDateFormat("dd/MM/yy hh:mm a")
val netDate = Date(item.timestamp)
val date =sdf.format(netDate)
Log.e("Tag","Formatted Date"+date)
"sdf" is variable "SimpleDateFormat" of where we can set format of date as we want.
"netDate" is variable of Date. In Date we can sending timestamp values and printing that Date by SimpleDateFormat by using sdf.format(netDate).
This worked for me - takes a Long
import java.time.*
private fun getDateTimeFromEpocLongOfSeconds(epoc: Long): String? {
try {
val netDate = Date(epoc*1000)
return netDate.toString()
} catch (e: Exception) {
return e.toString()
}
}
#SuppressLint("SimpleDateFormat")
fun dateFormatter(milliseconds: String): String {
return SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(Date(milliseconds.toLong())).toString()
}
This is a improved version existing answers (Sahil's and Javier's)
val stamp = Timestamp(System.currentTimeMillis()) // from java.sql.timestamp
val date = Date(stamp.time)
val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
// set your timezone appropriately or use `TimeZone.getDefault()`
sdf.timeZone = TimeZone.getTimeZone("Asia/Kolkata")
val formattedDate = sdf.format(date)
println(formattedDate)
Kotlin Playground link
Improvements
Set time zone to get correct time otherwise you will get the UTC time.
Formatted the date time according to yyyy-MM-dd HH:mm:ss format.
Disambiguate the Timestamp class import by commenting the required import.
Added Kotlin Playground link to see a working example.
fun stringtoDate(dates: String): Date {
val sdf = SimpleDateFormat("EEE, MMM dd yyyy",
Locale.ENGLISH)
var date: Date? = null
try {
date = sdf.parse(dates)
println(date)
} catch (e: ParseException) {
e.printStackTrace()
}
return date!!
}
If you're trying to convert timestamp from firebase.
This is what worked for me.
val timestamp = data[TIMESTAMP] as com.google.firebase.Timestamp
val date = timestamp.toDate()
This works for me.
fun FromTimestamp(value: Long?): Date? {
return if (value == null) null else Date(value)
}
private fun epochToIso8601(time: Long): String {
val format = "dd MMM yyyy HH:mm:ss" // you can add the format you need
val sdf = SimpleDateFormat(format, Locale.getDefault()) // default local
sdf.timeZone = TimeZone.getDefault() // set anytime zone you need
return sdf.format(Date(time * 1000))
}
The above code will get the time in long format, which is the default epoch format and return it as a string to display.
In case you have input as a string just add .toLong() and it will be converted to long.