Home / Specs / Timestamp Keys
Customization v1.2.9

Timestamp Keys

Insert formatted date/time with custom patterns

Timestamp Keys

Overview

Timestamp keys insert the current date and/or time formatted according to a user-specified pattern when pressed. This allows users to quickly insert dates, times, or combined datetime strings without typing them manually.

Key Files

FileClass/FunctionPurpose
src/main/kotlin/tribixbite/cleverkeys/KeyValue.kt:126Kind.TimestampEnum value for timestamp keys
src/main/kotlin/tribixbite/cleverkeys/KeyValue.kt:162-173TimestampFormatData class holding pattern and symbol
src/main/kotlin/tribixbite/cleverkeys/KeyValue.kt:460-466makeTimestampKey()Factory method to create keys
src/main/kotlin/tribixbite/cleverkeys/KeyValueParser.kt:121-127parseTimestampKeydef()Parser for short syntax
src/main/kotlin/tribixbite/cleverkeys/KeyEventHandler.kt:377-401handleTimestampKey()Formats and inserts time

Architecture

Key Press (timestamp key)
       |
       v
+----------------------+
| KeyEventHandler      | -- Receives timestamp KeyValue
| handleKeyPress()     |
+----------------------+
       |
       v
+----------------------+
| handleTimestampKey() | -- Extract pattern from KeyValue.timestampFormat
+----------------------+
       |
       v
+----------------------+
| DateTimeFormatter    | -- Format current time with pattern
| or SimpleDateFormat  |
+----------------------+
       |
       v
+----------------------+
| InputConnection      | -- Commit formatted text
| commitText()         |
+----------------------+

Syntax

Short Syntax

symbol:timestamp:'pattern'

Example: 📅:timestamp:'yyyy-MM-dd' displays "📅" and inserts "2026-01-15"

Long Syntax (Legacy)

:timestamp symbol='symbol':'pattern'

Example: :timestamp symbol='📅':'yyyy-MM-dd HH:mm'

Pattern Format

Uses Java DateTimeFormatter patterns:

PatternDescriptionExample
yyyy4-digit year2026
yy2-digit year26
MMMonth (01-12)01
MMMMonth abbrevJan
ddDay (01-31)15
HHHour 24h (00-23)14
hhHour 12h (01-12)02
mmMinute (00-59)30
ssSecond (00-59)45
aAM/PMPM
EDay of weekWed
EEEEFull day nameWednesday

Pre-defined Timestamp Keys

Available without specifying patterns:

Key NameSymbolPatternOutput Example
timestamp_date📅yyyy-MM-dd2026-01-15
timestamp_time🕐HH:mm14:30
timestamp_datetime📆yyyy-MM-dd HH:mm2026-01-15 14:30
timestamp_time_secondsHH:mm:ss14:30:45
timestamp_date_short📅MM/dd/yy01/15/26
timestamp_date_long🗓EEEE, MMMM d, yyyyWednesday, January 15, 2026
timestamp_time_12h🕐h:mm a2:30 PM
timestamp_iso📋yyyy-MM-dd'T'HH:mm:ss2026-01-15T14:30:45

Implementation Details

Data Class

data class TimestampFormat(
    val pattern: String,
    val symbol: String
)

Factory Method

fun makeTimestampKey(pattern: String, symbol: String): KeyValue {
    return KeyValue(
        kind = Kind.Timestamp,
        char = '\u0000',
        timestampFormat = TimestampFormat(pattern, symbol)
    )
}

Handler Implementation

private fun handleTimestampKey(key: KeyValue) {
    val format = key.timestampFormat ?: return
    val formattedTime = try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // API 26+: Use java.time
            val formatter = DateTimeFormatter.ofPattern(format.pattern)
            LocalDateTime.now().format(formatter)
        } else {
            // API < 26: Use SimpleDateFormat
            val formatter = SimpleDateFormat(format.pattern, Locale.getDefault())
            formatter.format(Date())
        }
    } catch (e: Exception) {
        Log.w(TAG, "Invalid timestamp format: ${format.pattern}")
        format.pattern  // Fallback: insert pattern itself
    }
    inputConnection.commitText(formattedTime, 1)
}

Parser Implementation

fun parseTimestampKeydef(keydef: String): KeyValue? {
    // Short syntax: symbol:timestamp:'pattern'
    val shortMatch = """(.+):timestamp:'(.+)'""".toRegex().matchEntire(keydef)
    if (shortMatch != null) {
        val (symbol, pattern) = shortMatch.destructured
        return makeTimestampKey(pattern, symbol)
    }
    return null
}

API Compatibility

Error Handling

If the pattern is invalid: