Pith - stave
package com.vgmlr.stave

import java.time.LocalDate
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit
import java.util.Locale

object StaveOTCClock {

    private fun newYearOf(date: LocalDate): LocalDate {
        val march20 = LocalDate.of(date.year, 3, 20)
        return if (date.isBefore(march20)) LocalDate.of(date.year - 1, 3, 20) else march20
    }

    fun getOTCTime(dateTime: LocalDateTime): String {
        val newYear = newYearOf(dateTime.toLocalDate())
        val daysSince = ChronoUnit.DAYS.between(newYear, dateTime.toLocalDate()) + 1
        val otcYear = "0" + newYear.format(DateTimeFormatter.ofPattern("yy"))
        val timePart = dateTime.format(DateTimeFormatter.ofPattern("HH:mm"))
        val ddMonPart = dateTime.format(DateTimeFormatter.ofPattern("dd MMM", Locale.ENGLISH))
        return "$timePart $daysSince $otcYear ($ddMonPart)"
    }

    fun getCurrentOTCTime(): String = getOTCTime(LocalDateTime.now())

    fun getFileNameTimestamp(): String {
        val now = LocalDateTime.now()
        val newYear = newYearOf(now.toLocalDate())
        val daysSince = ChronoUnit.DAYS.between(newYear, now.toLocalDate()) + 1
        val otcYear = "0" + newYear.format(DateTimeFormatter.ofPattern("yy"))
        val hhmmss = now.format(DateTimeFormatter.ofPattern("HHmmss"))
        return "$otcYear$daysSince$hhmmss"
    }
}